@fluid-app/portal-sdk 0.1.340 → 0.1.341

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 (151) hide show
  1. package/dist/{AddressAutocompleteInput-4OS-oYis.mjs → AddressAutocompleteInput-BQ7HCDqS.mjs} +17 -17
  2. package/dist/AddressAutocompleteInput-BQ7HCDqS.mjs.map +1 -0
  3. package/dist/{AddressAutocompleteInput-CZITNL-n.cjs → AddressAutocompleteInput-C0ns8N-l.cjs} +17 -17
  4. package/dist/AddressAutocompleteInput-C0ns8N-l.cjs.map +1 -0
  5. package/dist/{AppDownloadScreen-BYjlFEVq.cjs → AppDownloadScreen-DqqUBpS-.cjs} +5 -5
  6. package/dist/AppDownloadScreen-DqqUBpS-.cjs.map +1 -0
  7. package/dist/{AppDownloadScreen-BkPXQ6HD.mjs → AppDownloadScreen-ZUoc8X2D.mjs} +5 -5
  8. package/dist/AppDownloadScreen-ZUoc8X2D.mjs.map +1 -0
  9. package/dist/{CardWidget-Jv6HiiK-.cjs → CardWidget--S5FBquC.cjs} +2 -2
  10. package/dist/{CardWidget-Jv6HiiK-.cjs.map → CardWidget--S5FBquC.cjs.map} +1 -1
  11. package/dist/{CardWidget-C9UbLrzZ.mjs → CardWidget-ChfurL_z.mjs} +2 -2
  12. package/dist/{CardWidget-C9UbLrzZ.mjs.map → CardWidget-ChfurL_z.mjs.map} +1 -1
  13. package/dist/{CardWidget-Wj7aNAAe.cjs → CardWidget-DsfLoyup.cjs} +2 -2
  14. package/dist/{ContactsScreen-BDOyYGyR.cjs → ContactsScreen-B3Ena0O7.cjs} +2 -2
  15. package/dist/{ContactsScreen-6x_Y2HBg.cjs → ContactsScreen-CiegGc50.cjs} +18 -18
  16. package/dist/ContactsScreen-CiegGc50.cjs.map +1 -0
  17. package/dist/{ContactsScreen-CU5_SYVK.mjs → ContactsScreen-Cwyt5qIf.mjs} +18 -18
  18. package/dist/ContactsScreen-Cwyt5qIf.mjs.map +1 -0
  19. package/dist/{ContainerWidget-B0WqVKej.mjs → ContainerWidget-BHWPtBmF.mjs} +2 -2
  20. package/dist/{ContainerWidget-B0WqVKej.mjs.map → ContainerWidget-BHWPtBmF.mjs.map} +1 -1
  21. package/dist/{ContainerWidget-BJys0vji.cjs → ContainerWidget-Cf_D4TAi.cjs} +2 -2
  22. package/dist/{ContainerWidget-BJys0vji.cjs.map → ContainerWidget-Cf_D4TAi.cjs.map} +1 -1
  23. package/dist/{ContainerWidget-BPoDy9wl.cjs → ContainerWidget-CyDVJu83.cjs} +3 -3
  24. package/dist/{EmbedWidget-BjLKHqCD.cjs → EmbedWidget-B1gWxgsn.cjs} +2 -2
  25. package/dist/EmbedWidget-B1gWxgsn.cjs.map +1 -0
  26. package/dist/{EmbedWidget-DwYcDOSr.mjs → EmbedWidget-JVbp9wAL.mjs} +2 -2
  27. package/dist/EmbedWidget-JVbp9wAL.mjs.map +1 -0
  28. package/dist/{FluidProvider-CYgSHMUd.cjs → FluidProvider-BFU7ermL.cjs} +23 -23
  29. package/dist/{FluidProvider-CYgSHMUd.cjs.map → FluidProvider-BFU7ermL.cjs.map} +1 -1
  30. package/dist/{FluidProvider-rLNjrHI9.mjs → FluidProvider-BqJ-t2bW.mjs} +23 -23
  31. package/dist/{FluidProvider-rLNjrHI9.mjs.map → FluidProvider-BqJ-t2bW.mjs.map} +1 -1
  32. package/dist/{LayoutWidget-COFyne-B.cjs → LayoutWidget-3G-w-YLz.cjs} +2 -2
  33. package/dist/{LayoutWidget-_f70Meea.cjs → LayoutWidget-CG-dWz_c.cjs} +2 -2
  34. package/dist/{LayoutWidget-_f70Meea.cjs.map → LayoutWidget-CG-dWz_c.cjs.map} +1 -1
  35. package/dist/{LayoutWidget-CUG5HXPH.mjs → LayoutWidget-CrZG6Ipw.mjs} +2 -2
  36. package/dist/{LayoutWidget-CUG5HXPH.mjs.map → LayoutWidget-CrZG6Ipw.mjs.map} +1 -1
  37. package/dist/{MessagingScreen-CKPKnmdA.cjs → MessagingScreen-7BBNidBx.cjs} +15 -15
  38. package/dist/{MessagingScreen-DEKQhSxk.mjs → MessagingScreen-BIWRCS3T.mjs} +15 -15
  39. package/dist/{MessagingScreen-C_VnN2yj.cjs → MessagingScreen-D_wVko-i.cjs} +2 -2
  40. package/dist/{MessagingScreen-C_VnN2yj.cjs.map → MessagingScreen-D_wVko-i.cjs.map} +1 -1
  41. package/dist/{MessagingScreen-Bn1jNjdF.mjs → MessagingScreen-ZwSPp6zu.mjs} +2 -2
  42. package/dist/{MessagingScreen-Bn1jNjdF.mjs.map → MessagingScreen-ZwSPp6zu.mjs.map} +1 -1
  43. package/dist/{MySiteScreen-BLI39L5d.cjs → MySiteScreen-17KRkcj7.cjs} +29 -29
  44. package/dist/MySiteScreen-17KRkcj7.cjs.map +1 -0
  45. package/dist/{MySiteScreen-h7lBk3gC.cjs → MySiteScreen-BdBnDI6s.cjs} +1 -1
  46. package/dist/{MySiteScreen-B5jblKuW.mjs → MySiteScreen-BlTSt7a0.mjs} +29 -29
  47. package/dist/MySiteScreen-BlTSt7a0.mjs.map +1 -0
  48. package/dist/{MySiteWidget-CAj-6hXM.cjs → MySiteWidget-23lGcDO1.cjs} +3 -3
  49. package/dist/MySiteWidget-23lGcDO1.cjs.map +1 -0
  50. package/dist/{MySiteWidget-D0ZQpY-e.mjs → MySiteWidget-BXO8rmnf.mjs} +3 -3
  51. package/dist/{MySiteWidget-D0ZQpY-e.mjs.map → MySiteWidget-BXO8rmnf.mjs.map} +1 -1
  52. package/dist/{NestedWidget-D1iDgWh8.cjs → NestedWidget-CZGOZbpZ.cjs} +5 -5
  53. package/dist/NestedWidget-CZGOZbpZ.cjs.map +1 -0
  54. package/dist/{NestedWidget-BISpn0HM.cjs → NestedWidget-Cv8h-u5K.cjs} +1 -1
  55. package/dist/{NestedWidget-DPC6Y52o.mjs → NestedWidget-DuNuNaeT.mjs} +5 -5
  56. package/dist/NestedWidget-DuNuNaeT.mjs.map +1 -0
  57. package/dist/{OrdersScreen-BOu-b93J.mjs → OrdersScreen-BkUvISL0.mjs} +15 -15
  58. package/dist/{OrdersScreen-BX3Tp0W6.mjs → OrdersScreen-DgriwQBo.mjs} +4 -4
  59. package/dist/OrdersScreen-DgriwQBo.mjs.map +1 -0
  60. package/dist/{OrdersScreen-C0-X_pGG.cjs → OrdersScreen-TGNvFpjj.cjs} +4 -4
  61. package/dist/OrdersScreen-TGNvFpjj.cjs.map +1 -0
  62. package/dist/{OrdersScreen-CyT1TpjL.cjs → OrdersScreen-t1EwXPZx.cjs} +15 -15
  63. package/dist/{ProfileScreen-B1OMNJrQ.mjs → ProfileScreen-Bw8W8nxK.mjs} +4 -4
  64. package/dist/{ProfileScreen-B1OMNJrQ.mjs.map → ProfileScreen-Bw8W8nxK.mjs.map} +1 -1
  65. package/dist/{ProfileScreen-DEYfahoM.mjs → ProfileScreen-CArZ7TAm.mjs} +16 -16
  66. package/dist/{ProfileScreen-Dshb7RM2.cjs → ProfileScreen-CP5ijd_t.cjs} +4 -4
  67. package/dist/{ProfileScreen-Dshb7RM2.cjs.map → ProfileScreen-CP5ijd_t.cjs.map} +1 -1
  68. package/dist/{ProfileScreen-BRbz69S3.cjs → ProfileScreen-DXlKK4gO.cjs} +16 -16
  69. package/dist/{RecentActivityWidget-CVQpo1jC.mjs → RecentActivityWidget-ClgOlTXl.mjs} +3 -3
  70. package/dist/RecentActivityWidget-ClgOlTXl.mjs.map +1 -0
  71. package/dist/{RecentActivityWidget-DnGybdc3.cjs → RecentActivityWidget-DZGKRR5x.cjs} +3 -3
  72. package/dist/RecentActivityWidget-DZGKRR5x.cjs.map +1 -0
  73. package/dist/{ScreenRenderer-BYiZunHL.cjs → ScreenRenderer-CLDJUinO.cjs} +2 -2
  74. package/dist/{ScreenRenderer-BYiZunHL.cjs.map → ScreenRenderer-CLDJUinO.cjs.map} +1 -1
  75. package/dist/{ScreenRenderer-1ZCNOyIb.mjs → ScreenRenderer-TobkTBMC.mjs} +2 -2
  76. package/dist/{ScreenRenderer-1ZCNOyIb.mjs.map → ScreenRenderer-TobkTBMC.mjs.map} +1 -1
  77. package/dist/{SearchSort-K0-ffUoD.cjs → SearchSort-CDuQPacI.cjs} +2 -2
  78. package/dist/{SearchSort-K0-ffUoD.cjs.map → SearchSort-CDuQPacI.cjs.map} +1 -1
  79. package/dist/{SearchSort-CObUt78n.mjs → SearchSort-CMUL0qt3.mjs} +2 -2
  80. package/dist/{SearchSort-CObUt78n.mjs.map → SearchSort-CMUL0qt3.mjs.map} +1 -1
  81. package/dist/{ShareablesScreen-aafzr3Vs.mjs → ShareablesScreen-B6Qs0xXn.mjs} +116 -116
  82. package/dist/ShareablesScreen-B6Qs0xXn.mjs.map +1 -0
  83. package/dist/{ShareablesScreen-COVW0ikb.cjs → ShareablesScreen-BAOW6RIK.cjs} +116 -116
  84. package/dist/ShareablesScreen-BAOW6RIK.cjs.map +1 -0
  85. package/dist/{ShareablesScreen-CNAem5rt.mjs → ShareablesScreen-C3K5ed-X.mjs} +2 -2
  86. package/dist/{ShareablesScreen-BZv1NXJV.cjs → ShareablesScreen-C3juoUMG.cjs} +2 -2
  87. package/dist/{ShopScreen-fcy9uJ3Z.cjs → ShopScreen-BjuLPVrk.cjs} +13 -13
  88. package/dist/ShopScreen-BjuLPVrk.cjs.map +1 -0
  89. package/dist/{ShopScreen-Bhn_bZ8O.mjs → ShopScreen-CtqHSaUW.mjs} +15 -15
  90. package/dist/{ShopScreen-CaEKFEGZ.cjs → ShopScreen-CwGh-q7J.cjs} +15 -15
  91. package/dist/{ShopScreen-dvruZcuz.mjs → ShopScreen-DNJ4Geoq.mjs} +13 -13
  92. package/dist/ShopScreen-DNJ4Geoq.mjs.map +1 -0
  93. package/dist/{ShopWidget-BZ48BUxp.cjs → ShopWidget-BAi2p8DP.cjs} +8 -8
  94. package/dist/ShopWidget-BAi2p8DP.cjs.map +1 -0
  95. package/dist/{ShopWidget-ZmhMoVmK.mjs → ShopWidget-D9-DhKP4.mjs} +8 -8
  96. package/dist/ShopWidget-D9-DhKP4.mjs.map +1 -0
  97. package/dist/{ShopWidget-DmlseAqM.cjs → ShopWidget-_T-ycRq1.cjs} +2 -2
  98. package/dist/{SubscriptionsScreen-BYQrZ2aR.mjs → SubscriptionsScreen-B55dK8Qb.mjs} +16 -16
  99. package/dist/{SubscriptionsScreen-CfxeuHVV.mjs → SubscriptionsScreen-CVKyyzbR.mjs} +23 -23
  100. package/dist/SubscriptionsScreen-CVKyyzbR.mjs.map +1 -0
  101. package/dist/{SubscriptionsScreen-Bupuf-0D.cjs → SubscriptionsScreen-Dz1PGO2z.cjs} +23 -23
  102. package/dist/SubscriptionsScreen-Dz1PGO2z.cjs.map +1 -0
  103. package/dist/{SubscriptionsScreen-BoSpOiOm.cjs → SubscriptionsScreen-TAXj2UXa.cjs} +16 -16
  104. package/dist/{TableWidget-Dyq8JXbd.cjs → TableWidget-C4F1IEKt.cjs} +1 -1
  105. package/dist/{TableWidget-fbsVsyqZ.mjs → TableWidget-CpHI9CGQ.mjs} +3 -3
  106. package/dist/TableWidget-CpHI9CGQ.mjs.map +1 -0
  107. package/dist/{TableWidget-wQkzw7Jg.cjs → TableWidget-RK0B52qT.cjs} +3 -3
  108. package/dist/TableWidget-RK0B52qT.cjs.map +1 -0
  109. package/dist/{ToDoWidget-BPh5ZLCT.cjs → ToDoWidget-B1uzfuI5.cjs} +2 -2
  110. package/dist/{ToDoWidget-1_JCx9X7.mjs → ToDoWidget-BaWksZpJ.mjs} +5 -5
  111. package/dist/{ToDoWidget-1_JCx9X7.mjs.map → ToDoWidget-BaWksZpJ.mjs.map} +1 -1
  112. package/dist/{ToDoWidget-1ZaXZTi4.cjs → ToDoWidget-C03kvBE-.cjs} +5 -5
  113. package/dist/{ToDoWidget-1ZaXZTi4.cjs.map → ToDoWidget-C03kvBE-.cjs.map} +1 -1
  114. package/dist/index.cjs +50 -50
  115. package/dist/index.cjs.map +1 -1
  116. package/dist/index.d.cts.map +1 -1
  117. package/dist/index.d.mts.map +1 -1
  118. package/dist/index.mjs +50 -50
  119. package/dist/index.mjs.map +1 -1
  120. package/dist/{task-composer-form-2z5Qk6US.cjs → task-composer-form-BEZGTBBZ.cjs} +2 -2
  121. package/dist/{task-composer-form-2z5Qk6US.cjs.map → task-composer-form-BEZGTBBZ.cjs.map} +1 -1
  122. package/dist/{task-composer-form-B3eR9kfb.mjs → task-composer-form-D_Pbl6qk.mjs} +2 -2
  123. package/dist/{task-composer-form-B3eR9kfb.mjs.map → task-composer-form-D_Pbl6qk.mjs.map} +1 -1
  124. package/package.json +15 -15
  125. package/dist/AddressAutocompleteInput-4OS-oYis.mjs.map +0 -1
  126. package/dist/AddressAutocompleteInput-CZITNL-n.cjs.map +0 -1
  127. package/dist/AppDownloadScreen-BYjlFEVq.cjs.map +0 -1
  128. package/dist/AppDownloadScreen-BkPXQ6HD.mjs.map +0 -1
  129. package/dist/ContactsScreen-6x_Y2HBg.cjs.map +0 -1
  130. package/dist/ContactsScreen-CU5_SYVK.mjs.map +0 -1
  131. package/dist/EmbedWidget-BjLKHqCD.cjs.map +0 -1
  132. package/dist/EmbedWidget-DwYcDOSr.mjs.map +0 -1
  133. package/dist/MySiteScreen-B5jblKuW.mjs.map +0 -1
  134. package/dist/MySiteScreen-BLI39L5d.cjs.map +0 -1
  135. package/dist/MySiteWidget-CAj-6hXM.cjs.map +0 -1
  136. package/dist/NestedWidget-D1iDgWh8.cjs.map +0 -1
  137. package/dist/NestedWidget-DPC6Y52o.mjs.map +0 -1
  138. package/dist/OrdersScreen-BX3Tp0W6.mjs.map +0 -1
  139. package/dist/OrdersScreen-C0-X_pGG.cjs.map +0 -1
  140. package/dist/RecentActivityWidget-CVQpo1jC.mjs.map +0 -1
  141. package/dist/RecentActivityWidget-DnGybdc3.cjs.map +0 -1
  142. package/dist/ShareablesScreen-COVW0ikb.cjs.map +0 -1
  143. package/dist/ShareablesScreen-aafzr3Vs.mjs.map +0 -1
  144. package/dist/ShopScreen-dvruZcuz.mjs.map +0 -1
  145. package/dist/ShopScreen-fcy9uJ3Z.cjs.map +0 -1
  146. package/dist/ShopWidget-BZ48BUxp.cjs.map +0 -1
  147. package/dist/ShopWidget-ZmhMoVmK.mjs.map +0 -1
  148. package/dist/SubscriptionsScreen-Bupuf-0D.cjs.map +0 -1
  149. package/dist/SubscriptionsScreen-CfxeuHVV.mjs.map +0 -1
  150. package/dist/TableWidget-fbsVsyqZ.mjs.map +0 -1
  151. package/dist/TableWidget-wQkzw7Jg.cjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ToDoWidget-1ZaXZTi4.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetPreviewContext","useDataSourceRegistryConfig","Dialog","DialogContent","DialogHeader","DialogTitle","PortalContainerProvider","TaskComposerForm","useContactsTranslation","useInfiniteContacts","Popover","PopoverTrigger","cn","ChevronsUpDown","PopoverContent","Search","Input","Check","useWidgetPreviewContext","borderWidthClasses","borderColorClasses","ListChecks","ErrorState","Plus","parseTaskBody","getFontSizeField","getColorField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"sources":["../../widgets/src/hooks/use-todos.preview.ts","../../widgets/src/hooks/use-todos.ts","../../widgets/src/hooks/use-update-todo.ts","../../widgets/src/widgets/CreateTodoDialog.tsx","../../widgets/src/widgets/ToDoWidget.tsx"],"sourcesContent":["import type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst now = new Date();\n\nfunction daysFromNow(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() + days);\n return d.toISOString();\n}\n\nexport const PREVIEW_DATA: Todo[] = [\n {\n id: 1,\n body: \"Send follow-up email to new leads\",\n dueAt: daysFromNow(1),\n completedAt: null,\n createdAt: daysFromNow(-2),\n contactId: 101,\n contactName: \"Sarah Johnson\",\n },\n {\n id: 2,\n body: \"Prepare slides for team training\",\n dueAt: daysFromNow(3),\n completedAt: null,\n createdAt: daysFromNow(-1),\n contactId: null,\n contactName: null,\n },\n {\n id: 3,\n body: \"Review monthly sales report\",\n dueAt: daysFromNow(-1),\n completedAt: null,\n createdAt: daysFromNow(-5),\n contactId: 102,\n contactName: \"Mike Chen\",\n },\n];\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-todos.preview\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\n/**\n * Shared cache key for the todos list. Both useTodos (read) and\n * useUpdateTodo (write) use this — drift would silently break optimistic\n * updates.\n */\nexport function todosQueryKey(args: {\n baseUrl: string | undefined;\n isPreview: boolean;\n}) {\n return [\n \"portal-widget-use\",\n \"todos\",\n args.isPreview ? \"preview\" : args.baseUrl,\n ] as const;\n}\n\nexport function useTodos(): UseQueryResult<Todo[], Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useQuery({\n queryKey: todosQueryKey({ baseUrl, isPreview }),\n queryFn: ({ signal }) => widgetsApi.fetchTodos(signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { todosQueryKey } from \"./use-todos\";\n\ntype UpdateVariables = { id: number; completed: boolean };\n\nexport function useUpdateTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n const queryKey = todosQueryKey({ baseUrl, isPreview });\n\n return useMutation({\n mutationFn: ({ id, completed }: UpdateVariables) => {\n // Defense in depth: ToDoWidget already disables the checkbox in\n // preview mode, but if any other caller fires this mutation while\n // previewing we'd PATCH demo data on the real backend. Fail closed.\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo updates are disabled in preview mode\"),\n );\n }\n return widgetsApi.updateTodo(id, completed);\n },\n onMutate: async ({ id, completed }) => {\n await queryClient.cancelQueries({ queryKey });\n const previous = queryClient.getQueryData<Todo[]>(queryKey);\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === id\n ? {\n ...todo,\n completedAt: completed ? new Date().toISOString() : null,\n }\n : todo,\n ),\n );\n return { previous };\n },\n onSuccess: (updated, { completed }) => {\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === updated.id ? updated : todo,\n ),\n );\n // Match the documented test plan: completing toasts, un-completing\n // is silent. The widget today only ever fires completed=true, but\n // gating here keeps the contract honest for any future caller that\n // toggles either direction.\n if (completed) {\n fluidToast({ title: \"Todo completed\", type: \"success\" });\n }\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(queryKey, context.previous);\n }\n fluidToast({ title: \"Failed to update todo\", type: \"error\" });\n },\n // Belt-and-suspenders refetch to reconcile any race we couldn't see\n // (e.g., a different tab mutated the same todo). Cheap — one GET per\n // toggle.\n onSettled: () => {\n queryClient.invalidateQueries({ queryKey });\n },\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Check, ChevronsUpDown, Search } from \"lucide-react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n cn,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n Input,\n Popover,\n PopoverContent,\n PopoverTrigger,\n PortalContainerProvider,\n} from \"@fluid-app/ui-primitives\";\nimport { useInfiniteContacts } from \"@fluid-app/contacts-core/hooks/use-infinite-contacts\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { TaskComposerForm } from \"@fluid-app/contacts-ui/portal/components/tasks/task-composer-form\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { todosQueryKey } from \"../hooks/use-todos\";\n\nconst SEARCH_DEBOUNCE_MS = 200;\n\nexport interface CreateTodoDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function CreateTodoDialog({\n open,\n onOpenChange,\n}: CreateTodoDialogProps): React.JSX.Element {\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n const [selectedContact, setSelectedContact] = useState<Contact | null>(null);\n // Anchor the popover's portal inside the dialog. Dialog applies\n // pointer-events: none to the body while open, which kills clicks and\n // scroll on a body-portaled popover in WebKit. See edit-bill-date-dialog\n // for the canonical pattern.\n const [popoverContainer, setPopoverContainer] =\n useState<HTMLDivElement | null>(null);\n\n // Reset state when the dialog closes so the next open starts fresh.\n useEffect(() => {\n if (!open) setSelectedContact(null);\n }, [open]);\n\n const handleDone = () => {\n queryClient.invalidateQueries({\n queryKey: todosQueryKey({ baseUrl, isPreview }),\n });\n onOpenChange(false);\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"gap-4 p-4 sm:max-w-md sm:gap-6 sm:p-6\">\n <DialogHeader>\n <DialogTitle>Add a to-do</DialogTitle>\n </DialogHeader>\n\n <PortalContainerProvider container={popoverContainer}>\n <div className=\"mt-2 flex flex-col gap-3\">\n <ContactPicker\n value={selectedContact}\n onSelect={setSelectedContact}\n />\n\n {selectedContact && (\n <TaskComposerForm\n key={selectedContact.id}\n contactId={String(selectedContact.id)}\n onDone={handleDone}\n />\n )}\n </div>\n </PortalContainerProvider>\n {/* Portal target for the popover. Must live INSIDE DialogContent so\n it ends up in the dialog's body-level portal — otherwise it\n renders inline next to the widget, and any transformed ancestor\n (builder canvas zoom, etc.) would break `position: fixed`.\n Intentionally NOT aria-hidden — the popover content portaled\n into this container has its own listbox/option semantics that\n screen readers need to reach. `pointer-events-none` keeps the\n empty overlay from capturing clicks; the popover content sets\n `pointer-events-auto` so it remains interactive. */}\n <div\n ref={setPopoverContainer}\n className=\"pointer-events-none fixed inset-0 z-[9998]\"\n />\n </DialogContent>\n </Dialog>\n );\n}\n\ninterface ContactPickerProps {\n value: Contact | null;\n onSelect: (contact: Contact) => void;\n}\n\nfunction ContactPicker({\n value,\n onSelect,\n}: ContactPickerProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [open, setOpen] = useState(false);\n const [searchInput, setSearchInput] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handle = window.setTimeout(() => {\n setDebouncedSearch(searchInput.trim());\n }, SEARCH_DEBOUNCE_MS);\n return () => window.clearTimeout(handle);\n }, [searchInput]);\n\n const queryParams = useMemo(\n () => ({\n ...(debouncedSearch ? { search_query: debouncedSearch } : {}),\n sort_by: \"full_name\",\n sort_direction: \"asc\",\n per_page: 25,\n }),\n [debouncedSearch],\n );\n\n const {\n data,\n isLoading,\n isError,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useInfiniteContacts(queryParams);\n\n const contacts: Contact[] = useMemo(\n () => data?.pages.flatMap((page) => page.contacts ?? []) ?? [],\n [data],\n );\n\n // Auto-load the next page when the sentinel scrolls into view, so reps\n // with many contacts can reach all of them without typing a precise\n // search query.\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel || !hasNextPage) return;\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (entry?.isIntersecting && !isFetchingNextPage) {\n fetchNextPage();\n }\n });\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n return (\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-muted-foreground text-xs font-medium\">\n {t(\"contact_label\")}\n </label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n className=\"border-input bg-background hover:bg-muted/40 flex w-full items-center justify-between gap-2 rounded-md border px-3 py-2 text-left text-sm transition-colors\"\n >\n <span\n className={cn(\n \"truncate\",\n !value && \"text-muted-foreground font-normal\",\n )}\n >\n {value ? value.full_name : t(\"empty_select_contact\")}\n </span>\n <ChevronsUpDown\n className=\"text-muted-foreground size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"bg-popover text-popover-foreground pointer-events-auto z-[9999] w-(--radix-popover-trigger-width) overflow-hidden rounded-md border p-0 shadow-md\"\n >\n <div className=\"border-border flex items-center gap-2 border-b px-3 py-2\">\n <Search\n className=\"text-muted-foreground size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n <Input\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={t(\"search_placeholder\")}\n aria-label={t(\"search_placeholder\")}\n className=\"h-7 border-0 px-0 shadow-none focus-visible:ring-0\"\n />\n </div>\n <div className=\"max-h-64 overflow-y-auto py-1\" role=\"listbox\">\n {isLoading ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {t(\"loading\")}\n </div>\n ) : isError ? (\n <div className=\"text-destructive px-3 py-6 text-center text-xs\">\n {t(\"error_loading_list\")}\n </div>\n ) : contacts.length === 0 ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {debouncedSearch\n ? t(\"no_contacts_search\", { term: debouncedSearch })\n : t(\"no_contacts_yet\")}\n </div>\n ) : (\n <>\n {contacts.map((contact) => {\n const isSelected = value?.id === contact.id;\n return (\n <button\n key={contact.id}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => {\n onSelect(contact);\n setOpen(false);\n }}\n className=\"hover:bg-muted/50 flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm transition-colors\"\n >\n <span className=\"truncate\">{contact.full_name}</span>\n {isSelected && (\n <Check\n className=\"text-primary size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n })}\n {hasNextPage && (\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n )}\n {isFetchingNextPage && (\n <div className=\"text-muted-foreground px-3 py-2 text-center text-xs\">\n {t(\"loading_more\")}\n </div>\n )}\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n","import { useState, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getColorField,\n getFontSizeField,\n getPaddingField,\n} from \"../core/fields\";\nimport { ListChecks, Plus } from \"lucide-react\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { parseTaskBody } from \"@fluid-app/contacts-core/parse-task-body\";\nimport { useTodos } from \"../hooks/use-todos\";\nimport { useUpdateTodo } from \"../hooks/use-update-todo\";\nimport { ErrorState } from \"../components/error-state\";\nimport { CreateTodoDialog } from \"./CreateTodoDialog\";\n\ntype ToDoWidgetProps = ComponentProps<\"div\"> & {\n // Title\n titleEnabled?: boolean;\n titleText?: string;\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content\n maxItems?: number;\n};\n\nexport function ToDoWidget({\n // Title defaults\n titleEnabled = true,\n titleText = \"To-Do\",\n titleFontSize = \"lg\",\n titleColor = \"foreground\",\n\n // Styling defaults\n background = {\n type: \"solid\",\n color: \"background\",\n },\n textColor = \"foreground\",\n accentColor = \"primary\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n\n // Content defaults\n maxItems = 5,\n\n className,\n ...props\n}: ToDoWidgetProps): React.JSX.Element {\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n const { data: todos = [], isLoading, isError } = useTodos();\n const updateTodo = useUpdateTodo();\n const { isPreview } = useWidgetPreviewContext();\n const [pendingIds, setPendingIds] = useState<Set<number>>(new Set());\n const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);\n\n const toggleTodo = (id: number, completed: boolean) => {\n if (isPreview || pendingIds.has(id)) return;\n setPendingIds((prev) => new Set(prev).add(id));\n updateTodo.mutate(\n { id, completed },\n {\n onSettled: () =>\n setPendingIds((prev) => {\n const next = new Set(prev);\n next.delete(id);\n return next;\n }),\n },\n );\n };\n\n const activeTodos = todos.filter((todo) => !todo.completedAt);\n const todosToShow = activeTodos.slice(0, maxItems);\n const remainingCount = activeTodos.length - todosToShow.length;\n const isEmpty = activeTodos.length === 0;\n\n // Group todos by contactId so same-named contacts stay separate.\n const groupedTodos = todosToShow.reduce<\n {\n contactId: number | null;\n contactName: string | null;\n todos: typeof todosToShow;\n }[]\n >((groups, todo) => {\n const existing = groups.find((g) => g.contactId === todo.contactId);\n if (existing) {\n existing.todos.push(todo);\n } else {\n groups.push({\n contactId: todo.contactId,\n contactName: todo.contactName,\n todos: [todo],\n });\n }\n return groups;\n }, []);\n\n return (\n <div\n className={`overflow-hidden rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} text-${textColor} p-${padding} ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {titleEnabled && titleText && (\n <h2\n className={`text-${titleFontSize} font-header font-bold text-${titleColor}`}\n >\n {titleText}\n </h2>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {!isEmpty && !isLoading && (\n <span className={`text-2xl font-bold text-${accentColor}`}>\n {activeTodos.length}\n </span>\n )}\n <div\n className={`flex h-10 w-10 shrink-0 items-center justify-center`}\n >\n <ListChecks className={`h-5 w-5 text-${accentColor}-foreground`} />\n </div>\n </div>\n </div>\n\n {/* Loading state */}\n {isLoading ? (\n <div className=\"flex min-h-[120px] items-center justify-center\">\n <div className=\"h-6 w-6 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n </div>\n ) : isError ? (\n /* Error state */\n <ErrorState />\n ) : isEmpty ? (\n /* Empty state */\n <div className=\"flex flex-col items-center justify-center gap-3 py-8\">\n <p className={`text-center text-${textColor}/60`}>\n You&apos;ve got nothing else To-Do!\n </p>\n {!isPreview && (\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n className={`inline-flex items-center gap-1.5 rounded-full bg-${accentColor} text-${accentColor}-foreground hover:bg-${accentColor}/90 px-4 py-1.5 text-xs font-semibold transition-colors`}\n >\n <Plus className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n Add to-do\n </button>\n )}\n </div>\n ) : (\n /* Todo List */\n <>\n <div className=\"flex flex-col gap-3\">\n {groupedTodos.map((group) => (\n <div\n key={group.contactId ?? \"__unassigned__\"}\n className=\"flex flex-col\"\n >\n {group.contactName && (\n <div\n className={`mb-1 text-xs font-semibold tracking-wide uppercase text-${textColor}/60`}\n >\n {group.contactName}\n </div>\n )}\n {group.todos.map((todo, index) => (\n <div\n key={todo.id}\n className={`flex items-center gap-3 py-2 ${\n index !== group.todos.length - 1\n ? `border-b border-${textColor}/10`\n : \"\"\n }`}\n >\n <input\n type=\"checkbox\"\n className={`h-5 w-5 rounded-full border-2 border-${textColor}/30 bg-transparent not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-60`}\n checked={!!todo.completedAt}\n disabled={isPreview || pendingIds.has(todo.id)}\n onChange={(event) =>\n toggleTodo(todo.id, event.target.checked)\n }\n />\n <span className=\"line-clamp-1 flex-1 text-sm\">\n {parseTaskBody(todo.body).title}\n </span>\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Footer */}\n <div className=\"mt-2 flex items-center justify-between\">\n {remainingCount > 0 && (\n <span className={`text-sm text-${textColor}/50 underline`}>\n {remainingCount} more task{remainingCount > 1 ? \"s\" : \"\"}\n </span>\n )}\n <div className=\"ml-auto\">\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n disabled={isPreview}\n aria-label=\"Add to-do\"\n className={`flex h-8 w-8 items-center justify-center rounded-full transition-colors not-disabled:cursor-pointer hover:bg-${textColor}/10 disabled:opacity-60`}\n >\n <Plus className={`h-5 w-5 text-${textColor}/50`} />\n </button>\n </div>\n </div>\n </>\n )}\n\n {!isPreview && (\n <CreateTodoDialog\n open={isCreateDialogOpen}\n onOpenChange={setIsCreateDialogOpen}\n />\n )}\n </div>\n );\n}\n\nexport const toDoWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ToDoWidget\",\n displayName: \"To-Do Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Styling Tab - Title Group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed above the todo list\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"titleText\",\n label: \"Title\",\n type: \"text\",\n description: \"Title text displayed above the todo list\",\n defaultValue: \"To-Do\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n key: \"titleFontSize\",\n label: \"Title Font Size\",\n description: \"Font size for the widget title\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the widget title\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Styling Tab - Design Group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Default text color for todo items\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Color used for count badge and icon\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"maxItems\",\n label: \"Max Items\",\n type: \"number\",\n description: \"Maximum number of todo items to display\",\n min: 1,\n max: 20,\n step: 1,\n defaultValue: 5,\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding around the widget container\",\n defaultValue: 4,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the widget container\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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CL,OAAO;GACR;EACDA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,KAAK;GACL,MAAM;GACN,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}
1
+ {"version":3,"file":"ToDoWidget-C03kvBE-.cjs","names":["useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetsApi","useWidgetPreviewContext","useDataSourceRegistryConfig","useWidgetPreviewContext","useDataSourceRegistryConfig","Dialog","DialogContent","DialogHeader","DialogTitle","PortalContainerProvider","TaskComposerForm","useContactsTranslation","useInfiniteContacts","Popover","PopoverTrigger","cn","ChevronsUpDown","PopoverContent","Search","Input","Check","useWidgetPreviewContext","borderWidthClasses","borderColorClasses","ListChecks","ErrorState","Plus","parseTaskBody","getFontSizeField","getColorField","getPaddingField","getBorderRadiusField","getBorderWidthField","getBorderColorField"],"sources":["../../widgets/src/hooks/use-todos.preview.ts","../../widgets/src/hooks/use-todos.ts","../../widgets/src/hooks/use-update-todo.ts","../../widgets/src/widgets/CreateTodoDialog.tsx","../../widgets/src/widgets/ToDoWidget.tsx"],"sourcesContent":["import type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nconst now = new Date();\n\nfunction daysFromNow(days: number): string {\n const d = new Date(now);\n d.setDate(d.getDate() + days);\n return d.toISOString();\n}\n\nexport const PREVIEW_DATA: Todo[] = [\n {\n id: 1,\n body: \"Send follow-up email to new leads\",\n dueAt: daysFromNow(1),\n completedAt: null,\n createdAt: daysFromNow(-2),\n contactId: 101,\n contactName: \"Sarah Johnson\",\n },\n {\n id: 2,\n body: \"Prepare slides for team training\",\n dueAt: daysFromNow(3),\n completedAt: null,\n createdAt: daysFromNow(-1),\n contactId: null,\n contactName: null,\n },\n {\n id: 3,\n body: \"Review monthly sales report\",\n dueAt: daysFromNow(-1),\n completedAt: null,\n createdAt: daysFromNow(-5),\n contactId: 102,\n contactName: \"Mike Chen\",\n },\n];\n","import { useQuery, type UseQueryResult } from \"@tanstack/react-query\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { PREVIEW_DATA } from \"./use-todos.preview\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\nexport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\n\n/**\n * Shared cache key for the todos list. Both useTodos (read) and\n * useUpdateTodo (write) use this — drift would silently break optimistic\n * updates.\n */\nexport function todosQueryKey(args: {\n baseUrl: string | undefined;\n isPreview: boolean;\n}) {\n return [\n \"portal-widget-use\",\n \"todos\",\n args.isPreview ? \"preview\" : args.baseUrl,\n ] as const;\n}\n\nexport function useTodos(): UseQueryResult<Todo[], Error> {\n const widgetsApi = useWidgetsApi();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n return useQuery({\n queryKey: todosQueryKey({ baseUrl, isPreview }),\n queryFn: ({ signal }) => widgetsApi.fetchTodos(signal),\n enabled: !isPreview,\n ...(isPreview && { placeholderData: PREVIEW_DATA }),\n });\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { fluidToast } from \"@fluid-app/ui-primitives\";\nimport { useWidgetsApi } from \"@fluid-app/portal-core/widgets-api-context\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport type { Todo } from \"@fluid-app/portal-core/widgets-api-types\";\nimport { todosQueryKey } from \"./use-todos\";\n\ntype UpdateVariables = { id: number; completed: boolean };\n\nexport function useUpdateTodo() {\n const widgetsApi = useWidgetsApi();\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n\n const queryKey = todosQueryKey({ baseUrl, isPreview });\n\n return useMutation({\n mutationFn: ({ id, completed }: UpdateVariables) => {\n // Defense in depth: ToDoWidget already disables the checkbox in\n // preview mode, but if any other caller fires this mutation while\n // previewing we'd PATCH demo data on the real backend. Fail closed.\n if (isPreview) {\n return Promise.reject(\n new Error(\"Todo updates are disabled in preview mode\"),\n );\n }\n return widgetsApi.updateTodo(id, completed);\n },\n onMutate: async ({ id, completed }) => {\n await queryClient.cancelQueries({ queryKey });\n const previous = queryClient.getQueryData<Todo[]>(queryKey);\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === id\n ? {\n ...todo,\n completedAt: completed ? new Date().toISOString() : null,\n }\n : todo,\n ),\n );\n return { previous };\n },\n onSuccess: (updated, { completed }) => {\n queryClient.setQueryData<Todo[]>(queryKey, (current) =>\n (current ?? []).map((todo) =>\n todo.id === updated.id ? updated : todo,\n ),\n );\n // Match the documented test plan: completing toasts, un-completing\n // is silent. The widget today only ever fires completed=true, but\n // gating here keeps the contract honest for any future caller that\n // toggles either direction.\n if (completed) {\n fluidToast({ title: \"Todo completed\", type: \"success\" });\n }\n },\n onError: (_error, _variables, context) => {\n if (context?.previous) {\n queryClient.setQueryData(queryKey, context.previous);\n }\n fluidToast({ title: \"Failed to update todo\", type: \"error\" });\n },\n // Belt-and-suspenders refetch to reconcile any race we couldn't see\n // (e.g., a different tab mutated the same todo). Cheap — one GET per\n // toggle.\n onSettled: () => {\n queryClient.invalidateQueries({ queryKey });\n },\n });\n}\n","\"use client\";\n\nimport React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Check, ChevronsUpDown, Search } from \"lucide-react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n cn,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n Input,\n Popover,\n PopoverContent,\n PopoverTrigger,\n PortalContainerProvider,\n} from \"@fluid-app/ui-primitives\";\nimport { useInfiniteContacts } from \"@fluid-app/contacts-core/hooks/use-infinite-contacts\";\nimport { useContactsTranslation } from \"@fluid-app/contacts-core/translation-api-context\";\nimport type { Contact } from \"@fluid-app/contacts-core/types\";\nimport { TaskComposerForm } from \"@fluid-app/contacts-ui/portal/components/tasks/task-composer-form\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { useDataSourceRegistryConfig } from \"@fluid-app/portal-react/data-sources/registry-context\";\nimport { todosQueryKey } from \"../hooks/use-todos\";\n\nconst SEARCH_DEBOUNCE_MS = 200;\n\nexport interface CreateTodoDialogProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n}\n\nexport function CreateTodoDialog({\n open,\n onOpenChange,\n}: CreateTodoDialogProps): React.JSX.Element {\n const queryClient = useQueryClient();\n const { isPreview } = useWidgetPreviewContext();\n const { baseUrl } = useDataSourceRegistryConfig();\n const [selectedContact, setSelectedContact] = useState<Contact | null>(null);\n // Anchor the popover's portal inside the dialog. Dialog applies\n // pointer-events: none to the body while open, which kills clicks and\n // scroll on a body-portaled popover in WebKit. See edit-bill-date-dialog\n // for the canonical pattern.\n const [popoverContainer, setPopoverContainer] =\n useState<HTMLDivElement | null>(null);\n\n // Reset state when the dialog closes so the next open starts fresh.\n useEffect(() => {\n if (!open) setSelectedContact(null);\n }, [open]);\n\n const handleDone = () => {\n queryClient.invalidateQueries({\n queryKey: todosQueryKey({ baseUrl, isPreview }),\n });\n onOpenChange(false);\n };\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"gap-4 p-4 sm:max-w-md sm:gap-6 sm:p-6\">\n <DialogHeader>\n <DialogTitle>Add a to-do</DialogTitle>\n </DialogHeader>\n\n <PortalContainerProvider container={popoverContainer}>\n <div className=\"mt-2 flex flex-col gap-3\">\n <ContactPicker\n value={selectedContact}\n onSelect={setSelectedContact}\n />\n\n {selectedContact && (\n <TaskComposerForm\n key={selectedContact.id}\n contactId={String(selectedContact.id)}\n onDone={handleDone}\n />\n )}\n </div>\n </PortalContainerProvider>\n {/* Portal target for the popover. Must live INSIDE DialogContent so\n it ends up in the dialog's body-level portal — otherwise it\n renders inline next to the widget, and any transformed ancestor\n (builder canvas zoom, etc.) would break `position: fixed`.\n Intentionally NOT aria-hidden — the popover content portaled\n into this container has its own listbox/option semantics that\n screen readers need to reach. `pointer-events-none` keeps the\n empty overlay from capturing clicks; the popover content sets\n `pointer-events-auto` so it remains interactive. */}\n <div\n ref={setPopoverContainer}\n className=\"pointer-events-none fixed inset-0 z-[9998]\"\n />\n </DialogContent>\n </Dialog>\n );\n}\n\ninterface ContactPickerProps {\n value: Contact | null;\n onSelect: (contact: Contact) => void;\n}\n\nfunction ContactPicker({\n value,\n onSelect,\n}: ContactPickerProps): React.JSX.Element {\n const { t } = useContactsTranslation();\n const [open, setOpen] = useState(false);\n const [searchInput, setSearchInput] = useState(\"\");\n const [debouncedSearch, setDebouncedSearch] = useState(\"\");\n const sentinelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const handle = window.setTimeout(() => {\n setDebouncedSearch(searchInput.trim());\n }, SEARCH_DEBOUNCE_MS);\n return () => window.clearTimeout(handle);\n }, [searchInput]);\n\n const queryParams = useMemo(\n () => ({\n ...(debouncedSearch ? { search_query: debouncedSearch } : {}),\n sort_by: \"full_name\",\n sort_direction: \"asc\",\n per_page: 25,\n }),\n [debouncedSearch],\n );\n\n const {\n data,\n isLoading,\n isError,\n hasNextPage,\n isFetchingNextPage,\n fetchNextPage,\n } = useInfiniteContacts(queryParams);\n\n const contacts: Contact[] = useMemo(\n () => data?.pages.flatMap((page) => page.contacts ?? []) ?? [],\n [data],\n );\n\n // Auto-load the next page when the sentinel scrolls into view, so reps\n // with many contacts can reach all of them without typing a precise\n // search query.\n useEffect(() => {\n const sentinel = sentinelRef.current;\n if (!sentinel || !hasNextPage) return;\n\n const observer = new IntersectionObserver((entries) => {\n const entry = entries[0];\n if (entry?.isIntersecting && !isFetchingNextPage) {\n fetchNextPage();\n }\n });\n\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [hasNextPage, isFetchingNextPage, fetchNextPage]);\n\n return (\n <div className=\"flex flex-col gap-1\">\n <label className=\"text-muted-foreground text-xs font-medium\">\n {t(\"contact_label\")}\n </label>\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n className=\"border-input bg-background hover:bg-muted/40 flex w-full items-center justify-between gap-2 rounded-md border px-3 py-2 text-left text-sm transition-colors\"\n >\n <span\n className={cn(\n \"truncate\",\n !value && \"text-muted-foreground font-normal\",\n )}\n >\n {value ? value.full_name : t(\"empty_select_contact\")}\n </span>\n <ChevronsUpDown\n className=\"text-muted-foreground size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"bg-popover text-popover-foreground pointer-events-auto z-[9999] w-(--radix-popover-trigger-width) overflow-hidden rounded-md border p-0 shadow-md\"\n >\n <div className=\"border-border flex items-center gap-2 border-b px-3 py-2\">\n <Search\n className=\"text-muted-foreground size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n <Input\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder={t(\"search_placeholder\")}\n aria-label={t(\"search_placeholder\")}\n className=\"h-7 border-0 px-0 shadow-none focus-visible:ring-0\"\n />\n </div>\n <div className=\"max-h-64 overflow-y-auto py-1\" role=\"listbox\">\n {isLoading ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {t(\"loading\")}\n </div>\n ) : isError ? (\n <div className=\"text-destructive px-3 py-6 text-center text-xs\">\n {t(\"error_loading_list\")}\n </div>\n ) : contacts.length === 0 ? (\n <div className=\"text-muted-foreground px-3 py-6 text-center text-xs\">\n {debouncedSearch\n ? t(\"no_contacts_search\", { term: debouncedSearch })\n : t(\"no_contacts_yet\")}\n </div>\n ) : (\n <>\n {contacts.map((contact) => {\n const isSelected = value?.id === contact.id;\n return (\n <button\n key={contact.id}\n type=\"button\"\n role=\"option\"\n aria-selected={isSelected}\n onClick={() => {\n onSelect(contact);\n setOpen(false);\n }}\n className=\"hover:bg-muted/50 flex w-full items-center justify-between gap-2 px-3 py-1.5 text-left text-sm transition-colors\"\n >\n <span className=\"truncate\">{contact.full_name}</span>\n {isSelected && (\n <Check\n className=\"text-primary size-4 shrink-0\"\n aria-hidden=\"true\"\n />\n )}\n </button>\n );\n })}\n {hasNextPage && (\n <div ref={sentinelRef} aria-hidden=\"true\" className=\"h-4\" />\n )}\n {isFetchingNextPage && (\n <div className=\"text-muted-foreground px-3 py-2 text-center text-xs\">\n {t(\"loading_more\")}\n </div>\n )}\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n );\n}\n","import { useState, type ComponentProps } from \"react\";\nimport type React from \"react\";\nimport type {\n BackgroundValue,\n BorderRadiusOptions,\n BorderWidthOptions,\n ColorOptions,\n FontSizeOptions,\n PaddingOptions,\n} from \"@fluid-app/portal-core/types\";\nimport type { WidgetPropertySchema } from \"@fluid-app/portal-core/registries\";\nimport {\n getBorderRadiusField,\n getBorderWidthField,\n getBorderColorField,\n borderWidthClasses,\n borderColorClasses,\n getColorField,\n getFontSizeField,\n getPaddingField,\n} from \"../core/fields\";\nimport { ListChecks, Plus } from \"lucide-react\";\nimport { useWidgetPreviewContext } from \"@fluid-app/portal-react/data-sources/preview-context\";\nimport { parseTaskBody } from \"@fluid-app/contacts-core/parse-task-body\";\nimport { useTodos } from \"../hooks/use-todos\";\nimport { useUpdateTodo } from \"../hooks/use-update-todo\";\nimport { ErrorState } from \"../components/error-state\";\nimport { CreateTodoDialog } from \"./CreateTodoDialog\";\n\ntype ToDoWidgetProps = ComponentProps<\"div\"> & {\n // Title\n titleEnabled?: boolean;\n titleText?: string;\n titleFontSize?: FontSizeOptions;\n titleColor?: ColorOptions;\n\n // Styling\n background?: BackgroundValue;\n textColor?: ColorOptions;\n accentColor?: ColorOptions;\n padding?: PaddingOptions;\n borderRadius?: BorderRadiusOptions;\n borderWidth?: BorderWidthOptions;\n borderColor?: ColorOptions;\n\n // Content\n maxItems?: number;\n};\n\nexport function ToDoWidget({\n // Title defaults\n titleEnabled = true,\n titleText = \"To-Do\",\n titleFontSize = \"lg\",\n titleColor = \"foreground\",\n\n // Styling defaults\n background = {\n type: \"solid\",\n color: \"background\",\n },\n textColor = \"foreground\",\n accentColor = \"primary\",\n padding = 4,\n borderRadius = \"md\",\n borderWidth = \"none\",\n borderColor = \"muted\",\n\n // Content defaults\n maxItems = 5,\n\n className,\n ...props\n}: ToDoWidgetProps): React.JSX.Element {\n const backgroundColor = background.color || \"background\";\n const backgroundImage =\n (background.resource?.image_url || background.resource?.imageUrl) &&\n background.type === \"image\"\n ? `url(${background.resource.image_url || background.resource.imageUrl})`\n : \"none\";\n const { data: todos = [], isLoading, isError } = useTodos();\n const updateTodo = useUpdateTodo();\n const { isPreview } = useWidgetPreviewContext();\n const [pendingIds, setPendingIds] = useState<Set<number>>(new Set());\n const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false);\n\n const toggleTodo = (id: number, completed: boolean) => {\n if (isPreview || pendingIds.has(id)) return;\n setPendingIds((prev) => new Set(prev).add(id));\n updateTodo.mutate(\n { id, completed },\n {\n onSettled: () =>\n setPendingIds((prev) => {\n const next = new Set(prev);\n next.delete(id);\n return next;\n }),\n },\n );\n };\n\n const activeTodos = todos.filter((todo) => !todo.completedAt);\n const todosToShow = activeTodos.slice(0, maxItems);\n const remainingCount = activeTodos.length - todosToShow.length;\n const isEmpty = activeTodos.length === 0;\n\n // Group todos by contactId so same-named contacts stay separate.\n const groupedTodos = todosToShow.reduce<\n {\n contactId: number | null;\n contactName: string | null;\n todos: typeof todosToShow;\n }[]\n >((groups, todo) => {\n const existing = groups.find((g) => g.contactId === todo.contactId);\n if (existing) {\n existing.todos.push(todo);\n } else {\n groups.push({\n contactId: todo.contactId,\n contactName: todo.contactName,\n todos: [todo],\n });\n }\n return groups;\n }, []);\n\n return (\n <div\n className={`overflow-hidden rounded-${borderRadius} ${borderWidthClasses[borderWidth]} ${borderWidth !== \"none\" ? borderColorClasses[borderColor] : \"\"} bg-${backgroundColor} text-${textColor} p-${padding} ${className ?? \"\"}`}\n style={{ backgroundImage }}\n {...props}\n >\n {/* Header */}\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n {titleEnabled && titleText && (\n <h2\n className={`text-${titleFontSize} font-header font-bold text-${titleColor}`}\n >\n {titleText}\n </h2>\n )}\n </div>\n <div className=\"flex items-center gap-2\">\n {!isEmpty && !isLoading && (\n <span className={`text-2xl font-bold text-${accentColor}`}>\n {activeTodos.length}\n </span>\n )}\n <div className={`flex size-10 shrink-0 items-center justify-center`}>\n <ListChecks className={`h-5 w-5 text-${accentColor}-foreground`} />\n </div>\n </div>\n </div>\n\n {/* Loading state */}\n {isLoading ? (\n <div className=\"flex min-h-[120px] items-center justify-center\">\n <div className=\"size-6 animate-spin rounded-full border-2 border-current border-t-transparent\" />\n </div>\n ) : isError ? (\n /* Error state */\n <ErrorState />\n ) : isEmpty ? (\n /* Empty state */\n <div className=\"flex flex-col items-center justify-center gap-3 py-8\">\n <p className={`text-center text-${textColor}/60`}>\n You&apos;ve got nothing else To-Do!\n </p>\n {!isPreview && (\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n className={`inline-flex items-center gap-1.5 rounded-full bg-${accentColor} text-${accentColor}-foreground hover:bg-${accentColor}/90 px-4 py-1.5 text-xs font-semibold transition-colors`}\n >\n <Plus className=\"size-3.5\" aria-hidden=\"true\" />\n Add to-do\n </button>\n )}\n </div>\n ) : (\n /* Todo List */\n <>\n <div className=\"flex flex-col gap-3\">\n {groupedTodos.map((group) => (\n <div\n key={group.contactId ?? \"__unassigned__\"}\n className=\"flex flex-col\"\n >\n {group.contactName && (\n <div\n className={`mb-1 text-xs font-semibold tracking-wide uppercase text-${textColor}/60`}\n >\n {group.contactName}\n </div>\n )}\n {group.todos.map((todo, index) => (\n <div\n key={todo.id}\n className={`flex items-center gap-3 py-2 ${\n index !== group.todos.length - 1\n ? `border-b border-${textColor}/10`\n : \"\"\n }`}\n >\n <input\n type=\"checkbox\"\n className={`h-5 w-5 rounded-full border-2 border-${textColor}/30 bg-transparent not-disabled:cursor-pointer disabled:cursor-not-allowed disabled:opacity-60`}\n checked={!!todo.completedAt}\n disabled={isPreview || pendingIds.has(todo.id)}\n onChange={(event) =>\n toggleTodo(todo.id, event.target.checked)\n }\n />\n <span className=\"line-clamp-1 flex-1 text-sm\">\n {parseTaskBody(todo.body).title}\n </span>\n </div>\n ))}\n </div>\n ))}\n </div>\n\n {/* Footer */}\n <div className=\"mt-2 flex items-center justify-between\">\n {remainingCount > 0 && (\n <span className={`text-sm text-${textColor}/50 underline`}>\n {remainingCount} more task{remainingCount > 1 ? \"s\" : \"\"}\n </span>\n )}\n <div className=\"ml-auto\">\n <button\n type=\"button\"\n onClick={() => setIsCreateDialogOpen(true)}\n disabled={isPreview}\n aria-label=\"Add to-do\"\n className={`flex h-8 w-8 items-center justify-center rounded-full transition-colors not-disabled:cursor-pointer hover:bg-${textColor}/10 disabled:opacity-60`}\n >\n <Plus className={`h-5 w-5 text-${textColor}/50`} />\n </button>\n </div>\n </div>\n </>\n )}\n\n {!isPreview && (\n <CreateTodoDialog\n open={isCreateDialogOpen}\n onOpenChange={setIsCreateDialogOpen}\n />\n )}\n </div>\n );\n}\n\nexport const toDoWidgetPropertySchema: WidgetPropertySchema = {\n widgetType: \"ToDoWidget\",\n displayName: \"To-Do Widget\",\n tabsConfig: [{ id: \"styling\", label: \"Styling\" }],\n fields: [\n // Styling Tab - Title Group\n {\n key: \"titleEnabled\",\n label: \"Widget Title\",\n type: \"boolean\",\n description: \"Enable the title displayed above the todo list\",\n defaultValue: true,\n tab: \"styling\",\n group: \"Title\",\n },\n {\n key: \"titleText\",\n label: \"Title\",\n type: \"text\",\n description: \"Title text displayed above the todo list\",\n defaultValue: \"To-Do\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n },\n getFontSizeField({\n key: \"titleFontSize\",\n label: \"Title Font Size\",\n description: \"Font size for the widget title\",\n defaultValue: \"xl\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n getColorField({\n key: \"titleColor\",\n label: \"Title Color\",\n description: \"Color for the widget title\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Title\",\n requiresKeyToBeTrue: \"titleEnabled\",\n }),\n\n // Styling Tab - Design Group\n {\n type: \"background\",\n key: \"background\",\n label: \"Background\",\n description: \"Background for the widget container\",\n defaultValue: \"background\",\n tab: \"styling\",\n group: \"Design\",\n },\n getColorField({\n key: \"textColor\",\n label: \"Text Color\",\n description: \"Default text color for todo items\",\n defaultValue: \"foreground\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getColorField({\n key: \"accentColor\",\n label: \"Accent Color\",\n description: \"Color used for count badge and icon\",\n defaultValue: \"primary\",\n tab: \"styling\",\n group: \"Design\",\n }),\n {\n key: \"separator\",\n type: \"separator\",\n label: \"Separator\",\n tab: \"styling\",\n group: \"Design\",\n },\n {\n key: \"maxItems\",\n label: \"Max Items\",\n type: \"number\",\n description: \"Maximum number of todo items to display\",\n min: 1,\n max: 20,\n step: 1,\n defaultValue: 5,\n tab: \"styling\",\n group: \"Design\",\n },\n getPaddingField({\n key: \"padding\",\n label: \"Padding\",\n description: \"Padding around the widget container\",\n defaultValue: 4,\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderRadiusField({\n key: \"borderRadius\",\n label: \"Border Radius\",\n description: \"Border radius for the widget container\",\n defaultValue: \"md\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderWidthField({\n key: \"borderWidth\",\n label: \"Border Width\",\n description: \"Border width for the widget\",\n defaultValue: \"none\",\n tab: \"styling\",\n group: \"Design\",\n }),\n getBorderColorField({\n key: \"borderColor\",\n label: \"Border Color\",\n description: \"Border color for the widget\",\n defaultValue: \"muted\",\n tab: \"styling\",\n group: \"Design\",\n }),\n ],\n} as const satisfies WidgetPropertySchema;\n"],"mappings":"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CL,OAAO;GACR;EACDA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFA,mBAAAA,cAAc;GACZ,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACF;GACE,KAAK;GACL,MAAM;GACN,OAAO;GACP,KAAK;GACL,OAAO;GACR;EACD;GACE,KAAK;GACL,OAAO;GACP,MAAM;GACN,aAAa;GACb,KAAK;GACL,KAAK;GACL,MAAM;GACN,cAAc;GACd,KAAK;GACL,OAAO;GACR;EACDC,mBAAAA,gBAAgB;GACd,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,qBAAqB;GACnB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACFC,mBAAAA,oBAAoB;GAClB,KAAK;GACL,OAAO;GACP,aAAa;GACb,cAAc;GACd,KAAK;GACL,OAAO;GACR,CAAC;EACH;CACF"}
package/dist/index.cjs CHANGED
@@ -1,20 +1,20 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-9hOWP6kD.cjs");
3
- const require_FluidProvider = require("./FluidProvider-CYgSHMUd.cjs");
4
- const require_ScreenRenderer = require("./ScreenRenderer-BYiZunHL.cjs");
3
+ const require_FluidProvider = require("./FluidProvider-BFU7ermL.cjs");
4
+ const require_ScreenRenderer = require("./ScreenRenderer-CLDJUinO.cjs");
5
5
  const require_PortalTenantClientProvider = require("./PortalTenantClientProvider-Bpm-CZq1.cjs");
6
6
  require("./store-api-context-D1gZn22Z.cjs");
7
7
  require("./mysite-api-context-CilZcDS4.cjs");
8
8
  require("./countries-api-context-G-NW4BoH.cjs");
9
- require("./task-composer-form-2z5Qk6US.cjs");
9
+ require("./task-composer-form-BEZGTBBZ.cjs");
10
10
  require("./registry-context-DJ5xiVnt.cjs");
11
11
  const require_WidgetInteractionContext = require("./WidgetInteractionContext-BhkusA95.cjs");
12
- const require_EmbedWidget = require("./EmbedWidget-BjLKHqCD.cjs");
12
+ const require_EmbedWidget = require("./EmbedWidget-B1gWxgsn.cjs");
13
13
  const require_QuickLinksWidget = require("./QuickLinksWidget-Cik7DoRr.cjs");
14
14
  const require_static_dict_adapter = require("./static-dict-adapter-JAau5LHb.cjs");
15
15
  require("./error-state-DJq7C-23.cjs");
16
16
  require("./translation-api-context-factory-BSRK6Z50.cjs");
17
- const require_LayoutWidget = require("./LayoutWidget-_f70Meea.cjs");
17
+ const require_LayoutWidget = require("./LayoutWidget-CG-dWz_c.cjs");
18
18
  const require_registries = require("./registries-CpUM406S.cjs");
19
19
  require("./fields-C8gY9GlT.cjs");
20
20
  const require_TextWidget = require("./TextWidget-D9H9WUPH.cjs");
@@ -22,51 +22,51 @@ const require_AlertWidget = require("./AlertWidget-Bli5ni5t.cjs");
22
22
  const require_BulletListWidget = require("./BulletListWidget-BHkly6-D.cjs");
23
23
  require("./preview-context-BWCl-xyj.cjs");
24
24
  const require_CalendarWidget = require("./CalendarWidget-DW5wz5ke.cjs");
25
- const require_CardWidget = require("./CardWidget-Jv6HiiK-.cjs");
25
+ const require_CardWidget = require("./CardWidget--S5FBquC.cjs");
26
26
  require("./purify.es-3IyrJU0_.cjs");
27
27
  require("./MediaRenderer-D-hwg614.cjs");
28
28
  const require_CarouselWidget = require("./CarouselWidget-DtwI2yEZ.cjs");
29
29
  const require_CatchUpWidget = require("./CatchUpWidget-_ErrC-e8.cjs");
30
30
  const require_src = require("./src-Cx7UyT_c.cjs");
31
31
  const require_ChartWidget = require("./ChartWidget-BwluyVCs.cjs");
32
- const require_ContainerWidget = require("./ContainerWidget-BJys0vji.cjs");
32
+ const require_ContainerWidget = require("./ContainerWidget-Cf_D4TAi.cjs");
33
33
  const require_ImageWidget = require("./ImageWidget-CeAngL6c.cjs");
34
34
  const require_LinkWidget = require("./LinkWidget-Cm-vPKHS.cjs");
35
35
  const require_ListWidget = require("./ListWidget-D0fL1xOX.cjs");
36
- const require_MySiteWidget = require("./MySiteWidget-CAj-6hXM.cjs");
37
- const require_NestedWidget = require("./NestedWidget-D1iDgWh8.cjs");
36
+ const require_MySiteWidget = require("./MySiteWidget-23lGcDO1.cjs");
37
+ const require_NestedWidget = require("./NestedWidget-CZGOZbpZ.cjs");
38
38
  const require_PointsWidget = require("./PointsWidget-Byd2-eEi.cjs");
39
39
  const require_QuickShareWidget = require("./QuickShareWidget-BwOhBs6H.cjs");
40
- const require_RecentActivityWidget = require("./RecentActivityWidget-DnGybdc3.cjs");
40
+ const require_RecentActivityWidget = require("./RecentActivityWidget-DZGKRR5x.cjs");
41
41
  const require_SeparatorWidget = require("./SeparatorWidget-R9PjLUJh.cjs");
42
42
  const require_SpacerWidget = require("./SpacerWidget-CYHjTF38.cjs");
43
- const require_TableWidget = require("./TableWidget-wQkzw7Jg.cjs");
44
- const require_ToDoWidget = require("./ToDoWidget-1ZaXZTi4.cjs");
43
+ const require_TableWidget = require("./TableWidget-RK0B52qT.cjs");
44
+ const require_ToDoWidget = require("./ToDoWidget-C03kvBE-.cjs");
45
45
  const require_VideoWidget = require("./VideoWidget-Ccer5Uc-.cjs");
46
- const require_SearchSort = require("./SearchSort-K0-ffUoD.cjs");
47
- const require_ShopWidget = require("./ShopWidget-BZ48BUxp.cjs");
46
+ const require_SearchSort = require("./SearchSort-CDuQPacI.cjs");
47
+ const require_ShopWidget = require("./ShopWidget-BAi2p8DP.cjs");
48
48
  const require_ScreenHeaderContext = require("./ScreenHeaderContext-DWDN0-mb.cjs");
49
49
  const require_CustomersScreen = require("./CustomersScreen-C0nLka_R.cjs");
50
50
  const require_use_store = require("./use-store-D2S1FywW.cjs");
51
51
  const require_use_account = require("./use-account-BMLTwG3m.cjs");
52
52
  const require_AppNavigationContext = require("./AppNavigationContext-CDowN9gd.cjs");
53
- const require_MessagingScreen = require("./MessagingScreen-C_VnN2yj.cjs");
54
- require("./AddressAutocompleteInput-CZITNL-n.cjs");
53
+ const require_MessagingScreen = require("./MessagingScreen-D_wVko-i.cjs");
54
+ require("./AddressAutocompleteInput-C0ns8N-l.cjs");
55
55
  require("./Combobox-Dfa0Hn-Q.cjs");
56
56
  require("./use-mysite-portal-BmrDScmS.cjs");
57
- const require_ProfileScreen = require("./ProfileScreen-Dshb7RM2.cjs");
58
- const require_SubscriptionsScreen = require("./SubscriptionsScreen-Bupuf-0D.cjs");
57
+ const require_ProfileScreen = require("./ProfileScreen-CP5ijd_t.cjs");
58
+ const require_SubscriptionsScreen = require("./SubscriptionsScreen-Dz1PGO2z.cjs");
59
59
  require("./dist-BPZPs7SF.cjs");
60
60
  require("./es-CtTr3tb5.cjs");
61
- const require_ContactsScreen = require("./ContactsScreen-6x_Y2HBg.cjs");
61
+ const require_ContactsScreen = require("./ContactsScreen-CiegGc50.cjs");
62
62
  require("./dist-C-U7FKrp.cjs");
63
- const require_OrdersScreen = require("./OrdersScreen-C0-X_pGG.cjs");
64
- const require_MySiteScreen = require("./MySiteScreen-BLI39L5d.cjs");
63
+ const require_OrdersScreen = require("./OrdersScreen-TGNvFpjj.cjs");
64
+ const require_MySiteScreen = require("./MySiteScreen-17KRkcj7.cjs");
65
65
  require("./dist-DSufwDW6.cjs");
66
- const require_ShareablesScreen = require("./ShareablesScreen-COVW0ikb.cjs");
67
- const require_ShopScreen = require("./ShopScreen-fcy9uJ3Z.cjs");
66
+ const require_ShareablesScreen = require("./ShareablesScreen-BAOW6RIK.cjs");
67
+ const require_ShopScreen = require("./ShopScreen-BjuLPVrk.cjs");
68
68
  require("./UpgradeScreen-2gP1jzaE.cjs");
69
- require("./AppDownloadScreen-BYjlFEVq.cjs");
69
+ require("./AppDownloadScreen-DqqUBpS-.cjs");
70
70
  let react = require("react");
71
71
  react = require_chunk.__toESM(react);
72
72
  let _tanstack_react_query = require("@tanstack/react-query");
@@ -1693,7 +1693,7 @@ function CollapsibleNavItem({ item, isActive, currentSlug, onNavigate }) {
1693
1693
  onClick: () => onNavigate(childSlug),
1694
1694
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(RepIcon, {
1695
1695
  name: child.icon || "file",
1696
- className: "h-3 w-3"
1696
+ className: "size-3"
1697
1697
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: child.label })]
1698
1698
  }) }, child.slug || child.label);
