@mastra/playground-ui 68.0.0-alpha.1 → 68.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/dist/{DataCodeSection-CcPmJPTp.cjs → DataCodeSection-CFxXsQWH.cjs} +3 -3
  2. package/dist/DataCodeSection-CFxXsQWH.cjs.map +1 -0
  3. package/dist/{DataCodeSection-KJRyRD1Q.js → DataCodeSection-PY9XEg2C.js} +3 -3
  4. package/dist/DataCodeSection-PY9XEg2C.js.map +1 -0
  5. package/dist/{DataPanel-BwB1Oifd.cjs → DataPanel-Coc9h35I.cjs} +2 -2
  6. package/dist/{DataPanel-BwB1Oifd.cjs.map → DataPanel-Coc9h35I.cjs.map} +1 -1
  7. package/dist/{DataPanel-Bv4M17xO.js → DataPanel-IgB9D5PO.js} +2 -2
  8. package/dist/{DataPanel-Bv4M17xO.js.map → DataPanel-IgB9D5PO.js.map} +1 -1
  9. package/dist/{FilterBar-BO-vvvyq.js → FilterBar-BgW2dqRQ.js} +7 -7
  10. package/dist/FilterBar-BgW2dqRQ.js.map +1 -0
  11. package/dist/{FilterBar-Buw0tv51.cjs → FilterBar-CQl04O6t.cjs} +7 -7
  12. package/dist/FilterBar-CQl04O6t.cjs.map +1 -0
  13. package/dist/{MetricsTable-D-aZf3dk.cjs → MetricsTable-BSl81oNe.cjs} +44 -9
  14. package/dist/MetricsTable-BSl81oNe.cjs.map +1 -0
  15. package/dist/{MetricsTable-CRPeLHe1.js → MetricsTable-DID6LRoP.js} +44 -9
  16. package/dist/MetricsTable-DID6LRoP.js.map +1 -0
  17. package/dist/{ask-user-DdYz56qH.cjs → ask-user-C1p2PEYe.cjs} +2 -2
  18. package/dist/ask-user-C1p2PEYe.cjs.map +1 -0
  19. package/dist/{ask-user-B225wzWc.js → ask-user-DPznrqGO.js} +2 -2
  20. package/dist/ask-user-DPznrqGO.js.map +1 -0
  21. package/dist/chart-plot.css +5 -4
  22. package/dist/{combobox-CtCK0mNx.js → combobox-D21no8t5.js} +4 -4
  23. package/dist/{combobox-CtCK0mNx.js.map → combobox-D21no8t5.js.map} +1 -1
  24. package/dist/{combobox-CMx2ayFN.cjs → combobox-DIT_6xiG.cjs} +4 -4
  25. package/dist/combobox-DIT_6xiG.cjs.map +1 -0
  26. package/dist/{combobox-parts-ScKcYjMR.cjs → combobox-parts-C4phOq4t.cjs} +2 -2
  27. package/dist/combobox-parts-C4phOq4t.cjs.map +1 -0
  28. package/dist/{combobox-parts-C1CugUAU.js → combobox-parts-D90ir0Py.js} +3 -3
  29. package/dist/combobox-parts-D90ir0Py.js.map +1 -0
  30. package/dist/components/Combobox.cjs.js +2 -2
  31. package/dist/components/Combobox.es.js +2 -2
  32. package/dist/components/Command.cjs.js +1 -1
  33. package/dist/components/Command.cjs.js.map +1 -1
  34. package/dist/components/Command.es.js +1 -1
  35. package/dist/components/Command.es.js.map +1 -1
  36. package/dist/components/DataCodeSection.cjs.js +1 -1
  37. package/dist/components/DataCodeSection.es.js +1 -1
  38. package/dist/components/DataList.cjs.js +1 -1
  39. package/dist/components/DataList.es.js +1 -1
  40. package/dist/components/DataPanel.cjs.js +1 -1
  41. package/dist/components/DataPanel.es.js +1 -1
  42. package/dist/components/DateTimePicker.cjs.js +1 -1
  43. package/dist/components/DateTimePicker.cjs.js.map +1 -1
  44. package/dist/components/DateTimePicker.es.js +1 -1
  45. package/dist/components/DateTimePicker.es.js.map +1 -1
  46. package/dist/components/FilterBar.cjs.js +3 -3
  47. package/dist/components/FilterBar.es.js +3 -3
  48. package/dist/components/FormFieldBlocks.cjs.js +1 -1
  49. package/dist/components/FormFieldBlocks.cjs.js.map +1 -1
  50. package/dist/components/FormFieldBlocks.es.js +1 -1
  51. package/dist/components/FormFieldBlocks.es.js.map +1 -1
  52. package/dist/components/MetricsTable.cjs.js +1 -1
  53. package/dist/components/MetricsTable.es.js +1 -1
  54. package/dist/components/PropertyFilter.cjs.js +3 -3
  55. package/dist/components/PropertyFilter.cjs.js.map +1 -1
  56. package/dist/components/PropertyFilter.es.js +3 -3
  57. package/dist/components/PropertyFilter.es.js.map +1 -1
  58. package/dist/components/SavedViews.cjs.js +1 -1
  59. package/dist/components/SavedViews.es.js +1 -1
  60. package/dist/components/Sidebar.cjs.js +8 -8
  61. package/dist/components/Sidebar.cjs.js.map +1 -1
  62. package/dist/components/Sidebar.es.js +9 -9
  63. package/dist/components/Sidebar.es.js.map +1 -1
  64. package/dist/components/ai/ask-user.cjs.js +1 -1
  65. package/dist/components/ai/ask-user.es.js +1 -1
  66. package/dist/domains/chat/tools/badges/ask-user-badge.cjs.js +1 -1
  67. package/dist/domains/chat/tools/badges/ask-user-badge.es.js +1 -1
  68. package/dist/domains/dashboards/kinds/table/table-view.cjs.js +1 -1
  69. package/dist/domains/dashboards/kinds/table/table-view.es.js +1 -1
  70. package/dist/domains/dashboards/metrics-dashboard.cjs.js +1 -1
  71. package/dist/domains/dashboards/metrics-dashboard.cjs.js.map +1 -1
  72. package/dist/domains/dashboards/metrics-dashboard.es.js +1 -1
  73. package/dist/domains/dashboards/metrics-dashboard.es.js.map +1 -1
  74. package/dist/domains/datasets/components/save-as-dataset-item-dialog.cjs.js +1 -1
  75. package/dist/domains/datasets/components/save-as-dataset-item-dialog.es.js +1 -1
  76. package/dist/domains/logs/components/log-data-panel.cjs.js +1 -1
  77. package/dist/domains/logs/components/log-data-panel.es.js +1 -1
  78. package/dist/domains/logs/components/logs-saved-views.cjs.js +1 -1
  79. package/dist/domains/logs/components/logs-saved-views.es.js +1 -1
  80. package/dist/domains/logs/components/logs-toolbar.cjs.js +1 -1
  81. package/dist/domains/logs/components/logs-toolbar.es.js +1 -1
  82. package/dist/domains/metrics/components/breakdown/breakdown-table.cjs.js +2 -2
  83. package/dist/domains/metrics/components/breakdown/breakdown-table.cjs.js.map +1 -1
  84. package/dist/domains/metrics/components/breakdown/breakdown-table.es.js +2 -2
  85. package/dist/domains/metrics/components/breakdown/breakdown-table.es.js.map +1 -1
  86. package/dist/domains/metrics/components/metrics-time-range-chip.cjs.js +1 -1
  87. package/dist/domains/metrics/components/metrics-time-range-chip.es.js +1 -1
  88. package/dist/domains/observability/saved-views/observability-saved-views.cjs.js +1 -1
  89. package/dist/domains/observability/saved-views/observability-saved-views.es.js +1 -1
  90. package/dist/domains/observability/saved-views.cjs.js +1 -1
  91. package/dist/domains/observability/saved-views.es.js +1 -1
  92. package/dist/domains/observability.cjs.js +1 -1
  93. package/dist/domains/observability.es.js +1 -1
  94. package/dist/domains/scores/components/score-data-panel.cjs.js +1 -1
  95. package/dist/domains/scores/components/score-data-panel.es.js +1 -1
  96. package/dist/domains/scores/components/span-scoring.cjs.js +3 -3
  97. package/dist/domains/scores/components/span-scoring.cjs.js.map +1 -1
  98. package/dist/domains/scores/components/span-scoring.es.js +3 -3
  99. package/dist/domains/scores/components/span-scoring.es.js.map +1 -1
  100. package/dist/domains/skills/skill-simple-form.cjs.js +1 -1
  101. package/dist/domains/skills/skill-simple-form.cjs.js.map +1 -1
  102. package/dist/domains/skills/skill-simple-form.es.js +1 -1
  103. package/dist/domains/skills/skill-simple-form.es.js.map +1 -1
  104. package/dist/domains/spans/components/spans-explorer-body.cjs.js +1 -1
  105. package/dist/domains/spans/components/spans-explorer-body.es.js +1 -1
  106. package/dist/domains/spans/components/spans-filter-bar.cjs.js +3 -3
  107. package/dist/domains/spans/components/spans-filter-bar.cjs.js.map +1 -1
  108. package/dist/domains/spans/components/spans-filter-bar.es.js +3 -3
  109. package/dist/domains/spans/components/spans-filter-bar.es.js.map +1 -1
  110. package/dist/domains/spans/hooks/use-spans-filter-bar.cjs.js +1 -1
  111. package/dist/domains/spans/hooks/use-spans-filter-bar.es.js +1 -1
  112. package/dist/domains/threads/components/threads-explorer-body.cjs.js +1 -1
  113. package/dist/domains/threads/components/threads-explorer-body.es.js +1 -1
  114. package/dist/domains/threads/components/threads-filter-bar.cjs.js +3 -3
  115. package/dist/domains/threads/components/threads-filter-bar.cjs.js.map +1 -1
  116. package/dist/domains/threads/components/threads-filter-bar.es.js +3 -3
  117. package/dist/domains/threads/components/threads-filter-bar.es.js.map +1 -1
  118. package/dist/domains/threads/hooks/use-threads-filter-bar.cjs.js +1 -1
  119. package/dist/domains/threads/hooks/use-threads-filter-bar.es.js +1 -1
  120. package/dist/domains/traces/components/feedback-thread.cjs.js +1 -1
  121. package/dist/domains/traces/components/feedback-thread.cjs.js.map +1 -1
  122. package/dist/domains/traces/components/feedback-thread.es.js +1 -1
  123. package/dist/domains/traces/components/feedback-thread.es.js.map +1 -1
  124. package/dist/domains/traces/components/span-data-panel-view.cjs.js +1 -1
  125. package/dist/domains/traces/components/span-data-panel-view.es.js +1 -1
  126. package/dist/domains/traces/components/span-summary-description.cjs.js +1 -1
  127. package/dist/domains/traces/components/span-summary-description.es.js +1 -1
  128. package/dist/domains/traces/components/thread-trace/thread-trace-details.cjs.js +1 -1
  129. package/dist/domains/traces/components/thread-trace/thread-trace-details.es.js +1 -1
  130. package/dist/domains/traces/components/trace-columns-menu.cjs.js +3 -3
  131. package/dist/domains/traces/components/trace-columns-menu.cjs.js.map +1 -1
  132. package/dist/domains/traces/components/trace-columns-menu.es.js +3 -3
  133. package/dist/domains/traces/components/trace-columns-menu.es.js.map +1 -1
  134. package/dist/domains/traces/components/trace-data-panel-view.cjs.js +2 -2
  135. package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
  136. package/dist/domains/traces/components/trace-data-panel-view.es.js +2 -2
  137. package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
  138. package/dist/domains/traces/components/trace-id-button.cjs.js +1 -1
  139. package/dist/domains/traces/components/trace-id-button.es.js +1 -1
  140. package/dist/domains/traces/components/trace-summary-description.cjs.js +1 -1
  141. package/dist/domains/traces/components/trace-summary-description.es.js +1 -1
  142. package/dist/domains/traces/components/trace-thread-panel.cjs.js +1 -1
  143. package/dist/domains/traces/components/trace-thread-panel.es.js +1 -1
  144. package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.cjs.js +3 -3
  145. package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.cjs.js.map +1 -1
  146. package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.es.js +3 -3
  147. package/dist/domains/traces/components/traces-explorer/traces-explorer-filter-bar.es.js.map +1 -1
  148. package/dist/domains/traces/components/traces-explorer/traces-explorer-saved-views.cjs.js +1 -1
  149. package/dist/domains/traces/components/traces-explorer/traces-explorer-saved-views.es.js +1 -1
  150. package/dist/domains/traces/components/traces-explorer/use-traces-filter-bar.cjs.js +1 -1
  151. package/dist/domains/traces/components/traces-explorer/use-traces-filter-bar.es.js +1 -1
  152. package/dist/domains/workflows/components/workflow-combobox.cjs.js +2 -2
  153. package/dist/domains/workflows/components/workflow-combobox.cjs.js.map +1 -1
  154. package/dist/domains/workflows/components/workflow-combobox.es.js +2 -2
  155. package/dist/domains/workflows/components/workflow-combobox.es.js.map +1 -1
  156. package/dist/domains/workflows/workflow/input/workflow-processor-input.cjs.js +1 -1
  157. package/dist/domains/workflows/workflow/input/workflow-processor-input.cjs.js.map +1 -1
  158. package/dist/domains/workflows/workflow/input/workflow-processor-input.es.js +1 -1
  159. package/dist/domains/workflows/workflow/input/workflow-processor-input.es.js.map +1 -1
  160. package/dist/domains/workspace/components/workspace-add-skill-dialog.cjs.js +1 -1
  161. package/dist/domains/workspace/components/workspace-add-skill-dialog.cjs.js.map +1 -1
  162. package/dist/domains/workspace/components/workspace-add-skill-dialog.es.js +1 -1
  163. package/dist/domains/workspace/components/workspace-add-skill-dialog.es.js.map +1 -1
  164. package/dist/{filter-bar-chip-B4sV4gDm.js → filter-bar-chip-CABeKrtf.js} +4 -4
  165. package/dist/{filter-bar-chip-B4sV4gDm.js.map → filter-bar-chip-CABeKrtf.js.map} +1 -1
  166. package/dist/{filter-bar-chip-CIEsWcEw.cjs → filter-bar-chip-Cg-UbIwP.cjs} +4 -4
  167. package/dist/{filter-bar-chip-CIEsWcEw.cjs.map → filter-bar-chip-Cg-UbIwP.cjs.map} +1 -1
  168. package/dist/{filter-bar-time-range-DvuaFnkI.cjs → filter-bar-time-range-BA-pXMlo.cjs} +2 -2
  169. package/dist/{filter-bar-time-range-DvuaFnkI.cjs.map → filter-bar-time-range-BA-pXMlo.cjs.map} +1 -1
  170. package/dist/{filter-bar-time-range-CXQMBgpz.js → filter-bar-time-range-mg9JeYue.js} +2 -2
  171. package/dist/{filter-bar-time-range-CXQMBgpz.js.map → filter-bar-time-range-mg9JeYue.js.map} +1 -1
  172. package/dist/layout/tabbed-container.cjs.js +1 -1
  173. package/dist/layout/tabbed-container.es.js +1 -1
  174. package/dist/{observability-saved-views-BBam8Fr5.js → observability-saved-views-CjKTEp1V.js} +3 -3
  175. package/dist/observability-saved-views-CjKTEp1V.js.map +1 -0
  176. package/dist/{observability-saved-views-BAzxxoAr.cjs → observability-saved-views-Daizz4tU.cjs} +3 -3
  177. package/dist/observability-saved-views-Daizz4tU.cjs.map +1 -0
  178. package/dist/primitives/chart-plot.cjs.js +8 -6
  179. package/dist/primitives/chart-plot.cjs.js.map +1 -1
  180. package/dist/primitives/chart-plot.es.js +8 -6
  181. package/dist/primitives/chart-plot.es.js.map +1 -1
  182. package/dist/primitives/control-icon.cjs.js.map +1 -1
  183. package/dist/primitives/control-icon.es.js.map +1 -1
  184. package/dist/{property-filter-applied-p3dTTDdb.js → property-filter-applied--U5EZdaA.js} +2 -2
  185. package/dist/property-filter-applied--U5EZdaA.js.map +1 -0
  186. package/dist/{property-filter-applied-BCeRLcXb.cjs → property-filter-applied-BkkIObRq.cjs} +2 -2
  187. package/dist/property-filter-applied-BkkIObRq.cjs.map +1 -0
  188. package/dist/src/ds/components/MetricsTable/metrics-table-rows.d.ts +10 -3
  189. package/dist/src/ds/components/MetricsTable/metrics-table.d.ts +1 -1
  190. package/dist/style.css +14 -1
  191. package/dist/{tabbed-container-DQU7pVio.cjs → tabbed-container-B4lCBgRP.cjs} +2 -2
  192. package/dist/{tabbed-container-DQU7pVio.cjs.map → tabbed-container-B4lCBgRP.cjs.map} +1 -1
  193. package/dist/{tabbed-container-5j6dhoRX.js → tabbed-container-DI1GI1Qv.js} +2 -2
  194. package/dist/{tabbed-container-5j6dhoRX.js.map → tabbed-container-DI1GI1Qv.js.map} +1 -1
  195. package/oxlint/index.js +90 -0
  196. package/package.json +8 -8
  197. package/theme.css +4 -3
  198. package/dist/DataCodeSection-CcPmJPTp.cjs.map +0 -1
  199. package/dist/DataCodeSection-KJRyRD1Q.js.map +0 -1
  200. package/dist/FilterBar-BO-vvvyq.js.map +0 -1
  201. package/dist/FilterBar-Buw0tv51.cjs.map +0 -1
  202. package/dist/MetricsTable-CRPeLHe1.js.map +0 -1
  203. package/dist/MetricsTable-D-aZf3dk.cjs.map +0 -1
  204. package/dist/ask-user-B225wzWc.js.map +0 -1
  205. package/dist/ask-user-DdYz56qH.cjs.map +0 -1
  206. package/dist/combobox-CMx2ayFN.cjs.map +0 -1
  207. package/dist/combobox-parts-C1CugUAU.js.map +0 -1
  208. package/dist/combobox-parts-ScKcYjMR.cjs.map +0 -1
  209. package/dist/observability-saved-views-BAzxxoAr.cjs.map +0 -1
  210. package/dist/observability-saved-views-BBam8Fr5.js.map +0 -1
  211. package/dist/property-filter-applied-BCeRLcXb.cjs.map +0 -1
  212. package/dist/property-filter-applied-p3dTTDdb.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyFilter.cjs.js","names":["forwardRef","useMemo","useState","useRef","useCallback","Popover","PopoverTrigger","Button","ListFilterPlusIcon","PopoverContent","cn","ArrowLeftIcon","FilterIcon","Txt","_Fragment","menuItemButtonClass","menuItemTrailingIconClass","PlusIcon","Field","Combobox","FieldError","X","ListFilterPlus","ChevronRightIcon","PickMultiPanel"],"sources":["../../src/ds/components/PropertyFilter/property-filter-creator.tsx"],"sourcesContent":["import {\n ArrowLeftIcon,\n ChevronRightIcon,\n FilterIcon,\n ListFilterPlusIcon,\n PlusIcon,\n ListFilterPlus,\n X,\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { PickMultiPanel } from './pick-multi-panel';\nimport type { PropertyFilterField, PropertyFilterToken } from './types';\nimport { Button } from '@/ds/components/Button/Button';\nimport type { ButtonProps } from '@/ds/components/Button/Button';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport { Field, FieldError } from '@/ds/components/Field';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/ds/components/Popover/popover';\nimport { Txt } from '@/ds/components/Txt';\nimport {\n MENU_SIDE_OFFSET,\n menuEmptyClass,\n menuItemButtonClass,\n menuItemTrailingIconClass,\n} from '@/ds/primitives/menu-item';\nimport { controlStateColorTransition } from '@/ds/primitives/transitions';\nimport { quietTextHover } from '@/ds/primitives/typography';\nimport { cn } from '@/lib/utils';\n\n// Plain <button>s navigated with roving focus (not Base UI).\nconst FilterMenuButton = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>((props, ref) => (\n <button type=\"button\" role=\"menuitem\" data-filter-item=\"\" ref={ref} {...props} />\n));\nFilterMenuButton.displayName = 'FilterMenuButton';\n\nexport type PropertyFilterCreatorProps = {\n fields: PropertyFilterField[];\n tokens: PropertyFilterToken[];\n onTokensChange: (tokens: PropertyFilterToken[]) => void;\n label?: string;\n disabled?: boolean;\n /** Size passed through to the trigger Button. Defaults to 'md'. */\n size?: ButtonProps['size'];\n /**\n * Called when the user picks a text (id-style) field. Consumers are expected\n * to render a pending applied-filter pill with an active input so the user\n * can type the value inline instead of in this popover.\n */\n onStartTextFilter?: (fieldId: string) => void;\n /**\n * Field ids hidden from the Add Filter dropdown. Use to prevent users from\n * recreating a filter that an upstream context already owns (e.g. the agent\n * id when viewing the agent-scoped traces tab).\n */\n hiddenFieldIds?: readonly string[];\n};\n\n/**\n * Minimal Linear-style filter creator: a `+ Filter` button whose popover walks\n * the user through property → value → commit. For id-style text fields, the\n * picker closes immediately and the applied-filter pill owns the input. For\n * `pick-multi` fields (e.g. Root Entity Name) hovering the item opens a\n * separate side popover with checkboxes — each check adds its own applied\n * filter and the main popover stays open so users can pick many.\n */\nexport function PropertyFilterCreator({\n fields,\n tokens,\n onTokensChange,\n label = 'Add filter',\n disabled,\n size,\n onStartTextFilter,\n hiddenFieldIds,\n}: PropertyFilterCreatorProps) {\n const visibleFields = useMemo(() => {\n if (!hiddenFieldIds || hiddenFieldIds.length === 0) return fields;\n const hidden = new Set(hiddenFieldIds);\n return fields.filter(f => !hidden.has(f.id));\n }, [fields, hiddenFieldIds]);\n const [open, setOpen] = useState(false);\n const [fieldId, setFieldId] = useState<string | undefined>();\n const [multiValue, setMultiValue] = useState<string[]>([]);\n const [error, setError] = useState<string | undefined>();\n // Single source of truth for which pick-multi side panel is open. Opens only\n // via explicit click/keyboard press on the menu item — no hover/focus\n // auto-open (was too flicker-prone).\n const [openPickMultiFieldId, setOpenPickMultiFieldId] = useState<string | undefined>();\n\n // When the user picks a text field we close this popover and hand off focus\n // to the newly-created pill's input — prevent Radix from returning focus to\n // the trigger button in that case.\n const skipCloseFocusRef = useRef(false);\n\n const togglePickMulti = useCallback((id: string) => {\n setOpenPickMultiFieldId(current => (current === id ? undefined : id));\n }, []);\n const closePickMulti = useCallback(() => setOpenPickMultiFieldId(undefined), []);\n\n useEffect(() => {\n if (!open) setOpenPickMultiFieldId(undefined);\n }, [open]);\n\n const selectedField = useMemo(() => visibleFields.find(f => f.id === fieldId), [visibleFields, fieldId]);\n // Only single-use kinds (text, multi-select) count as \"used\". `pick-multi`\n // allows multiple tokens with the same fieldId.\n const singleUseFieldIds = useMemo(() => {\n const ids = new Set<string>();\n for (const token of tokens) {\n const field = fields.find(f => f.id === token.fieldId);\n if (field && field.kind !== 'pick-multi') ids.add(token.fieldId);\n }\n return ids;\n }, [tokens, fields]);\n\n const reset = useCallback(() => {\n setFieldId(undefined);\n setMultiValue([]);\n setError(undefined);\n }, []);\n\n useEffect(() => {\n if (!open) reset();\n }, [open, reset]);\n\n /**\n * Replace whatever token exists for `fieldId` with the given value. Used by\n * both single-select (radio) and multi-select (checkbox) pick-multi panels.\n * An empty list means nothing is selected, which removes the token here —\n * unlike the applied pill, where the filter stays on in a neutral state.\n */\n const replacePickMultiToken = useCallback(\n (fieldId: string, value: string | string[]) => {\n const existingIndex = tokens.findIndex(t => t.fieldId === fieldId);\n\n if (Array.isArray(value) && value.length === 0) {\n if (existingIndex === -1) return;\n onTokensChange(tokens.filter((_, i) => i !== existingIndex));\n return;\n }\n\n if (existingIndex === -1) {\n onTokensChange([...tokens, { fieldId, value }]);\n return;\n }\n\n const nextTokens = [...tokens];\n nextTokens[existingIndex] = { fieldId, value };\n onTokensChange(nextTokens);\n },\n [onTokensChange, tokens],\n );\n\n const commit = useCallback(() => {\n if (!selectedField) {\n setError('Choose a property first.');\n return;\n }\n if (singleUseFieldIds.has(selectedField.id)) {\n setError(`Remove the existing ${selectedField.label} filter before adding another.`);\n return;\n }\n if (multiValue.length === 0) {\n setError(`Choose at least one ${selectedField.label.toLowerCase()} value.`);\n return;\n }\n onTokensChange([...tokens, { fieldId: selectedField.id, value: multiValue }]);\n setOpen(false);\n }, [multiValue, onTokensChange, selectedField, singleUseFieldIds, tokens]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button size={size} disabled={disabled} icon={<ListFilterPlusIcon />}>\n {label}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className={cn('w-64', selectedField ? 'p-3' : 'p-1')}\n initialFocus={false}\n finalFocus={() => {\n if (skipCloseFocusRef.current) {\n skipCloseFocusRef.current = false;\n return false;\n }\n return true;\n }}\n >\n <div className={cn('grid', selectedField && 'gap-3')}>\n {selectedField && (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Back to properties\"\n className={cn(quietTextHover, controlStateColorTransition)}\n onClick={reset}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </button>\n <FilterIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n <Txt as=\"span\" variant=\"caption\" tone=\"muted\">{`${selectedField.label} · is`}</Txt>\n </div>\n )}\n\n {!selectedField && (\n <div\n role=\"menu\"\n className=\"max-h-[80dvh] overflow-auto\"\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const buttons = Array.from(\n e.currentTarget.querySelectorAll<HTMLButtonElement>('[data-filter-item]:not([disabled])'),\n );\n if (buttons.length === 0) return;\n e.preventDefault();\n const active = document.activeElement as HTMLElement | null;\n const current = buttons.findIndex(b => b === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = buttons.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % buttons.length;\n else next = current <= 0 ? buttons.length - 1 : current - 1;\n buttons[next]?.focus();\n }}\n >\n <>\n {visibleFields.length > 0 ? (\n visibleFields.map(f => {\n const used = singleUseFieldIds.has(f.id);\n if (f.kind === 'pick-multi') {\n return (\n <PickMultiMenuItem\n key={f.id}\n field={f}\n tokens={tokens}\n onChange={replacePickMultiToken}\n open={openPickMultiFieldId === f.id}\n onToggle={togglePickMulti}\n onClose={closePickMulti}\n />\n );\n }\n return (\n <FilterMenuButton\n key={f.id}\n className={cn(menuItemButtonClass, 'group')}\n disabled={used}\n onClick={() => {\n setError(undefined);\n if (f.kind === 'text') {\n onTokensChange([...tokens, { fieldId: f.id, value: '' }]);\n onStartTextFilter?.(f.id);\n skipCloseFocusRef.current = true;\n setOpen(false);\n return;\n }\n setFieldId(f.id);\n }}\n >\n <span className=\"truncate\">{f.label}</span>\n {used ? (\n <span className=\"ml-auto text-muted-foreground\">In use</span>\n ) : (\n <span\n className={cn(\n menuItemTrailingIconClass,\n 'text-muted-foreground opacity-0 group-hover:opacity-100 group-focus:opacity-100',\n )}\n >\n <PlusIcon />\n </span>\n )}\n </FilterMenuButton>\n );\n })\n ) : (\n <div className={menuEmptyClass}>No matching property.</div>\n )}\n </>\n </div>\n )}\n\n {selectedField && (\n <Field invalid={Boolean(error)}>\n <Combobox\n multiple\n options={selectedField.options ?? []}\n value={multiValue}\n onValueChange={v => {\n setMultiValue(v);\n setError(undefined);\n }}\n placeholder={selectedField.placeholder ?? `Choose ${selectedField.label}`}\n searchPlaceholder={`Search ${selectedField.label.toLowerCase()}...`}\n emptyText={selectedField.emptyText ?? 'No option found.'}\n size=\"md\"\n aria-label={selectedField.label}\n />\n <FieldError>{error}</FieldError>\n </Field>\n )}\n\n {selectedField && (\n <div className=\"flex items-center justify-end gap-2\">\n <Button icon={<X />} variant=\"ghost\" size=\"md\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button icon={<ListFilterPlus />} size=\"md\" onClick={commit}>\n Add filter\n </Button>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\ntype PickMultiField = Extract<PropertyFilterField, { kind: 'pick-multi' }>;\n\ntype PickMultiMenuItemProps = {\n field: PickMultiField;\n tokens: PropertyFilterToken[];\n onChange: (fieldId: string, value: string | string[]) => void;\n open: boolean;\n onToggle: (fieldId: string) => void;\n onClose: () => void;\n};\n\n/**\n * A property-picker menu item that opens a separate Radix popover (portaled to\n * the side) with a radio group (single-select) or checkbox list (multi-select,\n * `field.multi === true`). Open/close is driven by explicit click / keyboard\n * press; the panel only closes when the user clicks outside, presses Escape,\n * or clicks the row again to toggle it off.\n */\nfunction PickMultiMenuItem({ field, tokens, onChange, open, onToggle, onClose }: PickMultiMenuItemProps) {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <Popover\n open={open}\n onOpenChange={next => {\n if (next) onToggle(field.id);\n else onClose();\n }}\n >\n <PopoverTrigger asChild>\n <FilterMenuButton\n className={menuItemButtonClass}\n onKeyDown={e => {\n if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n if (!open) onToggle(field.id);\n e.preventDefault();\n requestAnimationFrame(() => {\n const first = contentRef.current?.querySelector<HTMLElement>(\n 'input, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n first?.focus();\n });\n }}\n >\n {open && <ChevronRightIcon className=\"text-muted-foreground\" />}\n <span className=\"truncate\">{field.label}</span>\n {!open && (\n <span className={cn(menuItemTrailingIconClass, 'text-muted-foreground')}>\n <ChevronRightIcon />\n </span>\n )}\n </FilterMenuButton>\n </PopoverTrigger>\n <PopoverContent\n ref={contentRef}\n side=\"right\"\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className=\"w-64 p-0\"\n initialFocus={false}\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const items = Array.from(\n e.currentTarget.querySelectorAll<HTMLElement>('[data-pick-multi-item]:not([disabled])'),\n );\n if (items.length === 0) return;\n e.preventDefault();\n e.stopPropagation();\n const active = document.activeElement as HTMLElement | null;\n const current = items.findIndex(el => el === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = items.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % items.length;\n else next = current <= 0 ? items.length - 1 : current - 1;\n items[next]?.focus();\n }}\n data-pick-multi-panel\n >\n <PickMultiPanel field={field} tokens={tokens} onChange={onChange} />\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PropertyFilter.cjs.js","names":["forwardRef","useMemo","useState","useRef","useCallback","Popover","PopoverTrigger","Button","ListFilterPlusIcon","PopoverContent","cn","ArrowLeftIcon","FilterIcon","Txt","_Fragment","menuItemButtonClass","menuItemTrailingIconClass","PlusIcon","Field","Combobox","FieldError","X","ListFilterPlus","ChevronRightIcon","PickMultiPanel"],"sources":["../../src/ds/components/PropertyFilter/property-filter-creator.tsx"],"sourcesContent":["import {\n ArrowLeftIcon,\n ChevronRightIcon,\n FilterIcon,\n ListFilterPlusIcon,\n PlusIcon,\n ListFilterPlus,\n X,\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { PickMultiPanel } from './pick-multi-panel';\nimport type { PropertyFilterField, PropertyFilterToken } from './types';\nimport { Button } from '@/ds/components/Button/Button';\nimport type { ButtonProps } from '@/ds/components/Button/Button';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport { Field, FieldError } from '@/ds/components/Field';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/ds/components/Popover/popover';\nimport { Txt } from '@/ds/components/Txt';\nimport {\n MENU_SIDE_OFFSET,\n menuEmptyClass,\n menuItemButtonClass,\n menuItemTrailingIconClass,\n} from '@/ds/primitives/menu-item';\nimport { controlStateColorTransition } from '@/ds/primitives/transitions';\nimport { quietTextHover } from '@/ds/primitives/typography';\nimport { cn } from '@/lib/utils';\n\n// Plain <button>s navigated with roving focus (not Base UI).\nconst FilterMenuButton = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>((props, ref) => (\n <button type=\"button\" role=\"menuitem\" data-filter-item=\"\" ref={ref} {...props} />\n));\nFilterMenuButton.displayName = 'FilterMenuButton';\n\nexport type PropertyFilterCreatorProps = {\n fields: PropertyFilterField[];\n tokens: PropertyFilterToken[];\n onTokensChange: (tokens: PropertyFilterToken[]) => void;\n label?: string;\n disabled?: boolean;\n /** Size passed through to the trigger Button. Defaults to 'md'. */\n size?: ButtonProps['size'];\n /**\n * Called when the user picks a text (id-style) field. Consumers are expected\n * to render a pending applied-filter pill with an active input so the user\n * can type the value inline instead of in this popover.\n */\n onStartTextFilter?: (fieldId: string) => void;\n /**\n * Field ids hidden from the Add Filter dropdown. Use to prevent users from\n * recreating a filter that an upstream context already owns (e.g. the agent\n * id when viewing the agent-scoped traces tab).\n */\n hiddenFieldIds?: readonly string[];\n};\n\n/**\n * Minimal Linear-style filter creator: a `+ Filter` button whose popover walks\n * the user through property → value → commit. For id-style text fields, the\n * picker closes immediately and the applied-filter pill owns the input. For\n * `pick-multi` fields (e.g. Root Entity Name) hovering the item opens a\n * separate side popover with checkboxes — each check adds its own applied\n * filter and the main popover stays open so users can pick many.\n */\nexport function PropertyFilterCreator({\n fields,\n tokens,\n onTokensChange,\n label = 'Add filter',\n disabled,\n size,\n onStartTextFilter,\n hiddenFieldIds,\n}: PropertyFilterCreatorProps) {\n const visibleFields = useMemo(() => {\n if (!hiddenFieldIds || hiddenFieldIds.length === 0) return fields;\n const hidden = new Set(hiddenFieldIds);\n return fields.filter(f => !hidden.has(f.id));\n }, [fields, hiddenFieldIds]);\n const [open, setOpen] = useState(false);\n const [fieldId, setFieldId] = useState<string | undefined>();\n const [multiValue, setMultiValue] = useState<string[]>([]);\n const [error, setError] = useState<string | undefined>();\n // Single source of truth for which pick-multi side panel is open. Opens only\n // via explicit click/keyboard press on the menu item — no hover/focus\n // auto-open (was too flicker-prone).\n const [openPickMultiFieldId, setOpenPickMultiFieldId] = useState<string | undefined>();\n\n // When the user picks a text field we close this popover and hand off focus\n // to the newly-created pill's input — prevent Radix from returning focus to\n // the trigger button in that case.\n const skipCloseFocusRef = useRef(false);\n\n const togglePickMulti = useCallback((id: string) => {\n setOpenPickMultiFieldId(current => (current === id ? undefined : id));\n }, []);\n const closePickMulti = useCallback(() => setOpenPickMultiFieldId(undefined), []);\n\n useEffect(() => {\n if (!open) setOpenPickMultiFieldId(undefined);\n }, [open]);\n\n const selectedField = useMemo(() => visibleFields.find(f => f.id === fieldId), [visibleFields, fieldId]);\n // Only single-use kinds (text, multi-select) count as \"used\". `pick-multi`\n // allows multiple tokens with the same fieldId.\n const singleUseFieldIds = useMemo(() => {\n const ids = new Set<string>();\n for (const token of tokens) {\n const field = fields.find(f => f.id === token.fieldId);\n if (field && field.kind !== 'pick-multi') ids.add(token.fieldId);\n }\n return ids;\n }, [tokens, fields]);\n\n const reset = useCallback(() => {\n setFieldId(undefined);\n setMultiValue([]);\n setError(undefined);\n }, []);\n\n useEffect(() => {\n if (!open) reset();\n }, [open, reset]);\n\n /**\n * Replace whatever token exists for `fieldId` with the given value. Used by\n * both single-select (radio) and multi-select (checkbox) pick-multi panels.\n * An empty list means nothing is selected, which removes the token here —\n * unlike the applied pill, where the filter stays on in a neutral state.\n */\n const replacePickMultiToken = useCallback(\n (fieldId: string, value: string | string[]) => {\n const existingIndex = tokens.findIndex(t => t.fieldId === fieldId);\n\n if (Array.isArray(value) && value.length === 0) {\n if (existingIndex === -1) return;\n onTokensChange(tokens.filter((_, i) => i !== existingIndex));\n return;\n }\n\n if (existingIndex === -1) {\n onTokensChange([...tokens, { fieldId, value }]);\n return;\n }\n\n const nextTokens = [...tokens];\n nextTokens[existingIndex] = { fieldId, value };\n onTokensChange(nextTokens);\n },\n [onTokensChange, tokens],\n );\n\n const commit = useCallback(() => {\n if (!selectedField) {\n setError('Choose a property first.');\n return;\n }\n if (singleUseFieldIds.has(selectedField.id)) {\n setError(`Remove the existing ${selectedField.label} filter before adding another.`);\n return;\n }\n if (multiValue.length === 0) {\n setError(`Choose at least one ${selectedField.label.toLowerCase()} value.`);\n return;\n }\n onTokensChange([...tokens, { fieldId: selectedField.id, value: multiValue }]);\n setOpen(false);\n }, [multiValue, onTokensChange, selectedField, singleUseFieldIds, tokens]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button size={size} disabled={disabled} icon={<ListFilterPlusIcon />}>\n {label}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className={cn('w-64', selectedField ? 'p-3' : 'p-1')}\n initialFocus={false}\n finalFocus={() => {\n if (skipCloseFocusRef.current) {\n skipCloseFocusRef.current = false;\n return false;\n }\n return true;\n }}\n >\n <div className={cn('grid', selectedField && 'gap-3')}>\n {selectedField && (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Back to properties\"\n className={cn(quietTextHover, controlStateColorTransition)}\n onClick={reset}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </button>\n <FilterIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n <Txt as=\"span\" variant=\"caption\" tone=\"muted\">{`${selectedField.label} · is`}</Txt>\n </div>\n )}\n\n {!selectedField && (\n <div\n role=\"menu\"\n className=\"max-h-[80dvh] overflow-auto\"\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const buttons = Array.from(\n e.currentTarget.querySelectorAll<HTMLButtonElement>('[data-filter-item]:not([disabled])'),\n );\n if (buttons.length === 0) return;\n e.preventDefault();\n const active = document.activeElement as HTMLElement | null;\n const current = buttons.findIndex(b => b === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = buttons.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % buttons.length;\n else next = current <= 0 ? buttons.length - 1 : current - 1;\n buttons[next]?.focus();\n }}\n >\n <>\n {visibleFields.length > 0 ? (\n visibleFields.map(f => {\n const used = singleUseFieldIds.has(f.id);\n if (f.kind === 'pick-multi') {\n return (\n <PickMultiMenuItem\n key={f.id}\n field={f}\n tokens={tokens}\n onChange={replacePickMultiToken}\n open={openPickMultiFieldId === f.id}\n onToggle={togglePickMulti}\n onClose={closePickMulti}\n />\n );\n }\n return (\n <FilterMenuButton\n key={f.id}\n className={cn(menuItemButtonClass, 'group')}\n disabled={used}\n onClick={() => {\n setError(undefined);\n if (f.kind === 'text') {\n onTokensChange([...tokens, { fieldId: f.id, value: '' }]);\n onStartTextFilter?.(f.id);\n skipCloseFocusRef.current = true;\n setOpen(false);\n return;\n }\n setFieldId(f.id);\n }}\n >\n <span className=\"truncate\">{f.label}</span>\n {used ? (\n <span className=\"ml-auto text-muted-foreground\">In use</span>\n ) : (\n <span\n className={cn(\n menuItemTrailingIconClass,\n 'text-muted-foreground opacity-0 group-hover:opacity-100 group-focus:opacity-100',\n )}\n >\n <PlusIcon />\n </span>\n )}\n </FilterMenuButton>\n );\n })\n ) : (\n <div className={menuEmptyClass}>No matching property.</div>\n )}\n </>\n </div>\n )}\n\n {selectedField && (\n <Field invalid={Boolean(error)}>\n <Combobox\n multiple\n options={selectedField.options ?? []}\n value={multiValue}\n onValueChange={v => {\n setMultiValue(v);\n setError(undefined);\n }}\n placeholder={selectedField.placeholder ?? `Choose ${selectedField.label}`}\n searchPlaceholder={`Search ${selectedField.label.toLowerCase()}`}\n emptyText={selectedField.emptyText ?? 'No option found.'}\n size=\"md\"\n aria-label={selectedField.label}\n />\n <FieldError>{error}</FieldError>\n </Field>\n )}\n\n {selectedField && (\n <div className=\"flex items-center justify-end gap-2\">\n <Button icon={<X />} variant=\"ghost\" size=\"md\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button icon={<ListFilterPlus />} size=\"md\" onClick={commit}>\n Add filter\n </Button>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\ntype PickMultiField = Extract<PropertyFilterField, { kind: 'pick-multi' }>;\n\ntype PickMultiMenuItemProps = {\n field: PickMultiField;\n tokens: PropertyFilterToken[];\n onChange: (fieldId: string, value: string | string[]) => void;\n open: boolean;\n onToggle: (fieldId: string) => void;\n onClose: () => void;\n};\n\n/**\n * A property-picker menu item that opens a separate Radix popover (portaled to\n * the side) with a radio group (single-select) or checkbox list (multi-select,\n * `field.multi === true`). Open/close is driven by explicit click / keyboard\n * press; the panel only closes when the user clicks outside, presses Escape,\n * or clicks the row again to toggle it off.\n */\nfunction PickMultiMenuItem({ field, tokens, onChange, open, onToggle, onClose }: PickMultiMenuItemProps) {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <Popover\n open={open}\n onOpenChange={next => {\n if (next) onToggle(field.id);\n else onClose();\n }}\n >\n <PopoverTrigger asChild>\n <FilterMenuButton\n className={menuItemButtonClass}\n onKeyDown={e => {\n if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n if (!open) onToggle(field.id);\n e.preventDefault();\n requestAnimationFrame(() => {\n const first = contentRef.current?.querySelector<HTMLElement>(\n 'input, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n first?.focus();\n });\n }}\n >\n {open && <ChevronRightIcon className=\"text-muted-foreground\" />}\n <span className=\"truncate\">{field.label}</span>\n {!open && (\n <span className={cn(menuItemTrailingIconClass, 'text-muted-foreground')}>\n <ChevronRightIcon />\n </span>\n )}\n </FilterMenuButton>\n </PopoverTrigger>\n <PopoverContent\n ref={contentRef}\n side=\"right\"\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className=\"w-64 p-0\"\n initialFocus={false}\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const items = Array.from(\n e.currentTarget.querySelectorAll<HTMLElement>('[data-pick-multi-item]:not([disabled])'),\n );\n if (items.length === 0) return;\n e.preventDefault();\n e.stopPropagation();\n const active = document.activeElement as HTMLElement | null;\n const current = items.findIndex(el => el === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = items.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % items.length;\n else next = current <= 0 ? items.length - 1 : current - 1;\n items[next]?.focus();\n }}\n data-pick-multi-panel\n >\n <PickMultiPanel field={field} tokens={tokens} onChange={onChange} />\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
@@ -6,8 +6,8 @@ import "../primitives/typography.es.js";
6
6
  import { t as Txt } from "../Txt-BM6TVV_c.js";
7
7
  import { Field, FieldError } from "./Field.es.js";
8
8
  import { i as PopoverTrigger, n as Popover, r as PopoverContent } from "../popover-CzHvTPk2.js";
9
- import { t as Combobox } from "../combobox-CtCK0mNx.js";
10
- import { n as PickMultiPanel, r as PropertyFilterActions, t as PropertyFilterApplied } from "../property-filter-applied-p3dTTDdb.js";
9
+ import { t as Combobox } from "../combobox-D21no8t5.js";
10
+ import { n as PickMultiPanel, r as PropertyFilterActions, t as PropertyFilterApplied } from "../property-filter-applied--U5EZdaA.js";
11
11
  import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
12
12
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
13
13
  import { ArrowLeftIcon, ChevronRightIcon, FilterIcon, ListFilterPlus, ListFilterPlusIcon, PlusIcon, X } from "lucide-react";
@@ -232,7 +232,7 @@ function PropertyFilterCreator({ fields, tokens, onTokensChange, label = "Add fi
232
232
  setError(void 0);
233
233
  },
234
234
  placeholder: selectedField.placeholder ?? `Choose ${selectedField.label}`,
235
- searchPlaceholder: `Search ${selectedField.label.toLowerCase()}...`,
235
+ searchPlaceholder: `Search ${selectedField.label.toLowerCase()}`,
236
236
  emptyText: selectedField.emptyText ?? "No option found.",
237
237
  size: "md",
238
238
  "aria-label": selectedField.label
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyFilter.es.js","names":["_Fragment"],"sources":["../../src/ds/components/PropertyFilter/property-filter-creator.tsx"],"sourcesContent":["import {\n ArrowLeftIcon,\n ChevronRightIcon,\n FilterIcon,\n ListFilterPlusIcon,\n PlusIcon,\n ListFilterPlus,\n X,\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { PickMultiPanel } from './pick-multi-panel';\nimport type { PropertyFilterField, PropertyFilterToken } from './types';\nimport { Button } from '@/ds/components/Button/Button';\nimport type { ButtonProps } from '@/ds/components/Button/Button';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport { Field, FieldError } from '@/ds/components/Field';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/ds/components/Popover/popover';\nimport { Txt } from '@/ds/components/Txt';\nimport {\n MENU_SIDE_OFFSET,\n menuEmptyClass,\n menuItemButtonClass,\n menuItemTrailingIconClass,\n} from '@/ds/primitives/menu-item';\nimport { controlStateColorTransition } from '@/ds/primitives/transitions';\nimport { quietTextHover } from '@/ds/primitives/typography';\nimport { cn } from '@/lib/utils';\n\n// Plain <button>s navigated with roving focus (not Base UI).\nconst FilterMenuButton = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>((props, ref) => (\n <button type=\"button\" role=\"menuitem\" data-filter-item=\"\" ref={ref} {...props} />\n));\nFilterMenuButton.displayName = 'FilterMenuButton';\n\nexport type PropertyFilterCreatorProps = {\n fields: PropertyFilterField[];\n tokens: PropertyFilterToken[];\n onTokensChange: (tokens: PropertyFilterToken[]) => void;\n label?: string;\n disabled?: boolean;\n /** Size passed through to the trigger Button. Defaults to 'md'. */\n size?: ButtonProps['size'];\n /**\n * Called when the user picks a text (id-style) field. Consumers are expected\n * to render a pending applied-filter pill with an active input so the user\n * can type the value inline instead of in this popover.\n */\n onStartTextFilter?: (fieldId: string) => void;\n /**\n * Field ids hidden from the Add Filter dropdown. Use to prevent users from\n * recreating a filter that an upstream context already owns (e.g. the agent\n * id when viewing the agent-scoped traces tab).\n */\n hiddenFieldIds?: readonly string[];\n};\n\n/**\n * Minimal Linear-style filter creator: a `+ Filter` button whose popover walks\n * the user through property → value → commit. For id-style text fields, the\n * picker closes immediately and the applied-filter pill owns the input. For\n * `pick-multi` fields (e.g. Root Entity Name) hovering the item opens a\n * separate side popover with checkboxes — each check adds its own applied\n * filter and the main popover stays open so users can pick many.\n */\nexport function PropertyFilterCreator({\n fields,\n tokens,\n onTokensChange,\n label = 'Add filter',\n disabled,\n size,\n onStartTextFilter,\n hiddenFieldIds,\n}: PropertyFilterCreatorProps) {\n const visibleFields = useMemo(() => {\n if (!hiddenFieldIds || hiddenFieldIds.length === 0) return fields;\n const hidden = new Set(hiddenFieldIds);\n return fields.filter(f => !hidden.has(f.id));\n }, [fields, hiddenFieldIds]);\n const [open, setOpen] = useState(false);\n const [fieldId, setFieldId] = useState<string | undefined>();\n const [multiValue, setMultiValue] = useState<string[]>([]);\n const [error, setError] = useState<string | undefined>();\n // Single source of truth for which pick-multi side panel is open. Opens only\n // via explicit click/keyboard press on the menu item — no hover/focus\n // auto-open (was too flicker-prone).\n const [openPickMultiFieldId, setOpenPickMultiFieldId] = useState<string | undefined>();\n\n // When the user picks a text field we close this popover and hand off focus\n // to the newly-created pill's input — prevent Radix from returning focus to\n // the trigger button in that case.\n const skipCloseFocusRef = useRef(false);\n\n const togglePickMulti = useCallback((id: string) => {\n setOpenPickMultiFieldId(current => (current === id ? undefined : id));\n }, []);\n const closePickMulti = useCallback(() => setOpenPickMultiFieldId(undefined), []);\n\n useEffect(() => {\n if (!open) setOpenPickMultiFieldId(undefined);\n }, [open]);\n\n const selectedField = useMemo(() => visibleFields.find(f => f.id === fieldId), [visibleFields, fieldId]);\n // Only single-use kinds (text, multi-select) count as \"used\". `pick-multi`\n // allows multiple tokens with the same fieldId.\n const singleUseFieldIds = useMemo(() => {\n const ids = new Set<string>();\n for (const token of tokens) {\n const field = fields.find(f => f.id === token.fieldId);\n if (field && field.kind !== 'pick-multi') ids.add(token.fieldId);\n }\n return ids;\n }, [tokens, fields]);\n\n const reset = useCallback(() => {\n setFieldId(undefined);\n setMultiValue([]);\n setError(undefined);\n }, []);\n\n useEffect(() => {\n if (!open) reset();\n }, [open, reset]);\n\n /**\n * Replace whatever token exists for `fieldId` with the given value. Used by\n * both single-select (radio) and multi-select (checkbox) pick-multi panels.\n * An empty list means nothing is selected, which removes the token here —\n * unlike the applied pill, where the filter stays on in a neutral state.\n */\n const replacePickMultiToken = useCallback(\n (fieldId: string, value: string | string[]) => {\n const existingIndex = tokens.findIndex(t => t.fieldId === fieldId);\n\n if (Array.isArray(value) && value.length === 0) {\n if (existingIndex === -1) return;\n onTokensChange(tokens.filter((_, i) => i !== existingIndex));\n return;\n }\n\n if (existingIndex === -1) {\n onTokensChange([...tokens, { fieldId, value }]);\n return;\n }\n\n const nextTokens = [...tokens];\n nextTokens[existingIndex] = { fieldId, value };\n onTokensChange(nextTokens);\n },\n [onTokensChange, tokens],\n );\n\n const commit = useCallback(() => {\n if (!selectedField) {\n setError('Choose a property first.');\n return;\n }\n if (singleUseFieldIds.has(selectedField.id)) {\n setError(`Remove the existing ${selectedField.label} filter before adding another.`);\n return;\n }\n if (multiValue.length === 0) {\n setError(`Choose at least one ${selectedField.label.toLowerCase()} value.`);\n return;\n }\n onTokensChange([...tokens, { fieldId: selectedField.id, value: multiValue }]);\n setOpen(false);\n }, [multiValue, onTokensChange, selectedField, singleUseFieldIds, tokens]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button size={size} disabled={disabled} icon={<ListFilterPlusIcon />}>\n {label}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className={cn('w-64', selectedField ? 'p-3' : 'p-1')}\n initialFocus={false}\n finalFocus={() => {\n if (skipCloseFocusRef.current) {\n skipCloseFocusRef.current = false;\n return false;\n }\n return true;\n }}\n >\n <div className={cn('grid', selectedField && 'gap-3')}>\n {selectedField && (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Back to properties\"\n className={cn(quietTextHover, controlStateColorTransition)}\n onClick={reset}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </button>\n <FilterIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n <Txt as=\"span\" variant=\"caption\" tone=\"muted\">{`${selectedField.label} · is`}</Txt>\n </div>\n )}\n\n {!selectedField && (\n <div\n role=\"menu\"\n className=\"max-h-[80dvh] overflow-auto\"\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const buttons = Array.from(\n e.currentTarget.querySelectorAll<HTMLButtonElement>('[data-filter-item]:not([disabled])'),\n );\n if (buttons.length === 0) return;\n e.preventDefault();\n const active = document.activeElement as HTMLElement | null;\n const current = buttons.findIndex(b => b === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = buttons.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % buttons.length;\n else next = current <= 0 ? buttons.length - 1 : current - 1;\n buttons[next]?.focus();\n }}\n >\n <>\n {visibleFields.length > 0 ? (\n visibleFields.map(f => {\n const used = singleUseFieldIds.has(f.id);\n if (f.kind === 'pick-multi') {\n return (\n <PickMultiMenuItem\n key={f.id}\n field={f}\n tokens={tokens}\n onChange={replacePickMultiToken}\n open={openPickMultiFieldId === f.id}\n onToggle={togglePickMulti}\n onClose={closePickMulti}\n />\n );\n }\n return (\n <FilterMenuButton\n key={f.id}\n className={cn(menuItemButtonClass, 'group')}\n disabled={used}\n onClick={() => {\n setError(undefined);\n if (f.kind === 'text') {\n onTokensChange([...tokens, { fieldId: f.id, value: '' }]);\n onStartTextFilter?.(f.id);\n skipCloseFocusRef.current = true;\n setOpen(false);\n return;\n }\n setFieldId(f.id);\n }}\n >\n <span className=\"truncate\">{f.label}</span>\n {used ? (\n <span className=\"ml-auto text-muted-foreground\">In use</span>\n ) : (\n <span\n className={cn(\n menuItemTrailingIconClass,\n 'text-muted-foreground opacity-0 group-hover:opacity-100 group-focus:opacity-100',\n )}\n >\n <PlusIcon />\n </span>\n )}\n </FilterMenuButton>\n );\n })\n ) : (\n <div className={menuEmptyClass}>No matching property.</div>\n )}\n </>\n </div>\n )}\n\n {selectedField && (\n <Field invalid={Boolean(error)}>\n <Combobox\n multiple\n options={selectedField.options ?? []}\n value={multiValue}\n onValueChange={v => {\n setMultiValue(v);\n setError(undefined);\n }}\n placeholder={selectedField.placeholder ?? `Choose ${selectedField.label}`}\n searchPlaceholder={`Search ${selectedField.label.toLowerCase()}...`}\n emptyText={selectedField.emptyText ?? 'No option found.'}\n size=\"md\"\n aria-label={selectedField.label}\n />\n <FieldError>{error}</FieldError>\n </Field>\n )}\n\n {selectedField && (\n <div className=\"flex items-center justify-end gap-2\">\n <Button icon={<X />} variant=\"ghost\" size=\"md\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button icon={<ListFilterPlus />} size=\"md\" onClick={commit}>\n Add filter\n </Button>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\ntype PickMultiField = Extract<PropertyFilterField, { kind: 'pick-multi' }>;\n\ntype PickMultiMenuItemProps = {\n field: PickMultiField;\n tokens: PropertyFilterToken[];\n onChange: (fieldId: string, value: string | string[]) => void;\n open: boolean;\n onToggle: (fieldId: string) => void;\n onClose: () => void;\n};\n\n/**\n * A property-picker menu item that opens a separate Radix popover (portaled to\n * the side) with a radio group (single-select) or checkbox list (multi-select,\n * `field.multi === true`). Open/close is driven by explicit click / keyboard\n * press; the panel only closes when the user clicks outside, presses Escape,\n * or clicks the row again to toggle it off.\n */\nfunction PickMultiMenuItem({ field, tokens, onChange, open, onToggle, onClose }: PickMultiMenuItemProps) {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <Popover\n open={open}\n onOpenChange={next => {\n if (next) onToggle(field.id);\n else onClose();\n }}\n >\n <PopoverTrigger asChild>\n <FilterMenuButton\n className={menuItemButtonClass}\n onKeyDown={e => {\n if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n if (!open) onToggle(field.id);\n e.preventDefault();\n requestAnimationFrame(() => {\n const first = contentRef.current?.querySelector<HTMLElement>(\n 'input, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n first?.focus();\n });\n }}\n >\n {open && <ChevronRightIcon className=\"text-muted-foreground\" />}\n <span className=\"truncate\">{field.label}</span>\n {!open && (\n <span className={cn(menuItemTrailingIconClass, 'text-muted-foreground')}>\n <ChevronRightIcon />\n </span>\n )}\n </FilterMenuButton>\n </PopoverTrigger>\n <PopoverContent\n ref={contentRef}\n side=\"right\"\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className=\"w-64 p-0\"\n initialFocus={false}\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const items = Array.from(\n e.currentTarget.querySelectorAll<HTMLElement>('[data-pick-multi-item]:not([disabled])'),\n );\n if (items.length === 0) return;\n e.preventDefault();\n e.stopPropagation();\n const active = document.activeElement as HTMLElement | null;\n const current = items.findIndex(el => el === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = items.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % items.length;\n else next = current <= 0 ? items.length - 1 : current - 1;\n items[next]?.focus();\n }}\n data-pick-multi-panel\n >\n <PickMultiPanel field={field} tokens={tokens} onChange={onChange} />\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PropertyFilter.es.js","names":["_Fragment"],"sources":["../../src/ds/components/PropertyFilter/property-filter-creator.tsx"],"sourcesContent":["import {\n ArrowLeftIcon,\n ChevronRightIcon,\n FilterIcon,\n ListFilterPlusIcon,\n PlusIcon,\n ListFilterPlus,\n X,\n} from 'lucide-react';\nimport { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { PickMultiPanel } from './pick-multi-panel';\nimport type { PropertyFilterField, PropertyFilterToken } from './types';\nimport { Button } from '@/ds/components/Button/Button';\nimport type { ButtonProps } from '@/ds/components/Button/Button';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport { Field, FieldError } from '@/ds/components/Field';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/ds/components/Popover/popover';\nimport { Txt } from '@/ds/components/Txt';\nimport {\n MENU_SIDE_OFFSET,\n menuEmptyClass,\n menuItemButtonClass,\n menuItemTrailingIconClass,\n} from '@/ds/primitives/menu-item';\nimport { controlStateColorTransition } from '@/ds/primitives/transitions';\nimport { quietTextHover } from '@/ds/primitives/typography';\nimport { cn } from '@/lib/utils';\n\n// Plain <button>s navigated with roving focus (not Base UI).\nconst FilterMenuButton = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>((props, ref) => (\n <button type=\"button\" role=\"menuitem\" data-filter-item=\"\" ref={ref} {...props} />\n));\nFilterMenuButton.displayName = 'FilterMenuButton';\n\nexport type PropertyFilterCreatorProps = {\n fields: PropertyFilterField[];\n tokens: PropertyFilterToken[];\n onTokensChange: (tokens: PropertyFilterToken[]) => void;\n label?: string;\n disabled?: boolean;\n /** Size passed through to the trigger Button. Defaults to 'md'. */\n size?: ButtonProps['size'];\n /**\n * Called when the user picks a text (id-style) field. Consumers are expected\n * to render a pending applied-filter pill with an active input so the user\n * can type the value inline instead of in this popover.\n */\n onStartTextFilter?: (fieldId: string) => void;\n /**\n * Field ids hidden from the Add Filter dropdown. Use to prevent users from\n * recreating a filter that an upstream context already owns (e.g. the agent\n * id when viewing the agent-scoped traces tab).\n */\n hiddenFieldIds?: readonly string[];\n};\n\n/**\n * Minimal Linear-style filter creator: a `+ Filter` button whose popover walks\n * the user through property → value → commit. For id-style text fields, the\n * picker closes immediately and the applied-filter pill owns the input. For\n * `pick-multi` fields (e.g. Root Entity Name) hovering the item opens a\n * separate side popover with checkboxes — each check adds its own applied\n * filter and the main popover stays open so users can pick many.\n */\nexport function PropertyFilterCreator({\n fields,\n tokens,\n onTokensChange,\n label = 'Add filter',\n disabled,\n size,\n onStartTextFilter,\n hiddenFieldIds,\n}: PropertyFilterCreatorProps) {\n const visibleFields = useMemo(() => {\n if (!hiddenFieldIds || hiddenFieldIds.length === 0) return fields;\n const hidden = new Set(hiddenFieldIds);\n return fields.filter(f => !hidden.has(f.id));\n }, [fields, hiddenFieldIds]);\n const [open, setOpen] = useState(false);\n const [fieldId, setFieldId] = useState<string | undefined>();\n const [multiValue, setMultiValue] = useState<string[]>([]);\n const [error, setError] = useState<string | undefined>();\n // Single source of truth for which pick-multi side panel is open. Opens only\n // via explicit click/keyboard press on the menu item — no hover/focus\n // auto-open (was too flicker-prone).\n const [openPickMultiFieldId, setOpenPickMultiFieldId] = useState<string | undefined>();\n\n // When the user picks a text field we close this popover and hand off focus\n // to the newly-created pill's input — prevent Radix from returning focus to\n // the trigger button in that case.\n const skipCloseFocusRef = useRef(false);\n\n const togglePickMulti = useCallback((id: string) => {\n setOpenPickMultiFieldId(current => (current === id ? undefined : id));\n }, []);\n const closePickMulti = useCallback(() => setOpenPickMultiFieldId(undefined), []);\n\n useEffect(() => {\n if (!open) setOpenPickMultiFieldId(undefined);\n }, [open]);\n\n const selectedField = useMemo(() => visibleFields.find(f => f.id === fieldId), [visibleFields, fieldId]);\n // Only single-use kinds (text, multi-select) count as \"used\". `pick-multi`\n // allows multiple tokens with the same fieldId.\n const singleUseFieldIds = useMemo(() => {\n const ids = new Set<string>();\n for (const token of tokens) {\n const field = fields.find(f => f.id === token.fieldId);\n if (field && field.kind !== 'pick-multi') ids.add(token.fieldId);\n }\n return ids;\n }, [tokens, fields]);\n\n const reset = useCallback(() => {\n setFieldId(undefined);\n setMultiValue([]);\n setError(undefined);\n }, []);\n\n useEffect(() => {\n if (!open) reset();\n }, [open, reset]);\n\n /**\n * Replace whatever token exists for `fieldId` with the given value. Used by\n * both single-select (radio) and multi-select (checkbox) pick-multi panels.\n * An empty list means nothing is selected, which removes the token here —\n * unlike the applied pill, where the filter stays on in a neutral state.\n */\n const replacePickMultiToken = useCallback(\n (fieldId: string, value: string | string[]) => {\n const existingIndex = tokens.findIndex(t => t.fieldId === fieldId);\n\n if (Array.isArray(value) && value.length === 0) {\n if (existingIndex === -1) return;\n onTokensChange(tokens.filter((_, i) => i !== existingIndex));\n return;\n }\n\n if (existingIndex === -1) {\n onTokensChange([...tokens, { fieldId, value }]);\n return;\n }\n\n const nextTokens = [...tokens];\n nextTokens[existingIndex] = { fieldId, value };\n onTokensChange(nextTokens);\n },\n [onTokensChange, tokens],\n );\n\n const commit = useCallback(() => {\n if (!selectedField) {\n setError('Choose a property first.');\n return;\n }\n if (singleUseFieldIds.has(selectedField.id)) {\n setError(`Remove the existing ${selectedField.label} filter before adding another.`);\n return;\n }\n if (multiValue.length === 0) {\n setError(`Choose at least one ${selectedField.label.toLowerCase()} value.`);\n return;\n }\n onTokensChange([...tokens, { fieldId: selectedField.id, value: multiValue }]);\n setOpen(false);\n }, [multiValue, onTokensChange, selectedField, singleUseFieldIds, tokens]);\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <Button size={size} disabled={disabled} icon={<ListFilterPlusIcon />}>\n {label}\n </Button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className={cn('w-64', selectedField ? 'p-3' : 'p-1')}\n initialFocus={false}\n finalFocus={() => {\n if (skipCloseFocusRef.current) {\n skipCloseFocusRef.current = false;\n return false;\n }\n return true;\n }}\n >\n <div className={cn('grid', selectedField && 'gap-3')}>\n {selectedField && (\n <div className=\"flex items-center gap-2\">\n <button\n type=\"button\"\n aria-label=\"Back to properties\"\n className={cn(quietTextHover, controlStateColorTransition)}\n onClick={reset}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </button>\n <FilterIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n <Txt as=\"span\" variant=\"caption\" tone=\"muted\">{`${selectedField.label} · is`}</Txt>\n </div>\n )}\n\n {!selectedField && (\n <div\n role=\"menu\"\n className=\"max-h-[80dvh] overflow-auto\"\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const buttons = Array.from(\n e.currentTarget.querySelectorAll<HTMLButtonElement>('[data-filter-item]:not([disabled])'),\n );\n if (buttons.length === 0) return;\n e.preventDefault();\n const active = document.activeElement as HTMLElement | null;\n const current = buttons.findIndex(b => b === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = buttons.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % buttons.length;\n else next = current <= 0 ? buttons.length - 1 : current - 1;\n buttons[next]?.focus();\n }}\n >\n <>\n {visibleFields.length > 0 ? (\n visibleFields.map(f => {\n const used = singleUseFieldIds.has(f.id);\n if (f.kind === 'pick-multi') {\n return (\n <PickMultiMenuItem\n key={f.id}\n field={f}\n tokens={tokens}\n onChange={replacePickMultiToken}\n open={openPickMultiFieldId === f.id}\n onToggle={togglePickMulti}\n onClose={closePickMulti}\n />\n );\n }\n return (\n <FilterMenuButton\n key={f.id}\n className={cn(menuItemButtonClass, 'group')}\n disabled={used}\n onClick={() => {\n setError(undefined);\n if (f.kind === 'text') {\n onTokensChange([...tokens, { fieldId: f.id, value: '' }]);\n onStartTextFilter?.(f.id);\n skipCloseFocusRef.current = true;\n setOpen(false);\n return;\n }\n setFieldId(f.id);\n }}\n >\n <span className=\"truncate\">{f.label}</span>\n {used ? (\n <span className=\"ml-auto text-muted-foreground\">In use</span>\n ) : (\n <span\n className={cn(\n menuItemTrailingIconClass,\n 'text-muted-foreground opacity-0 group-hover:opacity-100 group-focus:opacity-100',\n )}\n >\n <PlusIcon />\n </span>\n )}\n </FilterMenuButton>\n );\n })\n ) : (\n <div className={menuEmptyClass}>No matching property.</div>\n )}\n </>\n </div>\n )}\n\n {selectedField && (\n <Field invalid={Boolean(error)}>\n <Combobox\n multiple\n options={selectedField.options ?? []}\n value={multiValue}\n onValueChange={v => {\n setMultiValue(v);\n setError(undefined);\n }}\n placeholder={selectedField.placeholder ?? `Choose ${selectedField.label}`}\n searchPlaceholder={`Search ${selectedField.label.toLowerCase()}`}\n emptyText={selectedField.emptyText ?? 'No option found.'}\n size=\"md\"\n aria-label={selectedField.label}\n />\n <FieldError>{error}</FieldError>\n </Field>\n )}\n\n {selectedField && (\n <div className=\"flex items-center justify-end gap-2\">\n <Button icon={<X />} variant=\"ghost\" size=\"md\" onClick={() => setOpen(false)}>\n Cancel\n </Button>\n <Button icon={<ListFilterPlus />} size=\"md\" onClick={commit}>\n Add filter\n </Button>\n </div>\n )}\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n\ntype PickMultiField = Extract<PropertyFilterField, { kind: 'pick-multi' }>;\n\ntype PickMultiMenuItemProps = {\n field: PickMultiField;\n tokens: PropertyFilterToken[];\n onChange: (fieldId: string, value: string | string[]) => void;\n open: boolean;\n onToggle: (fieldId: string) => void;\n onClose: () => void;\n};\n\n/**\n * A property-picker menu item that opens a separate Radix popover (portaled to\n * the side) with a radio group (single-select) or checkbox list (multi-select,\n * `field.multi === true`). Open/close is driven by explicit click / keyboard\n * press; the panel only closes when the user clicks outside, presses Escape,\n * or clicks the row again to toggle it off.\n */\nfunction PickMultiMenuItem({ field, tokens, onChange, open, onToggle, onClose }: PickMultiMenuItemProps) {\n const contentRef = useRef<HTMLDivElement>(null);\n\n return (\n <Popover\n open={open}\n onOpenChange={next => {\n if (next) onToggle(field.id);\n else onClose();\n }}\n >\n <PopoverTrigger asChild>\n <FilterMenuButton\n className={menuItemButtonClass}\n onKeyDown={e => {\n if (e.key !== 'ArrowRight' && e.key !== 'ArrowLeft') return;\n if (!open) onToggle(field.id);\n e.preventDefault();\n requestAnimationFrame(() => {\n const first = contentRef.current?.querySelector<HTMLElement>(\n 'input, button, [tabindex]:not([tabindex=\"-1\"])',\n );\n first?.focus();\n });\n }}\n >\n {open && <ChevronRightIcon className=\"text-muted-foreground\" />}\n <span className=\"truncate\">{field.label}</span>\n {!open && (\n <span className={cn(menuItemTrailingIconClass, 'text-muted-foreground')}>\n <ChevronRightIcon />\n </span>\n )}\n </FilterMenuButton>\n </PopoverTrigger>\n <PopoverContent\n ref={contentRef}\n side=\"right\"\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n className=\"w-64 p-0\"\n initialFocus={false}\n onKeyDown={e => {\n if (e.key !== 'ArrowDown' && e.key !== 'ArrowUp' && e.key !== 'Home' && e.key !== 'End') return;\n const items = Array.from(\n e.currentTarget.querySelectorAll<HTMLElement>('[data-pick-multi-item]:not([disabled])'),\n );\n if (items.length === 0) return;\n e.preventDefault();\n e.stopPropagation();\n const active = document.activeElement as HTMLElement | null;\n const current = items.findIndex(el => el === active);\n let next: number;\n if (e.key === 'Home') next = 0;\n else if (e.key === 'End') next = items.length - 1;\n else if (e.key === 'ArrowDown') next = current < 0 ? 0 : (current + 1) % items.length;\n else next = current <= 0 ? items.length - 1 : current - 1;\n items[next]?.focus();\n }}\n data-pick-multi-panel\n >\n <PickMultiPanel field={field} tokens={tokens} onChange={onChange} />\n </PopoverContent>\n </Popover>\n );\n}\n"],"mappings":"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"}
@@ -9,7 +9,7 @@ const require_primitives_password_manager_autofill = require("../primitives/pass
9
9
  const require_dropdown_menu = require("../dropdown-menu-BETTTPBB.cjs");
10
10
  const require_context_menu = require("../context-menu-DTFPCyae.cjs");
11
11
  const require_saved_view_schema = require("../saved-view-schema-DRJYELfK.cjs");
12
- const require_filter_bar_chip = require("../filter-bar-chip-CIEsWcEw.cjs");
12
+ const require_filter_bar_chip = require("../filter-bar-chip-Cg-UbIwP.cjs");
13
13
  const require_components_HoverCard = require("./HoverCard.cjs.js");
14
14
  let react = require("react");
15
15
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -8,7 +8,7 @@ import { passwordManagerOptOutProps } from "../primitives/password-manager-autof
8
8
  import { t as DropdownMenu } from "../dropdown-menu-B4jY3J9e.js";
9
9
  import { t as ContextMenu } from "../context-menu-Dv0NU0oM.js";
10
10
  import { n as savedViewNameSchema, r as serializeSavedViews, t as parseSavedViews } from "../saved-view-schema-eJXlRRel.js";
11
- import { o as FilterBarFieldLabel, u as formatValue } from "../filter-bar-chip-B4sV4gDm.js";
11
+ import { o as FilterBarFieldLabel, u as formatValue } from "../filter-bar-chip-CABeKrtf.js";
12
12
  import { HoverCard, HoverCardContent, HoverCardTrigger } from "./HoverCard.es.js";
13
13
  import { VisuallyHidden } from "../primitives/visually-hidden.es.js";
14
14
  import { Fragment, useRef, useState, useSyncExternalStore } from "react";
@@ -202,7 +202,7 @@ var SidebarMeter = (0, react.forwardRef)(function SidebarMeter({ label, value, s
202
202
  "data-slot": "sidebar-meter",
203
203
  "data-tone": tone,
204
204
  "data-state": state,
205
- className: require_utils.cn("relative isolate flex flex-col justify-center overflow-hidden rounded-lg border border-border bg-background px-3", href && "state-layer", className),
205
+ className: require_utils.cn("relative isolate flex flex-col justify-center overflow-hidden rounded-lg border border-border bg-background px-3", href && require_utils.cn("state-layer", "before:transition-none"), className),
206
206
  style: { height: CARD_HEIGHT },
207
207
  ...props,
208
208
  children: [
@@ -342,10 +342,10 @@ function SidebarHeader({ className, children, collapsedLogo, actions, ...props }
342
342
  children: [collapsed && collapsedLogo ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
343
343
  className: "group/collapsed-logo relative ml-0.5 grid size-9 shrink-0 place-items-center",
344
344
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
345
- className: require_utils.cn(hold, "grid place-items-center transition-opacity duration-normal [--sidebar-hold-opacity:1] group-focus-within/collapsed-logo:opacity-0 group-hover/sidebar:opacity-0 motion-reduce:transition-none"),
345
+ className: require_utils.cn(hold, "grid place-items-center [--sidebar-hold-opacity:1] group-focus-within/collapsed-logo:opacity-0 group-hover/sidebar:opacity-0"),
346
346
  children: collapsedLogo
347
347
  }), isMobile ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
348
- className: require_utils.cn(hold, "absolute inset-0 grid place-items-center opacity-0 transition-opacity duration-normal [--sidebar-hold-opacity:0] group-hover/sidebar:opacity-100 focus-within:opacity-100 motion-reduce:transition-none"),
348
+ className: require_utils.cn(hold, "absolute inset-0 grid place-items-center opacity-0 [--sidebar-hold-opacity:0] group-hover/sidebar:opacity-100 focus-within:opacity-100"),
349
349
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarTrigger, {})
350
350
  })]
351
351
  }) : children, actions]
@@ -411,7 +411,7 @@ function SidebarNavHeader({ children, icon, action, className, state: stateProp,
411
411
  className: require_utils.cn("max-w-full min-w-0 flex-1 truncate text-column", icon ? "pl-2" : "pl-3", toneClassName),
412
412
  children: href ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Link, {
413
413
  href,
414
- className: require_utils.cn("block min-w-0 truncate transition-colors duration-normal", {
414
+ className: require_utils.cn("block min-w-0 truncate", {
415
415
  "hover:text-foreground": !isActive,
416
416
  "text-foreground": isActive
417
417
  }),
@@ -471,11 +471,11 @@ var nestedExpandedItemClasses = (level) => {
471
471
  if (level === 2) return `gap-2 py-1 pr-3 pl-10 ${require_primitives_control_size.controlHeight.md}`;
472
472
  return `gap-2 py-1 pr-3 pl-12 ${require_primitives_control_size.controlHeight.md}`;
473
473
  };
474
- var idleSurface = require_utils.cn("rounded-lg text-muted-foreground hover:text-foreground", require_primitives_raised_surface.surfaceStateLayerStyle);
474
+ var idleSurface = require_utils.cn("rounded-lg text-muted-foreground transition-none before:transition-none hover:text-foreground", require_primitives_raised_surface.surfaceStateLayerStyle);
475
475
  var activeSurface = "bg-fill text-foreground";
476
476
  var featuredSurface = require_utils.cn("my-2 border border-transparent bg-brand-green text-black hover:text-black hover:brightness-95");
477
477
  var navRowSurfaceClasses = ({ isActive, isFeatured }) => require_utils.cn(idleSurface, isActive && activeSurface, isFeatured && featuredSurface);
478
- var navItemLayoutClasses = ({ isCollapsed, level = 0, size }) => require_utils.cn(navItemVariants({ size }), "w-full justify-start", require_primitives_transitions.controlStateColorTransition, "[&_svg]:size-4 [&_svg]:shrink-0", require_primitives_transitions.focusRing, !isCollapsed && nestedExpandedItemClasses(level), isCollapsed && "gap-0 px-[13.5px] py-0");
478
+ var navItemLayoutClasses = ({ isCollapsed, level = 0, size }) => require_utils.cn(navItemVariants({ size }), "w-full justify-start", "[&_svg]:size-4 [&_svg]:shrink-0", require_primitives_transitions.focusRing, !isCollapsed && nestedExpandedItemClasses(level), isCollapsed && "gap-0 px-[13.5px] py-0");
479
479
  var navItemClasses = ({ isActive, isCollapsed, isFeatured, level, size } = {}) => require_utils.cn(navItemLayoutClasses({
480
480
  isCollapsed,
481
481
  level,
@@ -625,7 +625,7 @@ function SidebarNavShowMore({ foldedCount, expanded, onExpandedChange, state: st
625
625
  className: require_utils.cn(require_primitives_text.textStyle({
626
626
  variant: "caption",
627
627
  tone: "muted"
628
- }), "self-start rounded-md pl-3 text-left hover:text-foreground", require_primitives_transitions.controlStateColorTransition, require_primitives_transitions.focusRing, className),
628
+ }), "self-start rounded-md pl-3 text-left hover:text-foreground", require_primitives_transitions.focusRing, className),
629
629
  ...props,
630
630
  children: expanded ? "Show less" : `Show ${foldedCount} more`
631
631
  });
@@ -1177,7 +1177,7 @@ function SidebarPanel({ children, className, mobileMode = "drawer" }) {
1177
1177
  onClick,
1178
1178
  onKeyDown,
1179
1179
  className: require_utils.cn("group absolute top-0 -right-1 z-10 h-full w-2 cursor-col-resize touch-none", "flex items-center justify-center", "focus-visible:outline-hidden"),
1180
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_primitives_resize_handle_indicator.ResizeHandleIndicator, { className: require_utils.cn("via-foreground/30 group-hover:opacity-100", "group-focus-visible:via-border-focus group-focus-visible:opacity-100", "in-data-[sidebar-gesture=active]:via-foreground/45 in-data-[sidebar-gesture=active]:opacity-100") })
1180
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_primitives_resize_handle_indicator.ResizeHandleIndicator, { className: require_utils.cn("via-foreground/30 transition-none group-hover:opacity-100", "group-focus-visible:via-border-focus group-focus-visible:opacity-100", "in-data-[sidebar-gesture=active]:via-foreground/45 in-data-[sidebar-gesture=active]:opacity-100") })
1181
1181
  })]
1182
1182
  });
1183
1183
  }