1699
1699
  }) }) })] })
@@ -1836,7 +1836,7 @@ function LanguageSelector() {
1836
1836
  size: "sm",
1837
1837
  className: "text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shrink-0 gap-1.5",
1838
1838
  "aria-label": t("language_select"),
1839
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "h-3 w-3" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1839
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Globe, { className: "size-3" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1840
1840
  className: "text-xs uppercase",
1841
1841
  children: locale.split("_")[0]
1842
1842
  })]
@@ -1851,7 +1851,7 @@ function LanguageSelector() {
1851
1851
  setLocale(lang.iso);
1852
1852
  setOpen(false);
1853
1853
  },
1854
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: lang.name }), lang.iso === locale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "h-4 w-4" })]
1854
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: lang.name }), lang.iso === locale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, { className: "size-4" })]
1855
1855
  }, lang.iso))
1856
1856
  })]
1857
1857
  });
@@ -1978,7 +1978,7 @@ function collectNavSlugs(items) {
1978
1978
  if (item.slug) slugs.push(normalizeSlug(item.slug));
1979
1979
  for (const child of item.children ?? []) if (child.slug) slugs.push(normalizeSlug(child.slug));
1980
1980
  }
1981
- return [...slugs].sort((a, b) => b.split("/").length - a.split("/").length);
1981
+ return slugs.toSorted((a, b) => b.split("/").length - a.split("/").length);
1982
1982
  }
1983
1983
  /**
1984
1984
  * Find the longest registered nav slug that is a prefix of `fullSlug`.
@@ -2178,17 +2178,17 @@ function BuilderScreenViewImpl({ screen, className }) {
2178
2178
  const BuilderScreenView = (0, react.memo)(BuilderScreenViewImpl);
2179
2179
  //#endregion
2180
2180
  //#region src/shell/system-screen-map.ts
2181
- const ProfileScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProfileScreen-BRbz69S3.cjs")).then((m) => ({ default: m.ProfileScreen })));
2182
- const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-CyT1TpjL.cjs")).then((m) => ({ default: m.OrdersScreen })));
2183
- const SubscriptionsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./SubscriptionsScreen-BoSpOiOm.cjs")).then((m) => ({ default: m.SubscriptionsScreen })));
2184
- const MessagingScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MessagingScreen-CKPKnmdA.cjs")).then((m) => ({ default: m.MessagingScreen })));
2185
- const ContactsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ContactsScreen-BDOyYGyR.cjs")).then((m) => ({ default: m.ContactsScreen })));
2186
- const ShopScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShopScreen-CaEKFEGZ.cjs")).then((m) => ({ default: m.ShopScreen })));
2181
+ const ProfileScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ProfileScreen-DXlKK4gO.cjs")).then((m) => ({ default: m.ProfileScreen })));
2182
+ const OrdersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./OrdersScreen-t1EwXPZx.cjs")).then((m) => ({ default: m.OrdersScreen })));
2183
+ const SubscriptionsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./SubscriptionsScreen-TAXj2UXa.cjs")).then((m) => ({ default: m.SubscriptionsScreen })));
2184
+ const MessagingScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MessagingScreen-7BBNidBx.cjs")).then((m) => ({ default: m.MessagingScreen })));
2185
+ const ContactsScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ContactsScreen-B3Ena0O7.cjs")).then((m) => ({ default: m.ContactsScreen })));
2186
+ const ShopScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShopScreen-CwGh-q7J.cjs")).then((m) => ({ default: m.ShopScreen })));
2187
2187
  const CustomersScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./CustomersScreen-C0nLka_R.cjs")).then((n) => n.CustomersScreen_exports).then((m) => ({ default: m.CustomersScreen })));
2188
- const ShareablesScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShareablesScreen-BZv1NXJV.cjs")).then((m) => ({ default: m.ShareablesScreen })));
2189
- const MySiteScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MySiteScreen-h7lBk3gC.cjs")).then((m) => ({ default: m.MySiteScreen })));
2188
+ const ShareablesScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./ShareablesScreen-C3juoUMG.cjs")).then((m) => ({ default: m.ShareablesScreen })));
2189
+ const MySiteScreen$1 = (0, react.lazy)(() => Promise.resolve().then(() => require("./MySiteScreen-BdBnDI6s.cjs")).then((m) => ({ default: m.MySiteScreen })));
2190
2190
  const UpgradeScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./UpgradeScreen-B6CNIieQ.cjs")).then((m) => ({ default: m.UpgradeScreen })));
2191
- const AppDownloadScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./AppDownloadScreen-BYjlFEVq.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => ({ default: m.AppDownloadScreen })));
2191
+ const AppDownloadScreen = (0, react.lazy)(() => Promise.resolve().then(() => require("./AppDownloadScreen-DqqUBpS-.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => ({ default: m.AppDownloadScreen })));
2192
2192
  const SYSTEM_SLUG_SCREEN_MAP = {
2193
2193
  profile: ProfileScreen$1,
2194
2194
  account: ProfileScreen$1,
@@ -2282,7 +2282,7 @@ function PageRouter({ currentSlug, currentNavItem, customPages, screens, baseSlu
2282
2282
  if (SystemScreen && systemScreenInNav) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Suspense, {
2283
2283
  fallback: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2284
2284
  className: "flex h-full items-center justify-center",
2285
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "border-primary h-8 w-8 animate-spin rounded-full border-2 border-t-transparent" })
2285
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "border-primary size-8 animate-spin rounded-full border-2 border-t-transparent" })
2286
2286
  }),
2287
2287
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SystemScreen, {})
2288
2288
  });
@@ -4090,17 +4090,17 @@ zod.z.object({
4090
4090
  //#endregion
4091
4091
  //#region src/screens/index.ts
4092
4092
  const screenPropertySchemas = {
4093
- ProfileScreen: () => Promise.resolve().then(() => require("./ProfileScreen-BRbz69S3.cjs")).then((m) => m.profileScreenPropertySchema),
4094
- MessagingScreen: () => Promise.resolve().then(() => require("./MessagingScreen-CKPKnmdA.cjs")).then((m) => m.messagingScreenPropertySchema),
4095
- ContactsScreen: () => Promise.resolve().then(() => require("./ContactsScreen-BDOyYGyR.cjs")).then((m) => m.contactsScreenPropertySchema),
4096
- OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-CyT1TpjL.cjs")).then((m) => m.ordersScreenPropertySchema),
4097
- SubscriptionsScreen: () => Promise.resolve().then(() => require("./SubscriptionsScreen-BoSpOiOm.cjs")).then((m) => m.subscriptionsScreenPropertySchema),
4093
+ ProfileScreen: () => Promise.resolve().then(() => require("./ProfileScreen-DXlKK4gO.cjs")).then((m) => m.profileScreenPropertySchema),
4094
+ MessagingScreen: () => Promise.resolve().then(() => require("./MessagingScreen-7BBNidBx.cjs")).then((m) => m.messagingScreenPropertySchema),
4095
+ ContactsScreen: () => Promise.resolve().then(() => require("./ContactsScreen-B3Ena0O7.cjs")).then((m) => m.contactsScreenPropertySchema),
4096
+ OrdersScreen: () => Promise.resolve().then(() => require("./OrdersScreen-t1EwXPZx.cjs")).then((m) => m.ordersScreenPropertySchema),
4097
+ SubscriptionsScreen: () => Promise.resolve().then(() => require("./SubscriptionsScreen-TAXj2UXa.cjs")).then((m) => m.subscriptionsScreenPropertySchema),
4098
4098
  CustomersScreen: () => Promise.resolve().then(() => require("./CustomersScreen-C0nLka_R.cjs")).then((n) => n.CustomersScreen_exports).then((m) => m.customersScreenPropertySchema),
4099
- MySiteScreen: () => Promise.resolve().then(() => require("./MySiteScreen-h7lBk3gC.cjs")).then((m) => m.mySiteScreenPropertySchema),
4100
- ShareablesScreen: () => Promise.resolve().then(() => require("./ShareablesScreen-BZv1NXJV.cjs")).then((m) => m.shareablesScreenPropertySchema),
4101
- ShopScreen: () => Promise.resolve().then(() => require("./ShopScreen-CaEKFEGZ.cjs")).then((m) => m.shopScreenPropertySchema),
4099
+ MySiteScreen: () => Promise.resolve().then(() => require("./MySiteScreen-BdBnDI6s.cjs")).then((m) => m.mySiteScreenPropertySchema),
4100
+ ShareablesScreen: () => Promise.resolve().then(() => require("./ShareablesScreen-C3juoUMG.cjs")).then((m) => m.shareablesScreenPropertySchema),
4101
+ ShopScreen: () => Promise.resolve().then(() => require("./ShopScreen-CwGh-q7J.cjs")).then((m) => m.shopScreenPropertySchema),
4102
4102
  UpgradeScreen: () => Promise.resolve().then(() => require("./UpgradeScreen-B6CNIieQ.cjs")).then((m) => m.upgradeScreenPropertySchema),
4103
- AppDownloadScreen: () => Promise.resolve().then(() => require("./AppDownloadScreen-BYjlFEVq.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => m.appDownloadScreenPropertySchema)
4103
+ AppDownloadScreen: () => Promise.resolve().then(() => require("./AppDownloadScreen-DqqUBpS-.cjs")).then((n) => n.AppDownloadScreen_exports).then((m) => m.appDownloadScreenPropertySchema)
4104
4104
  };
4105
4105
  /**
4106
4106
  * Core page template IDs
@@ -4371,7 +4371,7 @@ function QuickLinksDropdown({ onNavigate }) {
4371
4371
  size: "sm",
4372
4372
  className: "text-sidebar-foreground hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shrink-0",
4373
4373
  "aria-label": t("nav_quick_links"),
4374
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LayoutGrid, { className: "h-4 w-4" })
4374
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LayoutGrid, { className: "size-4" })
4375
4375
  })
4376
4376
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.PopoverContent, {
4377
4377
  align: "end",
@@ -4380,7 +4380,7 @@ function QuickLinksDropdown({ onNavigate }) {
4380
4380
  className: "flex flex-col",
4381
4381
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4382
4382
  className: "bg-background flex items-center gap-2 border-b p-4",
4383
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LayoutGrid, { className: "text-muted-foreground h-5 w-5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
4383
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.LayoutGrid, { className: "text-muted-foreground size-5" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
4384
4384
  className: "text-foreground text-sm font-semibold",
4385
4385
  children: t("nav_shortcuts")
4386
4386
  })]
@@ -4402,7 +4402,7 @@ function QuickLinksDropdown({ onNavigate }) {
4402
4402
  },
4403
4403
  children: [item.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RepIcon, {
4404
4404
  name: item.icon,
4405
- className: "h-4 w-4 shrink-0"
4405
+ className: "size-4 shrink-0"
4406
4406
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
4407
4407
  className: "truncate",
4408
4408
  children: item.label