@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
package/dist/style.css CHANGED
@@ -8390,6 +8390,14 @@
8390
8390
  --tw-enter-translate-y: calc(2*var(--spacing)*-1);
8391
8391
  }
8392
8392
 
8393
+ :is(.\*\:col-start-1 > *) {
8394
+ grid-column-start: 1;
8395
+ }
8396
+
8397
+ :is(.\*\:row-start-1 > *) {
8398
+ grid-row-start: 1;
8399
+ }
8400
+
8393
8401
  :is(.\*\:inline-flex > *) {
8394
8402
  display: inline-flex;
8395
8403
  }
@@ -9344,6 +9352,11 @@
9344
9352
  transition-duration: var(--tw-duration, var(--default-transition-duration));
9345
9353
  }
9346
9354
 
9355
+ .before\:transition-none:before {
9356
+ content: var(--tw-content);
9357
+ transition-property: none;
9358
+ }
9359
+
9347
9360
  .before\:duration-fast:before {
9348
9361
  content: var(--tw-content);
9349
9362
  transition-duration: var(--duration-fast);
@@ -15016,7 +15029,7 @@ html.light {
15016
15029
  --muted-foreground: var(--gray-8);
15017
15030
  --placeholder: var(--gray-7);
15018
15031
  --control-icon-rest: var(--muted-foreground);
15019
- --control-icon-hover: var(--foreground);
15032
+ --control-icon-hover: var(--muted-foreground);
15020
15033
  }
15021
15034
 
15022
15035
  .thread-viewport > [data-radix-scroll-area-content] {
@@ -4,7 +4,7 @@ const require_Txt = require("./Txt-BnoSqxKE.cjs");
4
4
  const require_tabs_tab = require("./tabs-tab-DGwfHVDr.cjs");
5
5
  const require_tabs_content = require("./tabs-content-CmXe5ML0.cjs");
6
6
  const require_data_list = require("./data-list-C4Vmq5HA.cjs");
7
- const require_combobox = require("./combobox-CMx2ayFN.cjs");
7
+ const require_combobox = require("./combobox-DIT_6xiG.cjs");
8
8
  const require_list_search = require("./list-search-BtRno5As.cjs");
9
9
  let react = require("react");
10
10
  let react_jsx_runtime = require("react/jsx-runtime");
@@ -127,4 +127,4 @@ Object.defineProperty(exports, "TabbedContainer", {
127
127
  }
128
128
  });
129
129
 
130
- //# sourceMappingURL=tabbed-container-DQU7pVio.cjs.map
130
+ //# sourceMappingURL=tabbed-container-B4lCBgRP.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabbed-container-DQU7pVio.cjs","names":["TabContent","cn","DataList","useContext","TabsContext","ListSearch","TooltipProvider","Tooltip","TooltipTrigger","ListFilterIcon","Txt","Combobox","TooltipContent","isValidElement","Children","Tabs","TabList","Tab"],"sources":["../src/ds/layout/tabbed-container/tabbed-container-root.tsx","../src/ds/layout/tabbed-container/index.ts"],"sourcesContent":["import { ListFilterIcon } from 'lucide-react';\nimport { Children, isValidElement, useContext } from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport './tabbed-container.css';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport type { ComboboxProps } from '@/ds/components/Combobox/combobox';\nimport { DataList } from '@/ds/components/DataList/data-list';\nimport type { DataListFit } from '@/ds/components/DataList/data-list-root';\nimport { ListSearch } from '@/ds/components/ListSearch/list-search';\nimport type { ListSearchProps } from '@/ds/components/ListSearch/list-search';\nimport { TabContent } from '@/ds/components/Tabs/tabs-content';\nimport { TabsContext } from '@/ds/components/Tabs/tabs-context';\nimport { TabList } from '@/ds/components/Tabs/tabs-list';\nimport { Tabs } from '@/ds/components/Tabs/tabs-root';\nimport type { TabsRootProps } from '@/ds/components/Tabs/tabs-root';\nimport { Tab } from '@/ds/components/Tabs/tabs-tab';\nimport type { TabProps } from '@/ds/components/Tabs/tabs-tab';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/ds/components/Tooltip/tooltip';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/lib/utils';\n\nexport type TabbedContainerSearchProps = Pick<\n ListSearchProps,\n 'debounceMs' | 'label' | 'onSearch' | 'placeholder' | 'value'\n>;\n\nexport type TabbedContainerFilterProps = ComboboxProps & { 'aria-label': string };\n\ntype TabbedContainerItemProps = Pick<\n TabProps,\n 'attention' | 'disabled' | 'disabledTooltip' | 'onClick' | 'onClose' | 'value'\n> & {\n label: ReactNode;\n children: ReactNode;\n className?: string;\n tabClassName?: string;\n};\n\nexport type TabbedContainerPanelProps = TabbedContainerItemProps;\n\nexport type TabbedContainerDataListProps = TabbedContainerItemProps & {\n columns: string;\n search?: TabbedContainerSearchProps;\n filter?: TabbedContainerFilterProps;\n fit?: DataListFit;\n};\n\nexport const TabbedContainerPanel = ({ value, children, className }: TabbedContainerPanelProps) => (\n <TabContent value={value} keepMounted className={cn('min-h-0 flex-1', className)}>\n {children}\n </TabContent>\n);\n\nexport const TabbedContainerDataList = ({ value, columns, fit, children, className }: TabbedContainerDataListProps) => (\n <TabContent value={value} keepMounted className={cn('tabbed-container-data-list min-h-0 flex-1', className)}>\n <DataList columns={columns} fit={fit} variant=\"light\" className=\"min-h-0 px-0 pb-0\">\n {children}\n </DataList>\n </TabContent>\n);\n\nexport const DataListControls = ({ dataLists }: { dataLists: ReactElement<TabbedContainerDataListProps>[] }) => {\n const tabs = useContext(TabsContext);\n return dataLists.map(dataList => {\n const { filter, search, value } = dataList.props;\n if (!search && !filter) return null;\n const active = value === tabs?.value;\n const filterCount = filter ? (Array.isArray(filter.value) ? filter.value.length : filter.value ? 1 : 0) : 0;\n return (\n <div key={value} data-slot=\"tabbed-container-controls\" data-active={active || undefined} hidden={!active}>\n <div data-slot=\"tabbed-container-query\">\n {search ? (\n <div data-slot=\"tabbed-container-search\">\n <ListSearch {...search} size=\"md\" shortcutDisabled={!active} />\n </div>\n ) : null}\n {filter ? (\n <TooltipProvider delay={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div data-slot=\"tabbed-container-filter\" data-active={filterCount > 0 || undefined}>\n <ListFilterIcon aria-hidden=\"true\" />\n {filterCount > 0 ? (\n <Txt as=\"span\" variant=\"meta\" aria-hidden=\"true\" data-slot=\"tabbed-container-filter-count\">\n {filterCount}\n </Txt>\n ) : null}\n {filter.multiple ? (\n <Combobox {...filter} clearLabel=\"Clear\" size=\"md\" variant=\"default\" />\n ) : (\n <Combobox {...filter} size=\"md\" variant=\"default\" />\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n {filterCount > 0 ? `Filter, ${filterCount} selected` : 'Filter'}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n </div>\n );\n });\n};\n\nexport type TabbedContainerProps<T extends string> = {\n children: ReactNode;\n defaultTab: T;\n value?: T;\n onValueChange?: (value: T) => void;\n frame?: TabsRootProps<T>['frame'];\n className?: string;\n};\n\ntype TabbedContainerChildProps = TabbedContainerPanelProps | TabbedContainerDataListProps;\n\nconst isContainerChild = (child: ReactNode): child is ReactElement<TabbedContainerChildProps> =>\n isValidElement(child) && (child.type === TabbedContainerPanel || child.type === TabbedContainerDataList);\n\nconst isDataList = (\n child: ReactElement<TabbedContainerChildProps>,\n): child is ReactElement<TabbedContainerDataListProps> => child.type === TabbedContainerDataList;\n\nexport function TabbedContainerRoot<T extends string>({\n children,\n defaultTab,\n value,\n onValueChange,\n frame = 'inset',\n className,\n}: TabbedContainerProps<T>) {\n const panels = Children.toArray(children).filter(isContainerChild);\n const dataLists = panels.filter(isDataList);\n return (\n <Tabs\n defaultTab={defaultTab}\n value={value}\n onValueChange={onValueChange}\n appearance=\"contained\"\n frame={frame}\n className={cn('tabbed-container min-h-0 flex-1', className)}\n >\n <div data-slot=\"tabbed-container-rail\">\n <div data-slot=\"tabbed-container-tabs\">\n <TabList>\n {panels.map(panel => (\n <Tab\n key={panel.props.value}\n value={panel.props.value}\n disabled={panel.props.disabled}\n attention={panel.props.attention}\n disabledTooltip={panel.props.disabledTooltip}\n onClick={panel.props.onClick}\n onClose={panel.props.onClose}\n className={panel.props.tabClassName}\n >\n {panel.props.label}\n </Tab>\n ))}\n </TabList>\n </div>\n <DataListControls dataLists={dataLists} />\n </div>\n {panels}\n </Tabs>\n );\n}\n","import { TabbedContainerDataList, TabbedContainerPanel, TabbedContainerRoot } from './tabbed-container-root';\n\nexport type {\n TabbedContainerDataListProps,\n TabbedContainerFilterProps,\n TabbedContainerPanelProps,\n TabbedContainerProps,\n TabbedContainerSearchProps,\n} from './tabbed-container-root';\n\nexport const TabbedContainer = Object.assign(TabbedContainerRoot, {\n Panel: TabbedContainerPanel,\n DataList: TabbedContainerDataList,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"tabbed-container-B4lCBgRP.cjs","names":["TabContent","cn","DataList","useContext","TabsContext","ListSearch","TooltipProvider","Tooltip","TooltipTrigger","ListFilterIcon","Txt","Combobox","TooltipContent","isValidElement","Children","Tabs","TabList","Tab"],"sources":["../src/ds/layout/tabbed-container/tabbed-container-root.tsx","../src/ds/layout/tabbed-container/index.ts"],"sourcesContent":["import { ListFilterIcon } from 'lucide-react';\nimport { Children, isValidElement, useContext } from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport './tabbed-container.css';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport type { ComboboxProps } from '@/ds/components/Combobox/combobox';\nimport { DataList } from '@/ds/components/DataList/data-list';\nimport type { DataListFit } from '@/ds/components/DataList/data-list-root';\nimport { ListSearch } from '@/ds/components/ListSearch/list-search';\nimport type { ListSearchProps } from '@/ds/components/ListSearch/list-search';\nimport { TabContent } from '@/ds/components/Tabs/tabs-content';\nimport { TabsContext } from '@/ds/components/Tabs/tabs-context';\nimport { TabList } from '@/ds/components/Tabs/tabs-list';\nimport { Tabs } from '@/ds/components/Tabs/tabs-root';\nimport type { TabsRootProps } from '@/ds/components/Tabs/tabs-root';\nimport { Tab } from '@/ds/components/Tabs/tabs-tab';\nimport type { TabProps } from '@/ds/components/Tabs/tabs-tab';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/ds/components/Tooltip/tooltip';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/lib/utils';\n\nexport type TabbedContainerSearchProps = Pick<\n ListSearchProps,\n 'debounceMs' | 'label' | 'onSearch' | 'placeholder' | 'value'\n>;\n\nexport type TabbedContainerFilterProps = ComboboxProps & { 'aria-label': string };\n\ntype TabbedContainerItemProps = Pick<\n TabProps,\n 'attention' | 'disabled' | 'disabledTooltip' | 'onClick' | 'onClose' | 'value'\n> & {\n label: ReactNode;\n children: ReactNode;\n className?: string;\n tabClassName?: string;\n};\n\nexport type TabbedContainerPanelProps = TabbedContainerItemProps;\n\nexport type TabbedContainerDataListProps = TabbedContainerItemProps & {\n columns: string;\n search?: TabbedContainerSearchProps;\n filter?: TabbedContainerFilterProps;\n fit?: DataListFit;\n};\n\nexport const TabbedContainerPanel = ({ value, children, className }: TabbedContainerPanelProps) => (\n <TabContent value={value} keepMounted className={cn('min-h-0 flex-1', className)}>\n {children}\n </TabContent>\n);\n\nexport const TabbedContainerDataList = ({ value, columns, fit, children, className }: TabbedContainerDataListProps) => (\n <TabContent value={value} keepMounted className={cn('tabbed-container-data-list min-h-0 flex-1', className)}>\n <DataList columns={columns} fit={fit} variant=\"light\" className=\"min-h-0 px-0 pb-0\">\n {children}\n </DataList>\n </TabContent>\n);\n\nexport const DataListControls = ({ dataLists }: { dataLists: ReactElement<TabbedContainerDataListProps>[] }) => {\n const tabs = useContext(TabsContext);\n return dataLists.map(dataList => {\n const { filter, search, value } = dataList.props;\n if (!search && !filter) return null;\n const active = value === tabs?.value;\n const filterCount = filter ? (Array.isArray(filter.value) ? filter.value.length : filter.value ? 1 : 0) : 0;\n return (\n <div key={value} data-slot=\"tabbed-container-controls\" data-active={active || undefined} hidden={!active}>\n <div data-slot=\"tabbed-container-query\">\n {search ? (\n <div data-slot=\"tabbed-container-search\">\n <ListSearch {...search} size=\"md\" shortcutDisabled={!active} />\n </div>\n ) : null}\n {filter ? (\n <TooltipProvider delay={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div data-slot=\"tabbed-container-filter\" data-active={filterCount > 0 || undefined}>\n <ListFilterIcon aria-hidden=\"true\" />\n {filterCount > 0 ? (\n <Txt as=\"span\" variant=\"meta\" aria-hidden=\"true\" data-slot=\"tabbed-container-filter-count\">\n {filterCount}\n </Txt>\n ) : null}\n {filter.multiple ? (\n <Combobox {...filter} clearLabel=\"Clear\" size=\"md\" variant=\"default\" />\n ) : (\n <Combobox {...filter} size=\"md\" variant=\"default\" />\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n {filterCount > 0 ? `Filter, ${filterCount} selected` : 'Filter'}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n </div>\n );\n });\n};\n\nexport type TabbedContainerProps<T extends string> = {\n children: ReactNode;\n defaultTab: T;\n value?: T;\n onValueChange?: (value: T) => void;\n frame?: TabsRootProps<T>['frame'];\n className?: string;\n};\n\ntype TabbedContainerChildProps = TabbedContainerPanelProps | TabbedContainerDataListProps;\n\nconst isContainerChild = (child: ReactNode): child is ReactElement<TabbedContainerChildProps> =>\n isValidElement(child) && (child.type === TabbedContainerPanel || child.type === TabbedContainerDataList);\n\nconst isDataList = (\n child: ReactElement<TabbedContainerChildProps>,\n): child is ReactElement<TabbedContainerDataListProps> => child.type === TabbedContainerDataList;\n\nexport function TabbedContainerRoot<T extends string>({\n children,\n defaultTab,\n value,\n onValueChange,\n frame = 'inset',\n className,\n}: TabbedContainerProps<T>) {\n const panels = Children.toArray(children).filter(isContainerChild);\n const dataLists = panels.filter(isDataList);\n return (\n <Tabs\n defaultTab={defaultTab}\n value={value}\n onValueChange={onValueChange}\n appearance=\"contained\"\n frame={frame}\n className={cn('tabbed-container min-h-0 flex-1', className)}\n >\n <div data-slot=\"tabbed-container-rail\">\n <div data-slot=\"tabbed-container-tabs\">\n <TabList>\n {panels.map(panel => (\n <Tab\n key={panel.props.value}\n value={panel.props.value}\n disabled={panel.props.disabled}\n attention={panel.props.attention}\n disabledTooltip={panel.props.disabledTooltip}\n onClick={panel.props.onClick}\n onClose={panel.props.onClose}\n className={panel.props.tabClassName}\n >\n {panel.props.label}\n </Tab>\n ))}\n </TabList>\n </div>\n <DataListControls dataLists={dataLists} />\n </div>\n {panels}\n </Tabs>\n );\n}\n","import { TabbedContainerDataList, TabbedContainerPanel, TabbedContainerRoot } from './tabbed-container-root';\n\nexport type {\n TabbedContainerDataListProps,\n TabbedContainerFilterProps,\n TabbedContainerPanelProps,\n TabbedContainerProps,\n TabbedContainerSearchProps,\n} from './tabbed-container-root';\n\nexport const TabbedContainer = Object.assign(TabbedContainerRoot, {\n Panel: TabbedContainerPanel,\n DataList: TabbedContainerDataList,\n});\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { t as Txt } from "./Txt-BM6TVV_c.js";
4
4
  import { i as TabsContext, n as Tabs, r as TabList, t as Tab } from "./tabs-tab-CYTZevdV.js";
5
5
  import { t as TabContent } from "./tabs-content-D__B9hd-.js";
6
6
  import { t as DataList } from "./data-list-DHCOoLmj.js";
7
- import { t as Combobox } from "./combobox-CtCK0mNx.js";
7
+ import { t as Combobox } from "./combobox-D21no8t5.js";
8
8
  import { t as ListSearch } from "./list-search-CkhsTFdG.js";
9
9
  import { Children, isValidElement, useContext } from "react";
10
10
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -122,4 +122,4 @@ var TabbedContainer = Object.assign(TabbedContainerRoot, {
122
122
  });
123
123
  export { TabbedContainer as t };
124
124
 
125
- //# sourceMappingURL=tabbed-container-5j6dhoRX.js.map
125
+ //# sourceMappingURL=tabbed-container-DI1GI1Qv.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabbed-container-5j6dhoRX.js","names":[],"sources":["../src/ds/layout/tabbed-container/tabbed-container-root.tsx","../src/ds/layout/tabbed-container/index.ts"],"sourcesContent":["import { ListFilterIcon } from 'lucide-react';\nimport { Children, isValidElement, useContext } from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport './tabbed-container.css';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport type { ComboboxProps } from '@/ds/components/Combobox/combobox';\nimport { DataList } from '@/ds/components/DataList/data-list';\nimport type { DataListFit } from '@/ds/components/DataList/data-list-root';\nimport { ListSearch } from '@/ds/components/ListSearch/list-search';\nimport type { ListSearchProps } from '@/ds/components/ListSearch/list-search';\nimport { TabContent } from '@/ds/components/Tabs/tabs-content';\nimport { TabsContext } from '@/ds/components/Tabs/tabs-context';\nimport { TabList } from '@/ds/components/Tabs/tabs-list';\nimport { Tabs } from '@/ds/components/Tabs/tabs-root';\nimport type { TabsRootProps } from '@/ds/components/Tabs/tabs-root';\nimport { Tab } from '@/ds/components/Tabs/tabs-tab';\nimport type { TabProps } from '@/ds/components/Tabs/tabs-tab';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/ds/components/Tooltip/tooltip';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/lib/utils';\n\nexport type TabbedContainerSearchProps = Pick<\n ListSearchProps,\n 'debounceMs' | 'label' | 'onSearch' | 'placeholder' | 'value'\n>;\n\nexport type TabbedContainerFilterProps = ComboboxProps & { 'aria-label': string };\n\ntype TabbedContainerItemProps = Pick<\n TabProps,\n 'attention' | 'disabled' | 'disabledTooltip' | 'onClick' | 'onClose' | 'value'\n> & {\n label: ReactNode;\n children: ReactNode;\n className?: string;\n tabClassName?: string;\n};\n\nexport type TabbedContainerPanelProps = TabbedContainerItemProps;\n\nexport type TabbedContainerDataListProps = TabbedContainerItemProps & {\n columns: string;\n search?: TabbedContainerSearchProps;\n filter?: TabbedContainerFilterProps;\n fit?: DataListFit;\n};\n\nexport const TabbedContainerPanel = ({ value, children, className }: TabbedContainerPanelProps) => (\n <TabContent value={value} keepMounted className={cn('min-h-0 flex-1', className)}>\n {children}\n </TabContent>\n);\n\nexport const TabbedContainerDataList = ({ value, columns, fit, children, className }: TabbedContainerDataListProps) => (\n <TabContent value={value} keepMounted className={cn('tabbed-container-data-list min-h-0 flex-1', className)}>\n <DataList columns={columns} fit={fit} variant=\"light\" className=\"min-h-0 px-0 pb-0\">\n {children}\n </DataList>\n </TabContent>\n);\n\nexport const DataListControls = ({ dataLists }: { dataLists: ReactElement<TabbedContainerDataListProps>[] }) => {\n const tabs = useContext(TabsContext);\n return dataLists.map(dataList => {\n const { filter, search, value } = dataList.props;\n if (!search && !filter) return null;\n const active = value === tabs?.value;\n const filterCount = filter ? (Array.isArray(filter.value) ? filter.value.length : filter.value ? 1 : 0) : 0;\n return (\n <div key={value} data-slot=\"tabbed-container-controls\" data-active={active || undefined} hidden={!active}>\n <div data-slot=\"tabbed-container-query\">\n {search ? (\n <div data-slot=\"tabbed-container-search\">\n <ListSearch {...search} size=\"md\" shortcutDisabled={!active} />\n </div>\n ) : null}\n {filter ? (\n <TooltipProvider delay={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div data-slot=\"tabbed-container-filter\" data-active={filterCount > 0 || undefined}>\n <ListFilterIcon aria-hidden=\"true\" />\n {filterCount > 0 ? (\n <Txt as=\"span\" variant=\"meta\" aria-hidden=\"true\" data-slot=\"tabbed-container-filter-count\">\n {filterCount}\n </Txt>\n ) : null}\n {filter.multiple ? (\n <Combobox {...filter} clearLabel=\"Clear\" size=\"md\" variant=\"default\" />\n ) : (\n <Combobox {...filter} size=\"md\" variant=\"default\" />\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n {filterCount > 0 ? `Filter, ${filterCount} selected` : 'Filter'}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n </div>\n );\n });\n};\n\nexport type TabbedContainerProps<T extends string> = {\n children: ReactNode;\n defaultTab: T;\n value?: T;\n onValueChange?: (value: T) => void;\n frame?: TabsRootProps<T>['frame'];\n className?: string;\n};\n\ntype TabbedContainerChildProps = TabbedContainerPanelProps | TabbedContainerDataListProps;\n\nconst isContainerChild = (child: ReactNode): child is ReactElement<TabbedContainerChildProps> =>\n isValidElement(child) && (child.type === TabbedContainerPanel || child.type === TabbedContainerDataList);\n\nconst isDataList = (\n child: ReactElement<TabbedContainerChildProps>,\n): child is ReactElement<TabbedContainerDataListProps> => child.type === TabbedContainerDataList;\n\nexport function TabbedContainerRoot<T extends string>({\n children,\n defaultTab,\n value,\n onValueChange,\n frame = 'inset',\n className,\n}: TabbedContainerProps<T>) {\n const panels = Children.toArray(children).filter(isContainerChild);\n const dataLists = panels.filter(isDataList);\n return (\n <Tabs\n defaultTab={defaultTab}\n value={value}\n onValueChange={onValueChange}\n appearance=\"contained\"\n frame={frame}\n className={cn('tabbed-container min-h-0 flex-1', className)}\n >\n <div data-slot=\"tabbed-container-rail\">\n <div data-slot=\"tabbed-container-tabs\">\n <TabList>\n {panels.map(panel => (\n <Tab\n key={panel.props.value}\n value={panel.props.value}\n disabled={panel.props.disabled}\n attention={panel.props.attention}\n disabledTooltip={panel.props.disabledTooltip}\n onClick={panel.props.onClick}\n onClose={panel.props.onClose}\n className={panel.props.tabClassName}\n >\n {panel.props.label}\n </Tab>\n ))}\n </TabList>\n </div>\n <DataListControls dataLists={dataLists} />\n </div>\n {panels}\n </Tabs>\n );\n}\n","import { TabbedContainerDataList, TabbedContainerPanel, TabbedContainerRoot } from './tabbed-container-root';\n\nexport type {\n TabbedContainerDataListProps,\n TabbedContainerFilterProps,\n TabbedContainerPanelProps,\n TabbedContainerProps,\n TabbedContainerSearchProps,\n} from './tabbed-container-root';\n\nexport const TabbedContainer = Object.assign(TabbedContainerRoot, {\n Panel: TabbedContainerPanel,\n DataList: TabbedContainerDataList,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"tabbed-container-DI1GI1Qv.js","names":[],"sources":["../src/ds/layout/tabbed-container/tabbed-container-root.tsx","../src/ds/layout/tabbed-container/index.ts"],"sourcesContent":["import { ListFilterIcon } from 'lucide-react';\nimport { Children, isValidElement, useContext } from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport './tabbed-container.css';\nimport { Combobox } from '@/ds/components/Combobox/combobox';\nimport type { ComboboxProps } from '@/ds/components/Combobox/combobox';\nimport { DataList } from '@/ds/components/DataList/data-list';\nimport type { DataListFit } from '@/ds/components/DataList/data-list-root';\nimport { ListSearch } from '@/ds/components/ListSearch/list-search';\nimport type { ListSearchProps } from '@/ds/components/ListSearch/list-search';\nimport { TabContent } from '@/ds/components/Tabs/tabs-content';\nimport { TabsContext } from '@/ds/components/Tabs/tabs-context';\nimport { TabList } from '@/ds/components/Tabs/tabs-list';\nimport { Tabs } from '@/ds/components/Tabs/tabs-root';\nimport type { TabsRootProps } from '@/ds/components/Tabs/tabs-root';\nimport { Tab } from '@/ds/components/Tabs/tabs-tab';\nimport type { TabProps } from '@/ds/components/Tabs/tabs-tab';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/ds/components/Tooltip/tooltip';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/lib/utils';\n\nexport type TabbedContainerSearchProps = Pick<\n ListSearchProps,\n 'debounceMs' | 'label' | 'onSearch' | 'placeholder' | 'value'\n>;\n\nexport type TabbedContainerFilterProps = ComboboxProps & { 'aria-label': string };\n\ntype TabbedContainerItemProps = Pick<\n TabProps,\n 'attention' | 'disabled' | 'disabledTooltip' | 'onClick' | 'onClose' | 'value'\n> & {\n label: ReactNode;\n children: ReactNode;\n className?: string;\n tabClassName?: string;\n};\n\nexport type TabbedContainerPanelProps = TabbedContainerItemProps;\n\nexport type TabbedContainerDataListProps = TabbedContainerItemProps & {\n columns: string;\n search?: TabbedContainerSearchProps;\n filter?: TabbedContainerFilterProps;\n fit?: DataListFit;\n};\n\nexport const TabbedContainerPanel = ({ value, children, className }: TabbedContainerPanelProps) => (\n <TabContent value={value} keepMounted className={cn('min-h-0 flex-1', className)}>\n {children}\n </TabContent>\n);\n\nexport const TabbedContainerDataList = ({ value, columns, fit, children, className }: TabbedContainerDataListProps) => (\n <TabContent value={value} keepMounted className={cn('tabbed-container-data-list min-h-0 flex-1', className)}>\n <DataList columns={columns} fit={fit} variant=\"light\" className=\"min-h-0 px-0 pb-0\">\n {children}\n </DataList>\n </TabContent>\n);\n\nexport const DataListControls = ({ dataLists }: { dataLists: ReactElement<TabbedContainerDataListProps>[] }) => {\n const tabs = useContext(TabsContext);\n return dataLists.map(dataList => {\n const { filter, search, value } = dataList.props;\n if (!search && !filter) return null;\n const active = value === tabs?.value;\n const filterCount = filter ? (Array.isArray(filter.value) ? filter.value.length : filter.value ? 1 : 0) : 0;\n return (\n <div key={value} data-slot=\"tabbed-container-controls\" data-active={active || undefined} hidden={!active}>\n <div data-slot=\"tabbed-container-query\">\n {search ? (\n <div data-slot=\"tabbed-container-search\">\n <ListSearch {...search} size=\"md\" shortcutDisabled={!active} />\n </div>\n ) : null}\n {filter ? (\n <TooltipProvider delay={200}>\n <Tooltip>\n <TooltipTrigger asChild>\n <div data-slot=\"tabbed-container-filter\" data-active={filterCount > 0 || undefined}>\n <ListFilterIcon aria-hidden=\"true\" />\n {filterCount > 0 ? (\n <Txt as=\"span\" variant=\"meta\" aria-hidden=\"true\" data-slot=\"tabbed-container-filter-count\">\n {filterCount}\n </Txt>\n ) : null}\n {filter.multiple ? (\n <Combobox {...filter} clearLabel=\"Clear\" size=\"md\" variant=\"default\" />\n ) : (\n <Combobox {...filter} size=\"md\" variant=\"default\" />\n )}\n </div>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n {filterCount > 0 ? `Filter, ${filterCount} selected` : 'Filter'}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n </div>\n );\n });\n};\n\nexport type TabbedContainerProps<T extends string> = {\n children: ReactNode;\n defaultTab: T;\n value?: T;\n onValueChange?: (value: T) => void;\n frame?: TabsRootProps<T>['frame'];\n className?: string;\n};\n\ntype TabbedContainerChildProps = TabbedContainerPanelProps | TabbedContainerDataListProps;\n\nconst isContainerChild = (child: ReactNode): child is ReactElement<TabbedContainerChildProps> =>\n isValidElement(child) && (child.type === TabbedContainerPanel || child.type === TabbedContainerDataList);\n\nconst isDataList = (\n child: ReactElement<TabbedContainerChildProps>,\n): child is ReactElement<TabbedContainerDataListProps> => child.type === TabbedContainerDataList;\n\nexport function TabbedContainerRoot<T extends string>({\n children,\n defaultTab,\n value,\n onValueChange,\n frame = 'inset',\n className,\n}: TabbedContainerProps<T>) {\n const panels = Children.toArray(children).filter(isContainerChild);\n const dataLists = panels.filter(isDataList);\n return (\n <Tabs\n defaultTab={defaultTab}\n value={value}\n onValueChange={onValueChange}\n appearance=\"contained\"\n frame={frame}\n className={cn('tabbed-container min-h-0 flex-1', className)}\n >\n <div data-slot=\"tabbed-container-rail\">\n <div data-slot=\"tabbed-container-tabs\">\n <TabList>\n {panels.map(panel => (\n <Tab\n key={panel.props.value}\n value={panel.props.value}\n disabled={panel.props.disabled}\n attention={panel.props.attention}\n disabledTooltip={panel.props.disabledTooltip}\n onClick={panel.props.onClick}\n onClose={panel.props.onClose}\n className={panel.props.tabClassName}\n >\n {panel.props.label}\n </Tab>\n ))}\n </TabList>\n </div>\n <DataListControls dataLists={dataLists} />\n </div>\n {panels}\n </Tabs>\n );\n}\n","import { TabbedContainerDataList, TabbedContainerPanel, TabbedContainerRoot } from './tabbed-container-root';\n\nexport type {\n TabbedContainerDataListProps,\n TabbedContainerFilterProps,\n TabbedContainerPanelProps,\n TabbedContainerProps,\n TabbedContainerSearchProps,\n} from './tabbed-container-root';\n\nexport const TabbedContainer = Object.assign(TabbedContainerRoot, {\n Panel: TabbedContainerPanel,\n DataList: TabbedContainerDataList,\n});\n"],"mappings":"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"}
package/oxlint/index.js CHANGED
@@ -13,6 +13,7 @@
13
13
  // playground-ui/txt-tone ink on <Txt> is its `tone` prop, not a text-* colour class
14
14
  // playground-ui/font-mono mono comes from <Txt font="mono">, <InlineCode> or <CodeBlock>
15
15
  // playground-ui/no-barrel-imports import from an exact @mastra/playground-ui subpath, not a broad barrel
16
+ // playground-ui/placeholder-text placeholders use sentence case and no trailing ellipsis ("Search agents")
16
17
 
17
18
  // Each option is { selector, message }: report every node an esquery selector matches.
18
19
  function selectorRule(selectors) {
@@ -178,6 +179,93 @@ const noBarrelImports = selectorRule(() =>
178
179
  ]).map(selector => ({ selector, message: BARREL_MESSAGE })),
179
180
  );
180
181
 
182
+ // --- placeholder-text ----------------------------------------------------------------------------------
183
+ // Placeholders read like the system search field on macOS and iOS: "Search agents", "Filter by name". No
184
+ // trailing ellipsis (`…` or `...`): the dimmed text already says the field is empty. Placeholders that give
185
+ // an instruction (start with Search, Filter, Select…) also use sentence case. Example values ("My Agent",
186
+ // "e.g. Production alerts") keep their capitals.
187
+ // Checks string `placeholder` / `*Placeholder` values in JSX attributes, object properties, default
188
+ // parameters and variables, including each branch of a ternary. Strings built at runtime are only partly seen.
189
+ // Options: { properNouns?: string[] } words that stay capitalized after the first, added to the defaults.
190
+ const PLACEHOLDER_NAME = /^placeholder$|Placeholder$/;
191
+ const INSTRUCTION_VERBS =
192
+ /^(Search|Filter|Find|Select|Choose|Pick|Enter|Type|Paste|Add|Write|Describe|Leave|Ask|Send|Name)\b/;
193
+ const PLACEHOLDER_PROPER_NOUNS = [
194
+ 'Mastra Code',
195
+ 'Mastra',
196
+ 'Studio',
197
+ 'Factory',
198
+ 'Factories',
199
+ 'MastraCode',
200
+ 'GitHub',
201
+ 'GitLab',
202
+ 'Google',
203
+ 'Slack',
204
+ 'Linear',
205
+ 'Vercel',
206
+ 'Stripe',
207
+ ];
208
+
209
+ // The string values a placeholder expression can take: literals, static template parts, ternary branches.
210
+ function placeholderStrings(node) {
211
+ if (!node) return [];
212
+ if (node.type === 'JSXExpressionContainer') return placeholderStrings(node.expression);
213
+ if (node.type === 'Literal' && typeof node.value === 'string') return [{ node, head: node.value, tail: node.value }];
214
+ if (node.type === 'TemplateLiteral') {
215
+ const { quasis } = node;
216
+ return [{ node, head: quasis[0].value.cooked, tail: quasis[quasis.length - 1].value.cooked }];
217
+ }
218
+ if (node.type === 'ConditionalExpression')
219
+ return [...placeholderStrings(node.consequent), ...placeholderStrings(node.alternate)];
220
+ if (node.type === 'LogicalExpression') return placeholderStrings(node.right);
221
+ return [];
222
+ }
223
+
224
+ function placeholderText(context) {
225
+ const nouns = [...PLACEHOLDER_PROPER_NOUNS, ...(context.options[0]?.properNouns ?? [])];
226
+ const properNouns = new RegExp(`\\b(?:${nouns.sort((a, b) => b.length - a.length).join('|')})\\b`, 'g');
227
+ // The first capitalized word that doesn't start a sentence and isn't (part of) a proper noun.
228
+ const titleCaseWord = text => {
229
+ let sentenceStart = true;
230
+ for (const word of text.replace(properNouns, 'x').trim().split(/\s+/)) {
231
+ if (!sentenceStart && /^[A-Z][a-z]/.test(word)) return word;
232
+ sentenceStart = /[.!?:]$/.test(word);
233
+ }
234
+ return null;
235
+ };
236
+ const check = value => {
237
+ for (const { node, head, tail } of placeholderStrings(value)) {
238
+ // A progress state shown in the field ("Loading agents…") keeps its ellipsis.
239
+ if (/(…|\.\.\.)\s*$/.test(tail) && !/^\s*\w+ing\b/.test(head)) {
240
+ context.report({ node, message: 'Drop the trailing ellipsis from this placeholder ("Search agents").' });
241
+ }
242
+ if (!INSTRUCTION_VERBS.test(head)) continue;
243
+ const word = titleCaseWord(head);
244
+ if (word) {
245
+ context.report({
246
+ node,
247
+ message: `Use sentence case in this placeholder: lowercase "${word.replace(/[^A-Za-z]+$/, '')}" unless it's a proper noun (add it to properNouns).`,
248
+ });
249
+ }
250
+ }
251
+ };
252
+ const keyName = key => (key?.type === 'Identifier' ? key.name : key?.type === 'Literal' ? key.value : '');
253
+ return {
254
+ JSXAttribute(node) {
255
+ if (node.name.type === 'JSXIdentifier' && PLACEHOLDER_NAME.test(node.name.name)) check(node.value);
256
+ },
257
+ Property(node) {
258
+ if (PLACEHOLDER_NAME.test(keyName(node.key))) check(node.value);
259
+ },
260
+ AssignmentPattern(node) {
261
+ if (node.left.type === 'Identifier' && PLACEHOLDER_NAME.test(node.left.name)) check(node.right);
262
+ },
263
+ VariableDeclarator(node) {
264
+ if (node.id.type === 'Identifier' && PLACEHOLDER_NAME.test(node.id.name)) check(node.init);
265
+ },
266
+ };
267
+ }
268
+
181
269
  const plugin = {
182
270
  meta: { name: 'playground-ui' },
183
271
  rules: {
@@ -186,6 +274,7 @@ const plugin = {
186
274
  'txt-tone': { meta: { type: 'suggestion', schema: false }, create: txtTone },
187
275
  'font-mono': { meta: { type: 'suggestion', schema: false }, create: fontMono },
188
276
  'no-barrel-imports': { meta: { type: 'suggestion', schema: false }, create: noBarrelImports },
277
+ 'placeholder-text': { meta: { type: 'suggestion', schema: false }, create: placeholderText },
189
278
  },
190
279
  };
191
280
 
@@ -197,6 +286,7 @@ export const recommended = {
197
286
  'playground-ui/txt-tone': 'error',
198
287
  'playground-ui/font-mono': 'error',
199
288
  'playground-ui/no-barrel-imports': 'error',
289
+ 'playground-ui/placeholder-text': 'error',
200
290
  };
201
291
 
202
292
  export default plugin;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mastra/playground-ui",
3
3
  "type": "module",
4
- "version": "68.0.0-alpha.1",
4
+ "version": "68.0.0-alpha.2",
5
5
  "description": "Mastra Playground components",
6
6
  "sideEffects": [
7
7
  "**/*.css"
@@ -220,9 +220,9 @@
220
220
  "react": ">=19.0.0",
221
221
  "react-dom": ">=19.0.0",
222
222
  "tailwindcss": "^4.0.0",
223
+ "@mastra/client-js": "^1.59.0-alpha.2",
223
224
  "@mastra/ai-sdk": "^1.11.3",
224
- "@mastra/client-js": "^1.59.0-alpha.1",
225
- "@mastra/react": "1.14.1-alpha.1"
225
+ "@mastra/react": "1.14.1-alpha.2"
226
226
  },
227
227
  "devDependencies": {
228
228
  "@modelcontextprotocol/sdk": "^1.32.2",
@@ -263,12 +263,12 @@
263
263
  "vite-plugin-lib-inject-css": "^2.2.2",
264
264
  "vitest": "4.1.12",
265
265
  "@types/d3-force": "^3.0.10",
266
- "@internal/lint": "0.0.147",
267
266
  "@mastra/ai-sdk": "1.11.3",
268
- "@mastra/client-js": "^1.59.0-alpha.1",
269
- "@mastra/core": "1.82.0-alpha.1",
270
- "@mastra/memory": "1.41.0-alpha.1",
271
- "@mastra/react": "1.14.1-alpha.1",
267
+ "@mastra/client-js": "^1.59.0-alpha.2",
268
+ "@internal/lint": "0.0.147",
269
+ "@mastra/core": "1.82.0-alpha.2",
270
+ "@mastra/memory": "1.41.0-alpha.2",
271
+ "@mastra/react": "1.14.1-alpha.2",
272
272
  "@mastra/schema-compat": "1.3.17"
273
273
  },
274
274
  "homepage": "https://mastra.ai",
package/theme.css CHANGED
@@ -47,10 +47,11 @@
47
47
  text read as a second ink instead of stepping back. */
48
48
  --muted-foreground: var(--gray-8);
49
49
  --placeholder: var(--gray-7);
50
- /* The icons inside an interactive control (see `controlIconState`): supporting at rest,
51
- the label's ink on hover. Contexts retune the pair, never the rule. */
50
+ /* The icons inside an interactive control (see `controlIconState`). A labelled control's
51
+ icons stay muted on hover: the label and surface answer it. Icon-only controls and lists
52
+ retune the pair, never the rule. */
52
53
  --control-icon-rest: var(--muted-foreground);
53
- --control-icon-hover: var(--foreground);
54
+ --control-icon-hover: var(--muted-foreground);
54
55
  }
55
56
 
56
57
  /* Semantic aliases stay inline so utilities resolve var(--token) on the styled
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataCodeSection-CcPmJPTp.cjs","names":["Text","Chunk","useRef","EditorView","useMemo","RangeSetBuilder","Decoration","CodeEditor","useState","cn","DataPanelSectionHeading","Button","SearchIcon","SearchInput","ButtonsGroup","CopyButton","AlignLeftIcon","AlignJustifyIcon","ExpandIcon","raisedSurfaceStyle","Dialog","DialogContent","DialogHeader","DialogTitle","_Fragment","DialogBody"],"sources":["../src/ds/components/DataCodeSection/data-code-section.tsx"],"sourcesContent":["import { Chunk } from '@codemirror/merge';\nimport { RangeSetBuilder, Text } from '@codemirror/state';\nimport { Decoration, EditorView } from '@codemirror/view';\nimport type { ReactCodeMirrorRef } from '@uiw/react-codemirror';\nimport { AlignJustifyIcon, AlignLeftIcon, ExpandIcon, SearchIcon } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { Button } from '@/ds/components/Button';\nimport { ButtonsGroup } from '@/ds/components/ButtonsGroup';\nimport { CodeEditor } from '@/ds/components/CodeEditor';\nimport { CopyButton } from '@/ds/components/CopyButton';\nimport { DataPanelSectionHeading } from '@/ds/components/DataPanel/data-panel-section-heading';\nimport { Dialog, DialogBody, DialogContent, DialogHeader, DialogTitle } from '@/ds/components/Dialog';\nimport { SearchInput } from '@/ds/components/SearchInput';\nimport { raisedSurfaceStyle } from '@/ds/primitives/raised-surface';\nimport { cn } from '@/lib/utils';\n\nexport interface DataCodeSectionDiff {\n /** The other document to compare against. */\n against: string;\n /** `a` = this document is the \"before\" (changes in red), `b` = \"after\" (changes in green). */\n side: 'a' | 'b';\n}\n\n/** Zero-based indexes of the lines of `doc` that differ from `diff.against`. */\nfunction changedLines(doc: string, { against, side }: DataCodeSectionDiff): Set<number> {\n const [a, b] = side === 'a' ? [doc, against] : [against, doc];\n const text = Text.of(doc.split('\\n'));\n const lines = new Set<number>();\n for (const chunk of Chunk.build(Text.of(a.split('\\n')), Text.of(b.split('\\n')))) {\n const from = side === 'a' ? chunk.fromA : chunk.fromB;\n const to = side === 'a' ? chunk.endA : chunk.endB;\n if (from >= to) continue;\n for (let pos = from; pos <= Math.min(to, text.length);) {\n const line = text.lineAt(pos);\n lines.add(line.number - 1);\n if (line.to >= to) break;\n pos = line.to + 1;\n }\n }\n return lines;\n}\n\nconst diffLineStyles = {\n removed: 'code-diff-removed bg-destructive-subtle',\n added: 'code-diff-added bg-success-subtle',\n};\nconst searchMatchStyle = 'code-search-match rounded-sm bg-badge-amber-strong';\n\ninterface CodeViewProps {\n code: string;\n changed?: Set<number>;\n diffSide?: DataCodeSectionDiff['side'];\n searchQuery: string;\n}\n\nfunction CodeView({ code, changed, diffSide, searchQuery }: CodeViewProps) {\n const ref = useRef<ReactCodeMirrorRef>(null);\n const query = searchQuery.toLowerCase();\n\n // Matches are scrolled to through CodeMirror: it only renders the visible lines, so an off-screen match has no DOM node yet.\n useEffect(() => {\n const view = ref.current?.view;\n if (!query || !view) return;\n const doc = view.state.doc;\n for (let n = 1; n <= doc.lines; n++) {\n const line = doc.line(n);\n if (line.text.toLowerCase().includes(query)) {\n view.dispatch({ effects: EditorView.scrollIntoView(line.from, { y: 'nearest' }) });\n return;\n }\n }\n }, [query]);\n\n const extensions = useMemo(\n () => [\n EditorView.decorations.compute(['doc'], state => {\n const builder = new RangeSetBuilder<Decoration>();\n for (let n = 1; n <= state.doc.lines; n++) {\n const line = state.doc.line(n);\n const classes: string[] = [];\n if (diffSide && changed?.has(n - 1)) classes.push(diffLineStyles[diffSide === 'a' ? 'removed' : 'added']);\n if (query && line.text.toLowerCase().includes(query)) classes.push(searchMatchStyle);\n if (classes.length) builder.add(line.from, line.from, Decoration.line({ class: classes.join(' ') }));\n }\n return builder.finish();\n }),\n ],\n [changed, diffSide, query],\n );\n\n return (\n <CodeEditor\n ref={ref}\n value={code}\n language=\"json\"\n editable={false}\n lineNumbers={false}\n showCopyButton={false}\n variant=\"embedded\"\n aria-label=\"JSON content\"\n extensions={extensions}\n />\n );\n}\n\nexport interface DataCodeSectionProps {\n title: React.ReactNode;\n dialogTitle?: React.ReactNode;\n icon?: React.ReactNode;\n codeStr?: string;\n simplified?: boolean;\n className?: string;\n /** Highlight lines that differ from another document. */\n diff?: DataCodeSectionDiff;\n /** Extra controls rendered in the header, before the built-in copy/expand buttons. */\n actions?: React.ReactNode;\n}\n\nexport function DataCodeSection({\n codeStr = '',\n title,\n dialogTitle,\n icon,\n simplified = false,\n className,\n diff,\n actions,\n}: DataCodeSectionProps) {\n const changed = useMemo(() => (diff ? changedLines(codeStr, diff) : undefined), [codeStr, diff]);\n const [showAsMultilineText, setShowAsMultilineText] = useState(false);\n const [searchMinimized, setSearchMinimized] = useState(true);\n const [searchQuery, setSearchQuery] = useState('');\n const [expandedOpen, setExpandedOpen] = useState(false);\n const [expandedSearchQuery, setExpandedSearchQuery] = useState('');\n const [expandedMultiline, setExpandedMultiline] = useState(false);\n\n const hasMultilineText = useMemo(() => {\n try {\n const parsed = JSON.parse(codeStr);\n return containsInnerNewline(parsed || '');\n } catch {\n return false;\n }\n }, [codeStr]);\n\n const finalCodeStr = showAsMultilineText ? codeStr?.replace(/\\\\n/g, '\\n') : codeStr;\n const expandedFinalCodeStr = expandedMultiline ? codeStr?.replace(/\\\\n/g, '\\n') : codeStr;\n const usePlainTextView = simplified || showAsMultilineText;\n\n if (!codeStr || codeStr === 'null') return null;\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n <div className=\"flex items-center justify-between\">\n <DataPanelSectionHeading icon={icon}>{title}</DataPanelSectionHeading>\n <div className=\"flex items-center gap-2\">\n {actions}\n {!usePlainTextView &&\n (searchMinimized ? (\n <Button\n size=\"icon-sm\"\n aria-label=\"Search code\"\n tooltip=\"Search code\"\n onClick={() => setSearchMinimized(false)}\n >\n <SearchIcon />\n </Button>\n ) : (\n <SearchInput\n label=\"Search code\"\n placeholder=\"Search...\"\n size=\"sm\"\n value={searchQuery}\n onValueChange={setSearchQuery}\n onClose={() => setSearchMinimized(true)}\n autoFocus\n />\n ))}\n <ButtonsGroup size=\"sm\">\n <CopyButton content={codeStr || 'No content'} />\n {hasMultilineText && (\n <Button\n size=\"icon-md\"\n aria-label={showAsMultilineText ? 'Show escaped newlines' : 'Show multiline text'}\n tooltip={showAsMultilineText ? 'Show escaped newlines' : 'Show multiline text'}\n onClick={() => setShowAsMultilineText(v => !v)}\n >\n {showAsMultilineText ? <AlignLeftIcon /> : <AlignJustifyIcon />}\n </Button>\n )}\n <Button size=\"icon-md\" aria-label=\"Expand\" tooltip=\"Expand\" onClick={() => setExpandedOpen(true)}>\n <ExpandIcon />\n </Button>\n </ButtonsGroup>\n </div>\n </div>\n\n <div\n className={cn(\n raisedSurfaceStyle,\n 'max-h-[30vh] overflow-hidden overflow-y-auto rounded-lg p-3 text-caption break-all text-muted-foreground',\n )}\n >\n {usePlainTextView ? (\n <div className=\"font-mono break-all text-muted-foreground\">\n <pre className=\"text-wrap\">{finalCodeStr}</pre>\n </div>\n ) : (\n <CodeView code={codeStr} changed={changed} diffSide={diff?.side} searchQuery={searchQuery} />\n )}\n </div>\n\n <Dialog open={expandedOpen} onOpenChange={setExpandedOpen}>\n <DialogContent size=\"full\">\n <DialogHeader>\n <div className=\"flex min-w-0 items-center justify-between gap-2\">\n <DialogTitle className=\"flex min-w-0 items-center gap-1.5 truncate [&>svg]:size-3.5\">\n {dialogTitle ?? (\n <>\n {icon}\n {title}\n </>\n )}\n </DialogTitle>\n <div className=\"flex shrink-0 items-center gap-2\">\n {!expandedMultiline && (\n <SearchInput\n label=\"Search code\"\n placeholder=\"Search...\"\n size=\"sm\"\n value={expandedSearchQuery}\n onValueChange={setExpandedSearchQuery}\n />\n )}\n <ButtonsGroup size=\"sm\">\n <CopyButton content={codeStr || 'No content'} />\n {hasMultilineText && (\n <Button\n size=\"icon-md\"\n aria-label={expandedMultiline ? 'Show escaped newlines' : 'Show multiline text'}\n tooltip={expandedMultiline ? 'Show escaped newlines' : 'Show multiline text'}\n onClick={() => setExpandedMultiline(v => !v)}\n >\n {expandedMultiline ? <AlignLeftIcon /> : <AlignJustifyIcon />}\n </Button>\n )}\n </ButtonsGroup>\n </div>\n </div>\n </DialogHeader>\n <DialogBody layout=\"fill\">\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {expandedMultiline ? (\n <div className={cn(raisedSurfaceStyle, 'rounded-lg p-3 text-caption break-all text-muted-foreground')}>\n <div className=\"font-mono break-all text-muted-foreground\">\n <pre className=\"text-wrap\">{expandedFinalCodeStr}</pre>\n </div>\n </div>\n ) : (\n <CodeView code={codeStr} changed={changed} diffSide={diff?.side} searchQuery={expandedSearchQuery} />\n )}\n </div>\n </DialogBody>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n\nfunction containsInnerNewline(obj: unknown): boolean {\n if (typeof obj === 'string') {\n const idx = obj.indexOf('\\n');\n return idx !== -1 && idx !== obj.length - 1;\n } else if (Array.isArray(obj)) {\n return obj.some(item => containsInnerNewline(item));\n } else if (obj && typeof obj === 'object') {\n return Object.values(obj).some(value => containsInnerNewline(value));\n }\n return false;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataCodeSection-KJRyRD1Q.js","names":["Text","_Fragment"],"sources":["../src/ds/components/DataCodeSection/data-code-section.tsx"],"sourcesContent":["import { Chunk } from '@codemirror/merge';\nimport { RangeSetBuilder, Text } from '@codemirror/state';\nimport { Decoration, EditorView } from '@codemirror/view';\nimport type { ReactCodeMirrorRef } from '@uiw/react-codemirror';\nimport { AlignJustifyIcon, AlignLeftIcon, ExpandIcon, SearchIcon } from 'lucide-react';\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport { Button } from '@/ds/components/Button';\nimport { ButtonsGroup } from '@/ds/components/ButtonsGroup';\nimport { CodeEditor } from '@/ds/components/CodeEditor';\nimport { CopyButton } from '@/ds/components/CopyButton';\nimport { DataPanelSectionHeading } from '@/ds/components/DataPanel/data-panel-section-heading';\nimport { Dialog, DialogBody, DialogContent, DialogHeader, DialogTitle } from '@/ds/components/Dialog';\nimport { SearchInput } from '@/ds/components/SearchInput';\nimport { raisedSurfaceStyle } from '@/ds/primitives/raised-surface';\nimport { cn } from '@/lib/utils';\n\nexport interface DataCodeSectionDiff {\n /** The other document to compare against. */\n against: string;\n /** `a` = this document is the \"before\" (changes in red), `b` = \"after\" (changes in green). */\n side: 'a' | 'b';\n}\n\n/** Zero-based indexes of the lines of `doc` that differ from `diff.against`. */\nfunction changedLines(doc: string, { against, side }: DataCodeSectionDiff): Set<number> {\n const [a, b] = side === 'a' ? [doc, against] : [against, doc];\n const text = Text.of(doc.split('\\n'));\n const lines = new Set<number>();\n for (const chunk of Chunk.build(Text.of(a.split('\\n')), Text.of(b.split('\\n')))) {\n const from = side === 'a' ? chunk.fromA : chunk.fromB;\n const to = side === 'a' ? chunk.endA : chunk.endB;\n if (from >= to) continue;\n for (let pos = from; pos <= Math.min(to, text.length);) {\n const line = text.lineAt(pos);\n lines.add(line.number - 1);\n if (line.to >= to) break;\n pos = line.to + 1;\n }\n }\n return lines;\n}\n\nconst diffLineStyles = {\n removed: 'code-diff-removed bg-destructive-subtle',\n added: 'code-diff-added bg-success-subtle',\n};\nconst searchMatchStyle = 'code-search-match rounded-sm bg-badge-amber-strong';\n\ninterface CodeViewProps {\n code: string;\n changed?: Set<number>;\n diffSide?: DataCodeSectionDiff['side'];\n searchQuery: string;\n}\n\nfunction CodeView({ code, changed, diffSide, searchQuery }: CodeViewProps) {\n const ref = useRef<ReactCodeMirrorRef>(null);\n const query = searchQuery.toLowerCase();\n\n // Matches are scrolled to through CodeMirror: it only renders the visible lines, so an off-screen match has no DOM node yet.\n useEffect(() => {\n const view = ref.current?.view;\n if (!query || !view) return;\n const doc = view.state.doc;\n for (let n = 1; n <= doc.lines; n++) {\n const line = doc.line(n);\n if (line.text.toLowerCase().includes(query)) {\n view.dispatch({ effects: EditorView.scrollIntoView(line.from, { y: 'nearest' }) });\n return;\n }\n }\n }, [query]);\n\n const extensions = useMemo(\n () => [\n EditorView.decorations.compute(['doc'], state => {\n const builder = new RangeSetBuilder<Decoration>();\n for (let n = 1; n <= state.doc.lines; n++) {\n const line = state.doc.line(n);\n const classes: string[] = [];\n if (diffSide && changed?.has(n - 1)) classes.push(diffLineStyles[diffSide === 'a' ? 'removed' : 'added']);\n if (query && line.text.toLowerCase().includes(query)) classes.push(searchMatchStyle);\n if (classes.length) builder.add(line.from, line.from, Decoration.line({ class: classes.join(' ') }));\n }\n return builder.finish();\n }),\n ],\n [changed, diffSide, query],\n );\n\n return (\n <CodeEditor\n ref={ref}\n value={code}\n language=\"json\"\n editable={false}\n lineNumbers={false}\n showCopyButton={false}\n variant=\"embedded\"\n aria-label=\"JSON content\"\n extensions={extensions}\n />\n );\n}\n\nexport interface DataCodeSectionProps {\n title: React.ReactNode;\n dialogTitle?: React.ReactNode;\n icon?: React.ReactNode;\n codeStr?: string;\n simplified?: boolean;\n className?: string;\n /** Highlight lines that differ from another document. */\n diff?: DataCodeSectionDiff;\n /** Extra controls rendered in the header, before the built-in copy/expand buttons. */\n actions?: React.ReactNode;\n}\n\nexport function DataCodeSection({\n codeStr = '',\n title,\n dialogTitle,\n icon,\n simplified = false,\n className,\n diff,\n actions,\n}: DataCodeSectionProps) {\n const changed = useMemo(() => (diff ? changedLines(codeStr, diff) : undefined), [codeStr, diff]);\n const [showAsMultilineText, setShowAsMultilineText] = useState(false);\n const [searchMinimized, setSearchMinimized] = useState(true);\n const [searchQuery, setSearchQuery] = useState('');\n const [expandedOpen, setExpandedOpen] = useState(false);\n const [expandedSearchQuery, setExpandedSearchQuery] = useState('');\n const [expandedMultiline, setExpandedMultiline] = useState(false);\n\n const hasMultilineText = useMemo(() => {\n try {\n const parsed = JSON.parse(codeStr);\n return containsInnerNewline(parsed || '');\n } catch {\n return false;\n }\n }, [codeStr]);\n\n const finalCodeStr = showAsMultilineText ? codeStr?.replace(/\\\\n/g, '\\n') : codeStr;\n const expandedFinalCodeStr = expandedMultiline ? codeStr?.replace(/\\\\n/g, '\\n') : codeStr;\n const usePlainTextView = simplified || showAsMultilineText;\n\n if (!codeStr || codeStr === 'null') return null;\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n <div className=\"flex items-center justify-between\">\n <DataPanelSectionHeading icon={icon}>{title}</DataPanelSectionHeading>\n <div className=\"flex items-center gap-2\">\n {actions}\n {!usePlainTextView &&\n (searchMinimized ? (\n <Button\n size=\"icon-sm\"\n aria-label=\"Search code\"\n tooltip=\"Search code\"\n onClick={() => setSearchMinimized(false)}\n >\n <SearchIcon />\n </Button>\n ) : (\n <SearchInput\n label=\"Search code\"\n placeholder=\"Search...\"\n size=\"sm\"\n value={searchQuery}\n onValueChange={setSearchQuery}\n onClose={() => setSearchMinimized(true)}\n autoFocus\n />\n ))}\n <ButtonsGroup size=\"sm\">\n <CopyButton content={codeStr || 'No content'} />\n {hasMultilineText && (\n <Button\n size=\"icon-md\"\n aria-label={showAsMultilineText ? 'Show escaped newlines' : 'Show multiline text'}\n tooltip={showAsMultilineText ? 'Show escaped newlines' : 'Show multiline text'}\n onClick={() => setShowAsMultilineText(v => !v)}\n >\n {showAsMultilineText ? <AlignLeftIcon /> : <AlignJustifyIcon />}\n </Button>\n )}\n <Button size=\"icon-md\" aria-label=\"Expand\" tooltip=\"Expand\" onClick={() => setExpandedOpen(true)}>\n <ExpandIcon />\n </Button>\n </ButtonsGroup>\n </div>\n </div>\n\n <div\n className={cn(\n raisedSurfaceStyle,\n 'max-h-[30vh] overflow-hidden overflow-y-auto rounded-lg p-3 text-caption break-all text-muted-foreground',\n )}\n >\n {usePlainTextView ? (\n <div className=\"font-mono break-all text-muted-foreground\">\n <pre className=\"text-wrap\">{finalCodeStr}</pre>\n </div>\n ) : (\n <CodeView code={codeStr} changed={changed} diffSide={diff?.side} searchQuery={searchQuery} />\n )}\n </div>\n\n <Dialog open={expandedOpen} onOpenChange={setExpandedOpen}>\n <DialogContent size=\"full\">\n <DialogHeader>\n <div className=\"flex min-w-0 items-center justify-between gap-2\">\n <DialogTitle className=\"flex min-w-0 items-center gap-1.5 truncate [&>svg]:size-3.5\">\n {dialogTitle ?? (\n <>\n {icon}\n {title}\n </>\n )}\n </DialogTitle>\n <div className=\"flex shrink-0 items-center gap-2\">\n {!expandedMultiline && (\n <SearchInput\n label=\"Search code\"\n placeholder=\"Search...\"\n size=\"sm\"\n value={expandedSearchQuery}\n onValueChange={setExpandedSearchQuery}\n />\n )}\n <ButtonsGroup size=\"sm\">\n <CopyButton content={codeStr || 'No content'} />\n {hasMultilineText && (\n <Button\n size=\"icon-md\"\n aria-label={expandedMultiline ? 'Show escaped newlines' : 'Show multiline text'}\n tooltip={expandedMultiline ? 'Show escaped newlines' : 'Show multiline text'}\n onClick={() => setExpandedMultiline(v => !v)}\n >\n {expandedMultiline ? <AlignLeftIcon /> : <AlignJustifyIcon />}\n </Button>\n )}\n </ButtonsGroup>\n </div>\n </div>\n </DialogHeader>\n <DialogBody layout=\"fill\">\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {expandedMultiline ? (\n <div className={cn(raisedSurfaceStyle, 'rounded-lg p-3 text-caption break-all text-muted-foreground')}>\n <div className=\"font-mono break-all text-muted-foreground\">\n <pre className=\"text-wrap\">{expandedFinalCodeStr}</pre>\n </div>\n </div>\n ) : (\n <CodeView code={codeStr} changed={changed} diffSide={diff?.side} searchQuery={expandedSearchQuery} />\n )}\n </div>\n </DialogBody>\n </DialogContent>\n </Dialog>\n </div>\n );\n}\n\nfunction containsInnerNewline(obj: unknown): boolean {\n if (typeof obj === 'string') {\n const idx = obj.indexOf('\\n');\n return idx !== -1 && idx !== obj.length - 1;\n } else if (Array.isArray(obj)) {\n return obj.some(item => containsInnerNewline(item));\n } else if (obj && typeof obj === 'object') {\n return Object.values(obj).some(value => containsInnerNewline(value));\n }\n return false;\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"FilterBar-BO-vvvyq.js","names":["_Fragment","_Fragment"],"sources":["../src/ds/components/FilterBar/filter-bar-input.tsx","../src/ds/components/FilterBar/use-settle-on-leave.ts","../src/ds/components/FilterBar/filter-bar-group-editor.tsx","../src/ds/components/FilterBar/filter-bar-advanced-chip.tsx","../src/ds/components/FilterBar/filter-bar-clear.tsx","../src/ds/components/FilterBar/filter-bar.tsx","../src/ds/components/FilterBar/default-operators.ts"],"sourcesContent":["import type { BaseUIEvent } from '@base-ui/react/types';\nimport { BracesIcon, ListFilterIcon } from 'lucide-react';\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { KeyboardEvent } from 'react';\nimport { flushSync } from 'react-dom';\nimport { FILTER_BAR_CONTROL_SIZE, FilterBarFieldLabel, alwaysHighlightProps } from './filter-bar-chip';\nimport { useFilterBarContext } from './filter-bar-context';\nimport { FilterBarOptionLabel, FilterBarOptionList } from './filter-bar-option-list';\nimport { findGroup } from './filter-bar-tree';\nimport { matchesQueryFilter } from './match-query';\nimport type { FilterBarDraft, FilterBarField, FilterBarOperator, FilterBarOption, FilterBarValue } from './types';\nimport { parseFieldValue } from './types';\nimport { useValueStep } from './use-value-step';\nimport { Button } from '@/ds/components/Button/Button';\nimport { ComboboxPrimitive, comboboxStyles } from '@/ds/components/Combobox';\nimport { comboboxTriggerClass } from '@/ds/components/Combobox/combobox-styles';\nimport { Kbd } from '@/ds/components/Kbd/kbd';\nimport { Txt } from '@/ds/components/Txt';\nimport { FLOATING_POSITION_METHOD } from '@/ds/primitives/floating';\nimport { inputFocusBorderWithin, unstyledFormElementStyle } from '@/ds/primitives/form-element';\nimport { MENU_SIDE_OFFSET } from '@/ds/primitives/menu-item';\nimport { passwordManagerOptOutProps } from '@/ds/primitives/password-manager-autofill';\nimport { usePortalContainer } from '@/ds/primitives/portal-container';\nimport { useIsApplePlatform } from '@/hooks/use-keyboard-shortcut-label';\nimport { cn } from '@/lib/utils';\n\ntype Step = 'field' | 'operator' | 'value';\n\ntype Item = FilterBarField | FilterBarOperator | FilterBarOption;\n\nconst getItemLabel = (item: Item) => ('label' in item && item.label ? item.label : 'value' in item ? item.value : '');\n\nconst EMPTY_ITEMS: readonly Item[] = [];\n/** Pinned last entry of the field list that spawns an advanced filter (an `or` group) instead of a filter. */\nconst ADVANCED_FIELD_ID = '__filter-bar-advanced__';\nconst ADVANCED_FIELD: FilterBarField = {\n id: ADVANCED_FIELD_ID,\n label: 'Advanced filter…',\n icon: BracesIcon,\n operators: [],\n};\n\nexport type FilterBarInputProps = {\n placeholder?: string;\n className?: string;\n 'aria-label'?: string;\n /**\n * Group this instance commits into; omit for the bar's own input. Only the instance whose\n * `groupId` matches the provider's `inputTarget` renders, so a single input is ever mounted.\n */\n groupId?: string;\n /** Called when Escape is pressed on an empty query inside a group, after the input hands back to the bar. */\n onLeave?: () => void;\n};\n\n/**\n * Typeahead entry point: type to pick a field, then an operator, then a value.\n * Focus never leaves the input; the popup is driven with the arrow keys.\n */\nexport function FilterBarInput(props: FilterBarInputProps) {\n const ctx = useFilterBarContext();\n if (ctx.inputTarget !== props.groupId) return null;\n return <FilterBarInputImpl {...props} />;\n}\n\nfunction FilterBarInputImpl({\n placeholder = 'Filter…',\n className,\n 'aria-label': ariaLabel = 'Add filter',\n groupId,\n onLeave,\n}: FilterBarInputProps) {\n const ctx = useFilterBarContext();\n const container = usePortalContainer();\n const inputRef = useRef<HTMLInputElement | null>(null);\n const anchorRef = useRef<HTMLDivElement>(null);\n const [open, setOpen] = useState(false);\n const [query, setQuery] = useState('');\n const [highlighted, setHighlighted] = useState<Item | null>(null);\n const [emptyForStepChange, setEmptyForStepChange] = useState(false);\n const modEnterLabel = useIsApplePlatform() ? '⌘↵' : 'Ctrl ↵';\n\n // The draft lives in the provider so the chip list can render it; the step follows from it.\n const { draft, setDraft: setDraftState, commitDraft } = ctx;\n const step: Step = !draft ? 'field' : !draft.operatorId ? 'operator' : 'value';\n const field = draft ? ctx.getField(draft.fieldId) : undefined;\n const fieldOperators = useMemo(() => (field ? ctx.getFieldOperators(field) : []), [ctx, field]);\n const operator = draft?.operatorId\n ? (fieldOperators.find(o => o.id === draft.operatorId) ?? ctx.getOperator(draft.operatorId))\n : undefined;\n // The advanced option lives in the bar only; inside a popover, nesting is the editor's `+ Group`.\n const offerAdvanced = ctx.groupsEnabled && groupId === undefined;\n const visibleFields = useMemo(() => {\n const fields = ctx.fields.filter(f => !f.hidden);\n return offerAdvanced ? [...fields, ADVANCED_FIELD] : fields;\n }, [ctx.fields, offerAdvanced]);\n const targetGroup = groupId ? findGroup(ctx.expression, groupId) : undefined;\n\n // A group's input mounts on demand (see `openGroupInput`) and takes focus itself.\n useEffect(() => {\n if (groupId) inputRef.current?.focus();\n }, [groupId]);\n\n // Base UI owns the highlight index and keeps it when the list content changes, so a row\n // reached with ArrowDown would carry over into the step that follows. An empty list committed\n // first drops that index, and `autoHighlight` re-anchors on the first row of the new step.\n const withHighlightReset = useCallback((change: () => void) => {\n flushSync(() => setEmptyForStepChange(true));\n change();\n setEmptyForStepChange(false);\n }, []);\n\n const setDraft = useCallback(\n (next: Omit<FilterBarDraft, 'id' | 'from'> | null) => withHighlightReset(() => setDraftState(next)),\n [withHighlightReset, setDraftState],\n );\n\n const reset = useCallback(() => {\n setDraftState(null);\n setQuery('');\n }, [setDraftState]);\n\n const close = useCallback(() => {\n setOpen(false);\n reset();\n }, [reset]);\n\n const commit = useCallback(\n (fieldId: string, operatorId: string, value: FilterBarValue) => {\n withHighlightReset(() => commitDraft({ fieldId, operatorId }, value));\n setQuery('');\n inputRef.current?.focus();\n },\n [withHighlightReset, commitDraft],\n );\n\n const selectOperator = useCallback(\n (fieldId: string, next: FilterBarOperator) => {\n if (next.arity === 'none') {\n commit(fieldId, next.id, '');\n return;\n }\n setDraft({ fieldId, operatorId: next.id });\n setQuery('');\n },\n [commit, setDraft],\n );\n\n const selectField = useCallback(\n (next: FilterBarField) => {\n if (next.id === ADVANCED_FIELD_ID) {\n // `or` is the useful default: an `and` group is indistinguishable from the root.\n const id = ctx.addGroup(undefined, 'or');\n ctx.setOpenGroup(id);\n ctx.openGroupInput(id);\n setQuery('');\n setOpen(false);\n return;\n }\n const [only, ...rest] = ctx.getFieldOperators(next);\n // Free-text entry with text already typed: that text is the value, so neither the\n // operator nor the value step has anything left to ask.\n if (next.search && only && query.trim() !== '') {\n commit(next.id, only.id, parseFieldValue(next.type, query));\n return;\n }\n // A single allowed operator is implied: skip straight to the value step.\n if (only && rest.length === 0) {\n selectOperator(next.id, only);\n return;\n }\n setDraft({ fieldId: next.id });\n setQuery('');\n },\n [ctx, commit, query, selectOperator, setDraft],\n );\n\n const valueStep = useValueStep({\n field,\n operator,\n query,\n enabled: open && step === 'value',\n setQuery,\n onCommit: value => {\n if (draft?.operatorId) commit(draft.fieldId, draft.operatorId, value);\n },\n });\n\n // Leaving a group's input hands the target back to the bar; empty groups are pruned when the\n // popover closes, never here.\n const leaveGroup = useCallback(() => {\n if (!groupId) return false;\n ctx.openGroupInput(undefined);\n onLeave?.();\n return true;\n }, [ctx, groupId, onLeave]);\n\n const stepBack = useCallback(() => {\n if (step === 'value' && draft) {\n // Back to the field step when the operator was implied (single operator).\n const skipOperator = field ? fieldOperators.length === 1 : false;\n setDraft(skipOperator ? null : { fieldId: draft.fieldId });\n } else if (step === 'operator') setDraft(null);\n else if (!leaveGroup()) setOpen(false);\n setQuery('');\n }, [step, draft, field, fieldOperators, setDraft, leaveGroup]);\n\n // Selection is routed per step and never kept by Base UI (`value` stays null).\n const handleSelect = (item: Item) => {\n if (step === 'field') selectField(item as FilterBarField);\n else if (step === 'operator' && draft) selectOperator(draft.fieldId, item as FilterBarOperator);\n else valueStep.handleSelect(item as FilterBarOption);\n };\n\n // App-level keys run before Base UI's own input handling.\n const handleKeyDown = (event: BaseUIEvent<KeyboardEvent<HTMLInputElement>>) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n // Consumed here: an enclosing popover (advanced filter) must not close on it.\n event.stopPropagation();\n event.preventBaseUIHandler();\n stepBack();\n return;\n }\n if (!open && (event.key === 'ArrowDown' || event.key === 'Enter')) {\n event.preventDefault();\n event.preventBaseUIHandler();\n setOpen(true);\n return;\n }\n if (query === '') {\n if (event.key === 'Backspace') {\n event.preventDefault();\n event.preventBaseUIHandler();\n if (step !== 'field') stepBack();\n else if (targetGroup) {\n // Inside a group: eat its last chip, or drop the group once it is empty.\n const last = targetGroup.nodes.findLast(node => !ctx.leaving.has(node.id));\n if (last) ctx.removeItem(last.id);\n else leaveGroup();\n } else {\n // Chips still animating out are already gone from the value: skip them.\n const last = ctx.items.findLast(item => !ctx.leaving.has(item.id));\n if (last) ctx.removeItem(last.id);\n }\n return;\n }\n if (event.key === 'ArrowLeft' && step === 'field') {\n if (ctx.focusChip(ctx.items.length - 1, -1, 'remove')) event.preventDefault();\n return;\n }\n }\n if (!open) return;\n\n if (event.key === 'Tab' && highlighted && step !== 'value' && (step === 'operator' || query !== '')) {\n event.preventDefault();\n event.preventBaseUIHandler();\n handleSelect(highlighted);\n return;\n }\n if (step === 'value') {\n const highlightedOption = valueStep.hasSuggestions ? (highlighted as FilterBarOption | null) : null;\n const handled = valueStep.handleKeyDown(event, highlightedOption);\n // Base UI closes on Enter when nothing is highlighted (form submission); the draft must stay open.\n if (handled || (event.key === 'Enter' && highlightedOption === null)) event.preventBaseUIHandler();\n }\n };\n\n const optionsForStep: Record<Step, readonly Item[]> = {\n field: visibleFields,\n operator: fieldOperators,\n value: valueStep.options,\n };\n const items: readonly Item[] = emptyForStepChange ? EMPTY_ITEMS : optionsForStep[step];\n\n // A search field is the way out for text that names no field, so it survives the field\n // step's own filtering whatever was typed; every other item matches on its label.\n const filterItem = useCallback(\n (item: Item, text: string, itemToString?: (item: Item) => string) =>\n ('search' in item && item.search === true) || matchesQueryFilter(item, text, itemToString),\n [],\n );\n\n const inputPlaceholder =\n step === 'field'\n ? placeholder\n : step === 'operator'\n ? 'Operator…'\n : valueStep.hasSuggestions && valueStep.allowFreeText\n ? 'Search or type a value…'\n : field?.type === 'number'\n ? 'Number…'\n : 'Value…';\n\n return (\n <>\n <ComboboxPrimitive.Root<Item>\n items={items}\n itemToStringLabel={getItemLabel}\n // The value step is already filtered (locally or server-side) by useValueSuggestions.\n filter={step === 'value' ? null : filterItem}\n value={null}\n onValueChange={(item, details) => {\n // Never let Base UI keep the selection, fill the input or close: each step routes it.\n details.cancel();\n if (item) handleSelect(item);\n }}\n inputValue={query}\n onInputValueChange={(next, details) => {\n if (details.reason !== 'input-change') return;\n setQuery(next);\n if (!open) setOpen(true);\n }}\n onItemHighlighted={item => setHighlighted(item ?? null)}\n open={open}\n onOpenChange={(next, details) => {\n // Escape is handled by the input (it steps back rather than closing).\n if (!next && details.reason === 'escape-key') return;\n // The input is the anchor, not a trigger: clicking it must keep the draft open.\n if (\n !next &&\n details.reason === 'outside-press' &&\n details.event.target instanceof Node &&\n inputRef.current?.contains(details.event.target)\n ) {\n return;\n }\n if (next) setOpen(true);\n else close();\n }}\n {...alwaysHighlightProps}\n modal={false}\n >\n <div\n ref={anchorRef}\n data-slot=\"filter-bar-input-trigger\"\n className={cn(\n // Same trigger recipe as every other DS Combobox (fill, radius, `[&>svg]` icon sizing\n // and the Button icon offset); the bar itself has no chrome. Focus lives on the\n // nested input, so the recipe's `focus-visible` border becomes `focus-within`.\n comboboxTriggerClass({ variant: 'default', size: FILTER_BAR_CONTROL_SIZE }),\n 'w-auto cursor-text',\n 'focus-within:bg-fill-hover',\n inputFocusBorderWithin,\n step === 'field' ? 'min-w-40' : 'min-w-28',\n className,\n )}\n >\n <ListFilterIcon aria-hidden className=\"shrink-0\" />\n <ComboboxPrimitive.Input\n ref={el => {\n inputRef.current = el;\n ctx.registerInput(el);\n }}\n aria-label={ariaLabel}\n spellCheck={false}\n {...passwordManagerOptOutProps}\n data-slot=\"filter-bar-input\"\n data-step={step}\n data-target={targetGroup?.id}\n inputMode={step === 'value' && field?.type === 'number' ? 'decimal' : undefined}\n placeholder={inputPlaceholder}\n className={cn(\n unstyledFormElementStyle,\n 'min-w-0 flex-1 bg-transparent',\n 'placeholder:text-muted-foreground placeholder:transition-opacity placeholder:duration-normal focus:placeholder:opacity-70',\n )}\n onFocus={() => setOpen(true)}\n onKeyDown={handleKeyDown}\n />\n </div>\n <ComboboxPrimitive.Portal container={container}>\n <ComboboxPrimitive.Positioner\n // Base UI anchors to the input, which starts after the filter icon; align with the pill instead.\n anchor={anchorRef}\n align=\"start\"\n sideOffset={MENU_SIDE_OFFSET}\n positionMethod={FLOATING_POSITION_METHOD}\n className={comboboxStyles.positioner}\n >\n <ComboboxPrimitive.Popup // Match the pill, with the DS Combobox's 11rem floor (replaces the menu's anchor-width minimum).\n className={cn(comboboxStyles.popup, 'w-(--anchor-width) min-w-44')}\n data-slot=\"filter-bar-editor\"\n >\n {step === 'field' && (\n <FilterBarOptionList<FilterBarField>\n aria-label=\"Fields\"\n getKey={f => f.id}\n renderOption={f => (\n <>\n <FilterBarFieldLabel field={f} />\n {f.search && query !== '' && (\n <span className=\"min-w-0 truncate text-muted-foreground\">\n {ctx.getFieldOperators(f)[0]?.label} \"{query}\"\n </span>\n )}\n </>\n )}\n emptyText=\"No matching field.\"\n />\n )}\n {step === 'operator' && (\n <FilterBarOptionList<FilterBarOperator>\n aria-label=\"Operators\"\n getKey={o => o.id}\n renderOption={o => o.label}\n emptyText=\"No matching operator.\"\n />\n )}\n {step === 'value' && valueStep.hasOptions && (\n <FilterBarOptionList<FilterBarOption>\n aria-label=\"Values\"\n aria-multiselectable={valueStep.isMany || undefined}\n getKey={o => o.value}\n renderOption={option => <FilterBarOptionLabel option={option} />}\n isSelected={o => valueStep.isMany && valueStep.selected.includes(o.value)}\n isLoading={valueStep.isLoading}\n error={valueStep.error}\n emptyText={\n valueStep.allowFreeText ? 'No suggestions — press Enter to use your text.' : 'No matching value.'\n }\n />\n )}\n {step === 'value' && !valueStep.hasSuggestions && (\n <div className=\"flex items-center justify-between gap-2 py-1 pr-1 pl-[.9em]\">\n <Txt variant=\"caption\" tone=\"muted\">\n Type a value\n </Txt>\n <Button\n size=\"sm\"\n variant=\"default\"\n disabled={!valueStep.canCommitQuery}\n onMouseDown={e => e.preventDefault()}\n onClick={() => valueStep.submitFreeText()}\n >\n Apply\n <Kbd size=\"xs\">↵</Kbd>\n </Button>\n </div>\n )}\n {step === 'value' && valueStep.isMany && (\n <div className=\"flex items-center justify-end gap-1 border-t border-border p-1\">\n <Button\n size=\"sm\"\n variant=\"default\"\n onMouseDown={e => e.preventDefault()}\n onClick={() => valueStep.commitDone()}\n >\n Done\n <Kbd size=\"xs\">{modEnterLabel}</Kbd>\n </Button>\n </div>\n )}\n </ComboboxPrimitive.Popup>\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n </ComboboxPrimitive.Root>\n </>\n );\n}\n","import { useEffect } from 'react';\nimport { useFilterBarContext } from './filter-bar-context';\n\n/** Keeps a leaving node in the DOM until its exit animation has played, then releases it. */\nexport function useSettleOnLeave(id: string, leaving: boolean, rootRef: React.RefObject<HTMLElement | null>) {\n const { settleRemove } = useFilterBarContext();\n useEffect(() => {\n const root = rootRef.current;\n if (!leaving || !root) return;\n const animations = typeof root.getAnimations === 'function' ? root.getAnimations({ subtree: true }) : [];\n if (animations.length === 0) {\n settleRemove(id);\n return;\n }\n let cancelled = false;\n Promise.all(animations.map(animation => animation.finished))\n .then(() => {\n if (!cancelled) settleRemove(id);\n })\n .catch(() => {});\n return () => {\n cancelled = true;\n };\n }, [leaving, id, settleRemove, rootRef]);\n}\n","import { FolderIcon, FolderPlusIcon, PlusIcon, Trash2Icon } from 'lucide-react';\nimport { Fragment, useEffect, useRef } from 'react';\nimport type { ReactNode } from 'react';\nimport { FilterBarChip } from './filter-bar-chip';\nimport { useFilterBarContext } from './filter-bar-context';\nimport { FilterBarInput } from './filter-bar-input';\nimport { countLeaves } from './filter-bar-tree';\nimport type { FilterBarGroup, FilterBarLogic } from './types';\nimport { isFilterBarGroup } from './types';\nimport { useSettleOnLeave } from './use-settle-on-leave';\nimport { Button } from '@/ds/components/Button/Button';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/lib/utils';\n\nconst connectorClass =\n 'flex h-control-sm w-14 shrink-0 items-center justify-center rounded-md text-column tracking-wide text-muted-foreground uppercase';\n\nexport type FilterBarLogicToggleProps = {\n groupId: string;\n logic: FilterBarLogic;\n className?: string;\n};\n\n/** `and` / `or` connector in front of a row; every connector of a group shares its logic. */\nexport function FilterBarLogicToggle({ groupId, logic, className }: FilterBarLogicToggleProps) {\n const ctx = useFilterBarContext();\n const next: FilterBarLogic = logic === 'and' ? 'or' : 'and';\n return (\n <button\n type=\"button\"\n data-slot=\"filter-bar-logic\"\n data-logic={logic}\n aria-label={`Joined with ${logic}, switch to ${next}`}\n title={`Switch to ${next}`}\n className={cn(\n connectorClass,\n 'filter-bar-logic cursor-pointer border border-border bg-fill-subtle outline-none',\n 'hover:bg-fill-hover hover:text-foreground focus-visible:bg-fill-hover focus-visible:text-foreground',\n className,\n )}\n onClick={() => ctx.setLogic(groupId, next)}\n >\n {logic}\n </button>\n );\n}\n\n/** Segmented `and | or` control shown in a nested group's header. */\nfunction FilterBarLogicSwitch({ groupId, logic }: { groupId: string; logic: FilterBarLogic }) {\n const ctx = useFilterBarContext();\n return (\n <div\n role=\"radiogroup\"\n aria-label=\"Group logic\"\n className=\"flex h-control-sm items-center gap-0.5 rounded-md border border-border bg-fill-subtle p-0.5\"\n >\n {(['and', 'or'] as const).map(value => (\n <button\n key={value}\n type=\"button\"\n role=\"radio\"\n aria-checked={logic === value}\n aria-label={`Join with ${value}`}\n className={cn(\n 'h-full cursor-pointer rounded-sm px-1.5 text-column tracking-wide uppercase outline-none',\n 'focus-visible:bg-fill-hover',\n logic === value ? 'bg-fill-hover text-foreground' : 'text-muted-foreground hover:text-foreground',\n )}\n onClick={() => logic !== value && ctx.setLogic(groupId, value)}\n >\n {value}\n </button>\n ))}\n </div>\n );\n}\n\nexport type FilterBarGroupEditorProps = {\n group: FilterBarGroup;\n /** Nesting level of `group` (root-level group = 1). */\n depth: number;\n /** Drops this group; rendered as a trailing `Clear all` in the footer. */\n onRemove?: () => void;\n removeLabel?: string;\n className?: string;\n};\n\n/**\n * Recursive rule builder shown in an advanced-filter popover. Rows are laid out as\n * `connector | condition`: the first row reads `where`, the following ones carry the\n * group's `and` / `or` toggle. Nested groups render as bordered cards with their own\n * header (logic switch + remove) and footer. The shared typeahead input renders as the\n * last row of the group it is pointed at.\n */\nexport function FilterBarGroupEditor({\n group,\n depth,\n onRemove,\n removeLabel = 'Remove group',\n className,\n}: FilterBarGroupEditorProps) {\n const ctx = useFilterBarContext();\n const addFilterRef = useRef<HTMLButtonElement>(null);\n const focusAddFilter = useRef(false);\n const targeted = ctx.inputTarget === group.id;\n const canNest = depth < ctx.maxDepth;\n\n // `+ Condition` is hidden while the input is open; focus it once it remounts.\n useEffect(() => {\n if (targeted || !focusAddFilter.current) return;\n focusAddFilter.current = false;\n addFilterRef.current?.focus();\n }, [targeted]);\n\n const rows: ReactNode[] = [];\n const connector = (key: string) =>\n rows.length === 0 ? (\n <span key={`${key}:where`} className={connectorClass}>\n where\n </span>\n ) : (\n <FilterBarLogicToggle key={`${key}:logic`} groupId={group.id} logic={group.logic} />\n );\n for (const node of group.nodes) {\n rows.push(\n <Fragment key={node.id}>\n {connector(node.id)}\n {isFilterBarGroup(node) ? (\n <NestedGroupCard group={node} depth={depth + 1} />\n ) : (\n <FilterBarChip item={node} className=\"w-fit\" />\n )}\n </Fragment>,\n );\n }\n if (ctx.draft && ctx.draft.groupId === group.id) {\n const { id, fieldId, operatorId = '' } = ctx.draft;\n rows.push(\n <Fragment key={id}>\n {connector(id)}\n <FilterBarChip draft item={{ id, fieldId, operatorId, value: '' }} className=\"w-fit\" />\n </Fragment>,\n );\n }\n if (targeted) {\n rows.push(\n <Fragment key=\"input\">\n {connector('input')}\n <FilterBarInput\n groupId={group.id}\n placeholder=\"Add condition…\"\n onLeave={() => {\n focusAddFilter.current = true;\n }}\n />\n </Fragment>,\n );\n }\n\n return (\n <div\n data-slot=\"filter-bar-group-editor\"\n data-depth={depth}\n role=\"group\"\n aria-label={`Conditions joined with ${group.logic}`}\n className={cn('flex min-w-0 flex-col', className)}\n >\n {rows.length > 0 && (\n <div className=\"grid grid-cols-[auto_minmax(0,1fr)] items-start gap-x-2 gap-y-1.5 p-2\">{rows}</div>\n )}\n <div\n data-slot=\"filter-bar-editor-actions\"\n className={cn('flex w-full items-center gap-1 p-1', rows.length > 0 && 'border-t border-border')}\n >\n {!targeted && (\n <Button\n ref={addFilterRef}\n variant=\"ghost\"\n size=\"sm\"\n icon={<PlusIcon />}\n onClick={() => ctx.openGroupInput(group.id)}\n >\n Condition\n </Button>\n )}\n <Button\n variant=\"ghost\"\n size=\"sm\"\n icon={<FolderPlusIcon />}\n className=\"text-muted-foreground\"\n tooltip={canNest ? undefined : `Groups can nest ${ctx.maxDepth} levels deep`}\n disabled={!canNest}\n onClick={() => ctx.addGroup(group.id, group.logic === 'and' ? 'or' : 'and')}\n >\n Group\n </Button>\n {onRemove && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n icon={<Trash2Icon />}\n className=\"ml-auto text-muted-foreground\"\n aria-label={removeLabel}\n onClick={onRemove}\n >\n Clear all\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nfunction NestedGroupCard({ group, depth }: { group: FilterBarGroup; depth: number }) {\n const ctx = useFilterBarContext();\n const rootRef = useRef<HTMLDivElement>(null);\n const leaving = ctx.leaving.has(group.id);\n useSettleOnLeave(group.id, leaving, rootRef);\n const count = countLeaves(group);\n\n return (\n <div\n ref={rootRef}\n data-slot=\"filter-bar-editor-nested\"\n data-leaving={leaving || undefined}\n aria-hidden={leaving || undefined}\n className={cn(\n 'filter-bar-editor-nested w-full overflow-hidden rounded-lg border border-border',\n leaving && 'pointer-events-none',\n )}\n >\n <div className=\"flex items-center gap-2 border-b border-border px-2 py-1\">\n <FolderIcon className=\"size-3.5 text-muted-foreground\" />\n <Txt as=\"span\" variant=\"label\" tone=\"ink\">\n Group\n </Txt>\n <Txt as=\"span\" variant=\"label\" tone=\"muted\">\n · {count} {count === 1 ? 'condition' : 'conditions'}\n </Txt>\n <div className=\"ml-auto flex items-center gap-1\">\n <FilterBarLogicSwitch groupId={group.id} logic={group.logic} />\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n tooltip=\"Remove group\"\n disabled={leaving}\n onClick={() => ctx.removeGroup(group.id)}\n >\n <Trash2Icon />\n </Button>\n </div>\n </div>\n <FilterBarGroupEditor group={group} depth={depth} />\n </div>\n );\n}\n","import { BracesIcon, XIcon } from 'lucide-react';\nimport { useRef, useState } from 'react';\nimport type { KeyboardEvent } from 'react';\nimport { chipClass, editableSegmentClass, removeSegmentClass } from './filter-bar-chip';\nimport { FILTER_BAR_SCOPE_ATTR, useFilterBarContext } from './filter-bar-context';\nimport { FilterBarGroupEditor } from './filter-bar-group-editor';\nimport { countLeaves } from './filter-bar-tree';\nimport type { FilterBarGroup } from './types';\nimport { useSettleOnLeave } from './use-settle-on-leave';\nimport { Button } from '@/ds/components/Button/Button';\nimport { Popover, PopoverContent, PopoverTrigger } from '@/ds/components/Popover';\nimport { Txt } from '@/ds/components/Txt';\nimport { cn } from '@/lib/utils';\n\nexport type FilterBarAdvancedChipProps = {\n group: FilterBarGroup;\n className?: string;\n};\n\n/**\n * A root-level group rendered as one \"Advanced filter\" chip. Its popover hosts the\n * recursive rule builder; the chip's remove button drops the whole subtree.\n */\nexport function FilterBarAdvancedChip({ group, className }: FilterBarAdvancedChipProps) {\n const ctx = useFilterBarContext();\n const [initial] = useState(() => !ctx.mounted);\n const rootRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const leaving = ctx.leaving.has(group.id);\n const open = ctx.openGroupId === group.id;\n const count = countLeaves(group);\n // Position in the flattened item list: navigation from the chip continues from its first leaf.\n const firstLeafIndex = ctx.items.findIndex(item => isUnder(group, item.id));\n const index = firstLeafIndex === -1 ? ctx.items.length : firstLeafIndex;\n useSettleOnLeave(group.id, leaving, rootRef);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (leaving) return;\n const segments = Array.from(rootRef.current?.querySelectorAll<HTMLElement>('[data-filter-bar-segment]') ?? []);\n const current = segments.findIndex(el => el === event.target);\n if (current === -1) return;\n switch (event.key) {\n case 'ArrowRight': {\n event.preventDefault();\n const next = segments[current + 1];\n if (next) next.focus();\n else if (!ctx.focusChip(index + count, 1, 'field')) ctx.focusInput();\n return;\n }\n case 'ArrowLeft': {\n event.preventDefault();\n const prev = segments[current - 1];\n if (prev) prev.focus();\n else ctx.focusChip(index - 1, -1, 'remove');\n return;\n }\n case 'Delete':\n case 'Backspace':\n event.preventDefault();\n remove();\n break;\n default:\n }\n };\n\n const remove = () => {\n ctx.removeGroup(group.id);\n ctx.focusAfterRemove(index);\n };\n\n return (\n <Popover open={open} onOpenChange={next => ctx.setOpenGroup(next ? group.id : null)}>\n <div\n ref={rootRef}\n role=\"group\"\n aria-label={`Advanced filter, ${count} ${count === 1 ? 'condition' : 'conditions'}`}\n aria-hidden={leaving || undefined}\n data-slot=\"filter-bar-advanced\"\n data-initial={initial || undefined}\n data-leaving={leaving || undefined}\n className={cn('filter-bar-advanced', chipClass, leaving && 'pointer-events-none', className)}\n onKeyDown={handleKeyDown}\n >\n <PopoverTrigger\n ref={el => {\n triggerRef.current = el;\n ctx.registerSegment(group.id, 'field', leaving ? null : el);\n }}\n render={<button type=\"button\" />}\n data-filter-bar-segment=\"field\"\n className={editableSegmentClass}\n title=\"Edit advanced filter\"\n >\n <BracesIcon aria-hidden />\n <span className=\"truncate\">Advanced filter</span>\n {count > 0 && (\n <Txt as=\"span\" variant=\"column\" tone=\"muted\" aria-hidden>\n {count}\n </Txt>\n )}\n </PopoverTrigger>\n {leaving ? (\n <span aria-hidden className={removeSegmentClass}>\n <XIcon />\n </span>\n ) : (\n <button\n type=\"button\"\n ref={el => ctx.registerSegment(group.id, 'remove', el)}\n data-filter-bar-segment=\"remove\"\n aria-label=\"Remove advanced filter\"\n title=\"Remove advanced filter\"\n className={removeSegmentClass}\n onClick={remove}\n >\n <XIcon />\n </button>\n )}\n </div>\n <PopoverContent\n align=\"start\"\n className=\"w-[min(92vw,44rem)] p-0\"\n {...{ [FILTER_BAR_SCOPE_ATTR]: 'advanced' }}\n finalFocus={triggerRef}\n >\n <div className=\"flex items-center gap-2 border-b border-border px-3 py-2\">\n <BracesIcon className=\"size-3.5 text-muted-foreground\" />\n <Txt as=\"span\" variant=\"label\" tone=\"ink\">\n Advanced filter\n </Txt>\n <Txt as=\"span\" variant=\"column\" tone=\"muted\" className=\"rounded-md bg-fill-subtle px-1.5\">\n {count}\n </Txt>\n <Button\n variant=\"ghost\"\n size=\"icon-sm\"\n className=\"ml-auto\"\n tooltip=\"Close\"\n onClick={() => ctx.setOpenGroup(null)}\n >\n <XIcon />\n </Button>\n </div>\n <FilterBarGroupEditor\n group={group}\n depth={1}\n removeLabel=\"Remove advanced filter\"\n onRemove={() => {\n ctx.setOpenGroup(null);\n remove();\n }}\n />\n </PopoverContent>\n </Popover>\n );\n}\n\nconst isUnder = (group: FilterBarGroup, itemId: string): boolean =>\n group.nodes.some(node => (node.id === itemId ? true : 'kind' in node && isUnder(node, itemId)));\n","import { useFilterBarContext } from './filter-bar-context';\nimport { ClearFiltersButton } from '@/ds/components/ClearFiltersButton/clear-filters-button';\n\n/** Removes every removable filter. Rendered by FilterBar at its trailing edge; hidden while nothing can be removed. */\nexport function FilterBarClear({ label }: { label: string }) {\n const ctx = useFilterBarContext();\n if (!ctx.hasRemovableItems) return null;\n return (\n <ClearFiltersButton\n label={label}\n onClick={event => {\n event.stopPropagation();\n ctx.clear();\n ctx.focusInput();\n }}\n />\n );\n}\n","import { Fragment } from 'react';\nimport type { ReactNode } from 'react';\nimport { FilterBarAdvancedChip } from './filter-bar-advanced-chip';\nimport { FilterBarChip } from './filter-bar-chip';\nimport { FilterBarClear } from './filter-bar-clear';\nimport { FILTER_BAR_SCOPE_ATTR, FilterBarProvider, useFilterBarContext } from './filter-bar-context';\nimport { FilterBarInput } from './filter-bar-input';\nimport { FilterBarTimeRange } from './filter-bar-time-range';\nimport { isFilterBarGroup } from './types';\nimport type { FilterBarExpression, FilterBarField, FilterBarItem, FilterBarOperator } from './types';\nimport { VisuallyHidden } from '@/ds/primitives/visually-hidden';\nimport { cn } from '@/lib/utils';\n\ntype FilterBarValueProps =\n | {\n /** Flat list of filters, implicitly joined with `and`. Advanced filters are never offered. */\n value: FilterBarItem[];\n onValueChange: (items: FilterBarItem[]) => void;\n }\n | {\n /**\n * Tree of filters and groups. Root nodes are joined with `and`; each root group renders\n * as one \"Advanced filter\" chip whose popover edits the nested `and` / `or` logic.\n */\n value: FilterBarExpression;\n onValueChange: (expression: FilterBarExpression) => void;\n };\n\nexport type FilterBarProps = FilterBarValueProps & {\n fields: FilterBarField[];\n operators: FilterBarOperator[];\n /**\n * Id given to a newly added item. Defaults to a random id. Consumers that rebuild `value` from\n * their own store (URL, query params…) should return the id they will rebuild it with, so the\n * draft chip and the committed chip are the same element.\n */\n createItemId?: (fieldId: string) => string;\n /** How deep advanced-filter groups may nest (root-level group = 1). Defaults to 3. */\n maxDepth?: number;\n 'aria-label'?: string;\n /**\n * Text shown in a value list when the field's `suggestions` resolver rejects, for example\n * to explain a server limit. Return `undefined` to keep the default \"Couldn't load values.\".\n */\n describeSuggestionsError?: (error: unknown) => string | undefined;\n /** Accessible label of the trailing \"remove every filter\" button. */\n clearLabel?: string;\n className?: string;\n children: ReactNode;\n};\n\nfunction FilterBarSurface({\n className,\n clearLabel,\n children,\n}: {\n className?: string;\n clearLabel: string;\n children: ReactNode;\n}) {\n const ctx = useFilterBarContext();\n return (\n <div\n role=\"group\"\n aria-label={ctx.ariaLabel}\n data-slot=\"filter-bar\"\n {...{ [FILTER_BAR_SCOPE_ATTR]: 'bar' }}\n className={cn(\n // No chrome of its own: chips and the typeahead input sit directly on the parent surface.\n // Layout: chips, input, then Clear right beside the input — all in one wrapping row so\n // Clear never drifts to the far edge of a wide container.\n 'flex w-full flex-wrap items-center gap-1.5',\n className,\n )}\n >\n {children}\n <span className=\"flex shrink-0 items-center empty:hidden\">\n <FilterBarClear label={clearLabel} />\n </span>\n <VisuallyHidden aria-live=\"polite\">{ctx.announcement}</VisuallyHidden>\n </div>\n );\n}\n\n/**\n * Braintrust-style filter bar: `field → operator → value` filters built from a\n * single typeahead input, rendered as inline editable chips. Domain-agnostic —\n * fields, operators and values are plain strings supplied by the consumer.\n *\n * Pass a `FilterBarExpression` as `value` to enable Linear-style advanced filters:\n * the input offers \"Advanced filter…\", which adds one chip whose popover hosts a\n * recursive rule builder (`and` / `or` connectors, nested groups). The bar itself\n * stays flat. A flat `FilterBarItem[]` stays flat.\n *\n * @example\n * <FilterBar value={items} onValueChange={setItems} fields={fields} operators={DEFAULT_FILTER_OPERATORS}>\n * <FilterBar.Chips />\n * <FilterBar.Input />\n * </FilterBar>\n */\nexport function FilterBar({\n fields,\n operators,\n value,\n onValueChange,\n createItemId,\n maxDepth,\n 'aria-label': ariaLabel = 'Filters',\n describeSuggestionsError,\n clearLabel = 'Clear filters',\n className,\n children,\n}: FilterBarProps) {\n return (\n <FilterBarProvider\n fields={fields}\n operators={operators}\n value={value}\n onValueChange={onValueChange}\n createItemId={createItemId}\n maxDepth={maxDepth}\n ariaLabel={ariaLabel}\n describeSuggestionsError={describeSuggestionsError}\n >\n <FilterBarSurface className={className} clearLabel={clearLabel}>\n {children}\n </FilterBarSurface>\n </FilterBarProvider>\n );\n}\n\n/**\n * Default layout: one editable chip per root item, one \"Advanced filter\" chip per root\n * group, in order, then the chip of the filter being built in the bar's input (which\n * becomes the last item's chip once committed).\n */\nexport function FilterBarChips({ renderChip = defaultRenderChip }: FilterBarChipsProps) {\n const ctx = useFilterBarContext();\n // One keyed array: the draft chip and the item it becomes share a key, so React\n // keeps the element across the commit instead of mounting a new chip.\n const chips: ReactNode[] = [];\n for (const node of ctx.expression.nodes) {\n const chip = isFilterBarGroup(node) ? <FilterBarAdvancedChip group={node} /> : renderChip(node);\n if (chip !== null) chips.push(<Fragment key={node.id}>{chip}</Fragment>);\n }\n if (ctx.draft && !ctx.draft.groupId) {\n // `FilterBarChip` needs a full item; the draft's missing parts are blank until picked.\n const { id, fieldId, operatorId = '' } = ctx.draft;\n chips.push(\n <Fragment key={id}>\n <FilterBarChip draft item={{ id, fieldId, operatorId, value: '' }} />\n </Fragment>,\n );\n }\n return <>{chips}</>;\n}\n\nexport type FilterBarChipsProps = {\n /**\n * Chip for an item; return `null` to render none (e.g. an item only held in the\n * value for scoping). Defaults to a plain editable `FilterBar.Chip`.\n */\n renderChip?: (item: FilterBarItem) => ReactNode;\n};\n\nconst defaultRenderChip = (item: FilterBarItem) => <FilterBarChip item={item} />;\n\nFilterBar.Chips = FilterBarChips;\nFilterBar.Chip = FilterBarChip;\nFilterBar.AdvancedChip = FilterBarAdvancedChip;\nFilterBar.Input = FilterBarInput;\nFilterBar.TimeRange = FilterBarTimeRange;\n","import type { FilterBarOperator } from './types';\n\n/** Opt-in starter set. Pure data: the component attaches no semantics to ids. */\nexport const DEFAULT_FILTER_OPERATORS: FilterBarOperator[] = [\n { id: 'is', label: 'is', widensTo: 'in' },\n { id: 'is-not', label: 'is not' },\n { id: 'contains', label: 'contains' },\n { id: 'not-contains', label: 'does not contain' },\n { id: 'starts-with', label: 'starts with' },\n { id: 'gt', label: '>' },\n { id: 'lt', label: '<' },\n { id: 'gte', label: '>=' },\n { id: 'lte', label: '<=' },\n { id: 'is-empty', label: 'is empty', arity: 'none' },\n { id: 'is-not-empty', label: 'is not empty', arity: 'none' },\n { id: 'in', label: 'in', arity: 'many' },\n];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8BA,IAAM,gBAAgB,SAAgB,WAAW,QAAQ,KAAK,QAAQ,KAAK,QAAQ,WAAW,OAAO,KAAK,QAAQ;AAElH,IAAM,cAA+B,CAAC;;AAEtC,IAAM,oBAAoB;AAC1B,IAAM,iBAAiC;CACrC,IAAI;CACJ,OAAO;CACP,MAAM;CACN,WAAW,CAAC;AACd;;;;;AAmBA,SAAgB,eAAe,OAA4B;CAEzD,IADY,oBACR,CAAA,CAAI,gBAAgB,MAAM,SAAS,OAAO;CAC9C,OAAO,oBAAC,oBAAD,EAAoB,GAAI,MAAQ,CAAA;AACzC;AAEA,SAAS,mBAAmB,EAC1B,cAAc,WACd,WACA,cAAc,YAAY,cAC1B,SACA,WACsB;CACtB,MAAM,MAAM,oBAAoB;CAChC,MAAM,YAAY,mBAAmB;CACrC,MAAM,WAAW,OAAgC,IAAI;CACrD,MAAM,YAAY,OAAuB,IAAI;CAC7C,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAS,EAAE;CACrC,MAAM,CAAC,aAAa,kBAAkB,SAAsB,IAAI;CAChE,MAAM,CAAC,oBAAoB,yBAAyB,SAAS,KAAK;CAClE,MAAM,gBAAgB,mBAAmB,IAAI,OAAO;CAGpD,MAAM,EAAE,OAAO,UAAU,eAAe,gBAAgB;CACxD,MAAM,OAAa,CAAC,QAAQ,UAAU,CAAC,MAAM,aAAa,aAAa;CACvE,MAAM,QAAQ,QAAQ,IAAI,SAAS,MAAM,OAAO,IAAI,KAAA;CACpD,MAAM,iBAAiB,cAAe,QAAQ,IAAI,kBAAkB,KAAK,IAAI,CAAC,GAAI,CAAC,KAAK,KAAK,CAAC;CAC9F,MAAM,WAAW,OAAO,aACnB,eAAe,MAAK,MAAK,EAAE,OAAO,MAAM,UAAU,KAAK,IAAI,YAAY,MAAM,UAAU,IACxF,KAAA;CAEJ,MAAM,gBAAgB,IAAI,iBAAiB,YAAY,KAAA;CACvD,MAAM,gBAAgB,cAAc;EAClC,MAAM,SAAS,IAAI,OAAO,QAAO,MAAK,CAAC,EAAE,MAAM;EAC/C,OAAO,gBAAgB,CAAC,GAAG,QAAQ,cAAc,IAAI;CACvD,GAAG,CAAC,IAAI,QAAQ,aAAa,CAAC;CAC9B,MAAM,cAAc,UAAU,UAAU,IAAI,YAAY,OAAO,IAAI,KAAA;CAGnE,gBAAgB;EACd,IAAI,SAAS,SAAS,SAAS,MAAM;CACvC,GAAG,CAAC,OAAO,CAAC;CAKZ,MAAM,qBAAqB,aAAa,WAAuB;EAC7D,gBAAgB,sBAAsB,IAAI,CAAC;EAC3C,OAAO;EACP,sBAAsB,KAAK;CAC7B,GAAG,CAAC,CAAC;CAEL,MAAM,WAAW,aACd,SAAqD,yBAAyB,cAAc,IAAI,CAAC,GAClG,CAAC,oBAAoB,aAAa,CACpC;CAEA,MAAM,QAAQ,kBAAkB;EAC9B,cAAc,IAAI;EAClB,SAAS,EAAE;CACb,GAAG,CAAC,aAAa,CAAC;CAElB,MAAM,QAAQ,kBAAkB;EAC9B,QAAQ,KAAK;EACb,MAAM;CACR,GAAG,CAAC,KAAK,CAAC;CAEV,MAAM,SAAS,aACZ,SAAiB,YAAoB,UAA0B;EAC9D,yBAAyB,YAAY;GAAE;GAAS;EAAW,GAAG,KAAK,CAAC;EACpE,SAAS,EAAE;EACX,SAAS,SAAS,MAAM;CAC1B,GACA,CAAC,oBAAoB,WAAW,CAClC;CAEA,MAAM,iBAAiB,aACpB,SAAiB,SAA4B;EAC5C,IAAI,KAAK,UAAU,QAAQ;GACzB,OAAO,SAAS,KAAK,IAAI,EAAE;GAC3B;EACF;EACA,SAAS;GAAE;GAAS,YAAY,KAAK;EAAG,CAAC;EACzC,SAAS,EAAE;CACb,GACA,CAAC,QAAQ,QAAQ,CACnB;CAEA,MAAM,cAAc,aACjB,SAAyB;EACxB,IAAI,KAAK,OAAO,mBAAmB;GAEjC,MAAM,KAAK,IAAI,SAAS,KAAA,GAAW,IAAI;GACvC,IAAI,aAAa,EAAE;GACnB,IAAI,eAAe,EAAE;GACrB,SAAS,EAAE;GACX,QAAQ,KAAK;GACb;EACF;EACA,MAAM,CAAC,MAAM,GAAG,QAAQ,IAAI,kBAAkB,IAAI;EAGlD,IAAI,KAAK,UAAU,QAAQ,MAAM,KAAK,MAAM,IAAI;GAC9C,OAAO,KAAK,IAAI,KAAK,IAAI,gBAAgB,KAAK,MAAM,KAAK,CAAC;GAC1D;EACF;EAEA,IAAI,QAAQ,KAAK,WAAW,GAAG;GAC7B,eAAe,KAAK,IAAI,IAAI;GAC5B;EACF;EACA,SAAS,EAAE,SAAS,KAAK,GAAG,CAAC;EAC7B,SAAS,EAAE;CACb,GACA;EAAC;EAAK;EAAQ;EAAO;EAAgB;CAAQ,CAC/C;CAEA,MAAM,YAAY,aAAa;EAC7B;EACA;EACA;EACA,SAAS,QAAQ,SAAS;EAC1B;EACA,WAAU,UAAS;GACjB,IAAI,OAAO,YAAY,OAAO,MAAM,SAAS,MAAM,YAAY,KAAK;EACtE;CACF,CAAC;CAID,MAAM,aAAa,kBAAkB;EACnC,IAAI,CAAC,SAAS,OAAO;EACrB,IAAI,eAAe,KAAA,CAAS;EAC5B,UAAU;EACV,OAAO;CACT,GAAG;EAAC;EAAK;EAAS;CAAO,CAAC;CAE1B,MAAM,WAAW,kBAAkB;EACjC,IAAI,SAAS,WAAW,OAAO;GAE7B,MAAM,eAAe,QAAQ,eAAe,WAAW,IAAI;GAC3D,SAAS,eAAe,OAAO,EAAE,SAAS,MAAM,QAAQ,CAAC;EAC3D,OAAO,IAAI,SAAS,YAAY,SAAS,IAAI;OACxC,IAAI,CAAC,WAAW,GAAG,QAAQ,KAAK;EACrC,SAAS,EAAE;CACb,GAAG;EAAC;EAAM;EAAO;EAAO;EAAgB;EAAU;CAAU,CAAC;CAG7D,MAAM,gBAAgB,SAAe;EACnC,IAAI,SAAS,SAAS,YAAY,IAAsB;OACnD,IAAI,SAAS,cAAc,OAAO,eAAe,MAAM,SAAS,IAAyB;OACzF,UAAU,aAAa,IAAuB;CACrD;CAGA,MAAM,iBAAiB,UAAwD;EAC7E,IAAI,MAAM,QAAQ,UAAU;GAC1B,MAAM,eAAe;GAErB,MAAM,gBAAgB;GACtB,MAAM,qBAAqB;GAC3B,SAAS;GACT;EACF;EACA,IAAI,CAAC,SAAS,MAAM,QAAQ,eAAe,MAAM,QAAQ,UAAU;GACjE,MAAM,eAAe;GACrB,MAAM,qBAAqB;GAC3B,QAAQ,IAAI;GACZ;EACF;EACA,IAAI,UAAU,IAAI;GAChB,IAAI,MAAM,QAAQ,aAAa;IAC7B,MAAM,eAAe;IACrB,MAAM,qBAAqB;IAC3B,IAAI,SAAS,SAAS,SAAS;SAC1B,IAAI,aAAa;KAEpB,MAAM,OAAO,YAAY,MAAM,UAAS,SAAQ,CAAC,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;KACzE,IAAI,MAAM,IAAI,WAAW,KAAK,EAAE;UAC3B,WAAW;IAClB,OAAO;KAEL,MAAM,OAAO,IAAI,MAAM,UAAS,SAAQ,CAAC,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;KACjE,IAAI,MAAM,IAAI,WAAW,KAAK,EAAE;IAClC;IACA;GACF;GACA,IAAI,MAAM,QAAQ,eAAe,SAAS,SAAS;IACjD,IAAI,IAAI,UAAU,IAAI,MAAM,SAAS,GAAG,IAAI,QAAQ,GAAG,MAAM,eAAe;IAC5E;GACF;EACF;EACA,IAAI,CAAC,MAAM;EAEX,IAAI,MAAM,QAAQ,SAAS,eAAe,SAAS,YAAY,SAAS,cAAc,UAAU,KAAK;GACnG,MAAM,eAAe;GACrB,MAAM,qBAAqB;GAC3B,aAAa,WAAW;GACxB;EACF;EACA,IAAI,SAAS,SAAS;GACpB,MAAM,oBAAoB,UAAU,iBAAkB,cAAyC;GAG/F,IAFgB,UAAU,cAAc,OAAO,iBAE3C,KAAY,MAAM,QAAQ,WAAW,sBAAsB,MAAO,MAAM,qBAAqB;EACnG;CACF;CAEA,MAAM,iBAAgD;EACpD,OAAO;EACP,UAAU;EACV,OAAO,UAAU;CACnB;CACA,MAAM,QAAyB,qBAAqB,cAAc,eAAe;CAIjF,MAAM,aAAa,aAChB,MAAY,MAAc,iBACxB,YAAY,QAAQ,KAAK,WAAW,QAAS,mBAAmB,MAAM,MAAM,YAAY,GAC3F,CAAC,CACH;CAEA,MAAM,mBACJ,SAAS,UACL,cACA,SAAS,aACP,cACA,UAAU,kBAAkB,UAAU,gBACpC,4BACA,OAAO,SAAS,WACd,YACA;CAEZ,OACE,oBAAAA,YAAA,EAAA,UACE,qBAAC,kBAAkB,MAAnB;EACS;EACP,mBAAmB;EAEnB,QAAQ,SAAS,UAAU,OAAO;EAClC,OAAO;EACP,gBAAgB,MAAM,YAAY;GAEhC,QAAQ,OAAO;GACf,IAAI,MAAM,aAAa,IAAI;EAC7B;EACA,YAAY;EACZ,qBAAqB,MAAM,YAAY;GACrC,IAAI,QAAQ,WAAW,gBAAgB;GACvC,SAAS,IAAI;GACb,IAAI,CAAC,MAAM,QAAQ,IAAI;EACzB;EACA,oBAAmB,SAAQ,eAAe,QAAQ,IAAI;EAChD;EACN,eAAe,MAAM,YAAY;GAE/B,IAAI,CAAC,QAAQ,QAAQ,WAAW,cAAc;GAE9C,IACE,CAAC,QACD,QAAQ,WAAW,mBACnB,QAAQ,MAAM,kBAAkB,QAChC,SAAS,SAAS,SAAS,QAAQ,MAAM,MAAM,GAE/C;GAEF,IAAI,MAAM,QAAQ,IAAI;QACjB,MAAM;EACb;EACA,GAAI;EACJ,OAAO;EAnCT,UAAA,CAqCE,qBAAC,OAAD;GACE,KAAK;GACL,aAAU;GACV,WAAW,GAIT,qBAAqB;IAAE,SAAS;IAAW,MAAA;GAA8B,CAAC,GAC1E,sBACA,8BACA,wBACA,SAAS,UAAU,aAAa,YAChC,SACF;GAbF,UAAA,CAeE,oBAAC,gBAAD;IAAgB,eAAA;IAAY,WAAU;GAAY,CAAA,GAClD,oBAAC,kBAAkB,OAAnB;IACE,MAAK,OAAM;KACT,SAAS,UAAU;KACnB,IAAI,cAAc,EAAE;IACtB;IACA,cAAY;IACZ,YAAY;IACZ,GAAI;IACJ,aAAU;IACV,aAAW;IACX,eAAa,aAAa;IAC1B,WAAW,SAAS,WAAW,OAAO,SAAS,WAAW,YAAY,KAAA;IACtE,aAAa;IACb,WAAW,GACT,0BACA,iCACA,2HACF;IACA,eAAe,QAAQ,IAAI;IAC3B,WAAW;GACZ,CAAA,CACE;EACL,CAAA,GAAA,oBAAC,kBAAkB,QAAnB;GAAqC;GACnC,UAAA,oBAAC,kBAAkB,YAAnB;IAEE,QAAQ;IACR,OAAM;IACN,YAAA;IACA,gBAAgB;IAChB,WAAW,eAAe;IAE1B,UAAA,qBAAC,kBAAkB,OAAnB;KACE,WAAW,GAAG,eAAe,OAAO,6BAA6B;KACjE,aAAU;KAFZ,UAAA;MAIG,SAAS,WACR,oBAAC,qBAAD;OACE,cAAW;OACX,SAAQ,MAAK,EAAE;OACf,eAAc,MACZ,qBAAAA,YAAA,EAAA,UAAA,CACE,oBAAC,qBAAD,EAAqB,OAAO,EAAI,CAAA,GAC/B,EAAE,UAAU,UAAU,MACrB,qBAAC,QAAD;QAAM,WAAU;QAAhB,UAAA;SACG,IAAI,kBAAkB,CAAC,CAAC,CAAC,EAAE,EAAE;SAAM;SAAG;SAAM;QACzC;OAER,CAAA,CAAA,EAAA,CAAA;OAEJ,WAAU;MACX,CAAA;MAEF,SAAS,cACR,oBAAC,qBAAD;OACE,cAAW;OACX,SAAQ,MAAK,EAAE;OACf,eAAc,MAAK,EAAE;OACrB,WAAU;MACX,CAAA;MAEF,SAAS,WAAW,UAAU,cAC7B,oBAAC,qBAAD;OACE,cAAW;OACX,wBAAsB,UAAU,UAAU,KAAA;OAC1C,SAAQ,MAAK,EAAE;OACf,eAAc,WAAU,oBAAC,sBAAD,EAA8B,OAAS,CAAA;OAC/D,aAAY,MAAK,UAAU,UAAU,UAAU,SAAS,SAAS,EAAE,KAAK;OACxE,WAAW,UAAU;OACrB,OAAO,UAAU;OACjB,WACE,UAAU,gBAAgB,mDAAmD;MAEhF,CAAA;MAEF,SAAS,WAAW,CAAC,UAAU,kBAC9B,qBAAC,OAAD;OAAK,WAAU;OAAf,UAAA,CACE,oBAAC,KAAD;QAAK,SAAQ;QAAU,MAAK;QAAQ,UAAA;OAE/B,CAAA,GACL,qBAAC,QAAD;QACE,MAAK;QACL,SAAQ;QACR,UAAU,CAAC,UAAU;QACrB,cAAa,MAAK,EAAE,eAAe;QACnC,eAAe,UAAU,eAAe;QAL1C,UAAA,CAMC,SAEC,oBAAC,KAAD;SAAK,MAAK;SAAK,UAAA;QAAM,CAAA,CACf;OACL,CAAA,CAAA;;MAEN,SAAS,WAAW,UAAU,UAC7B,oBAAC,OAAD;OAAK,WAAU;OACb,UAAA,qBAAC,QAAD;QACE,MAAK;QACL,SAAQ;QACR,cAAa,MAAK,EAAE,eAAe;QACnC,eAAe,UAAU,WAAW;QAJtC,UAAA,CAKC,QAEC,oBAAC,KAAD;SAAK,MAAK;SAAM,UAAA;QAAmB,CAAA,CAC7B;;MACL,CAAA;KAEgB;;GACG,CAAA;EACN,CAAA,CACJ;CACxB,CAAA,EAAA,CAAA;AAEN;;;ACvcA,SAAgB,iBAAiB,IAAY,SAAkB,SAA8C;CAC3G,MAAM,EAAE,iBAAiB,oBAAoB;CAC7C,gBAAgB;EACd,MAAM,OAAO,QAAQ;EACrB,IAAI,CAAC,WAAW,CAAC,MAAM;EACvB,MAAM,aAAa,OAAO,KAAK,kBAAkB,aAAa,KAAK,cAAc,EAAE,SAAS,KAAK,CAAC,IAAI,CAAC;EACvG,IAAI,WAAW,WAAW,GAAG;GAC3B,aAAa,EAAE;GACf;EACF;EACA,IAAI,YAAY;EAChB,QAAQ,IAAI,WAAW,KAAI,cAAa,UAAU,QAAQ,CAAC,CAAC,CACzD,WAAW;GACV,IAAI,CAAC,WAAW,aAAa,EAAE;EACjC,CAAC,CAAC,CACD,YAAY,CAAC,CAAC;EACjB,aAAa;GACX,YAAY;EACd;CACF,GAAG;EAAC;EAAS;EAAI;EAAc;CAAO,CAAC;AACzC;;ACVA,IAAM,iBACJ;;AASF,SAAgB,qBAAqB,EAAE,SAAS,OAAO,aAAwC;CAC7F,MAAM,MAAM,oBAAoB;CAChC,MAAM,OAAuB,UAAU,QAAQ,OAAO;CACtD,OACE,oBAAC,UAAD;EACE,MAAK;EACL,aAAU;EACV,cAAY;EACZ,cAAY,eAAe,MAAM,cAAc;EAC/C,OAAO,aAAa;EACpB,WAAW,GACT,gBACA,oFACA,uGACA,SACF;EACA,eAAe,IAAI,SAAS,SAAS,IAAI;EAExC,UAAA;CACK,CAAA;AAEZ;;AAGA,SAAS,qBAAqB,EAAE,SAAS,SAAqD;CAC5F,MAAM,MAAM,oBAAoB;CAChC,OACE,oBAAC,OAAD;EACE,MAAK;EACL,cAAW;EACX,WAAU;EAER,UAAA,CAAC,OAAO,IAAI,CAAC,CAAW,KAAI,UAC5B,oBAAC,UAAD;GAEE,MAAK;GACL,MAAK;GACL,gBAAc,UAAU;GACxB,cAAY,aAAa;GACzB,WAAW,GACT,4FACA,+BACA,UAAU,QAAQ,kCAAkC,6CACtD;GACA,eAAe,UAAU,SAAS,IAAI,SAAS,SAAS,KAAK;GAE5D,UAAA;EACK,GAbD,KAaC,CACT;CACE,CAAA;AAET;;;;;;;;AAmBA,SAAgB,qBAAqB,EACnC,OACA,OACA,UACA,cAAc,gBACd,aAC4B;CAC5B,MAAM,MAAM,oBAAoB;CAChC,MAAM,eAAe,OAA0B,IAAI;CACnD,MAAM,iBAAiB,OAAO,KAAK;CACnC,MAAM,WAAW,IAAI,gBAAgB,MAAM;CAC3C,MAAM,UAAU,QAAQ,IAAI;CAG5B,gBAAgB;EACd,IAAI,YAAY,CAAC,eAAe,SAAS;EACzC,eAAe,UAAU;EACzB,aAAa,SAAS,MAAM;CAC9B,GAAG,CAAC,QAAQ,CAAC;CAEb,MAAM,OAAoB,CAAC;CAC3B,MAAM,aAAa,QACjB,KAAK,WAAW,IACd,oBAAC,QAAD;EAA2B,WAAW;EAAgB,UAAA;CAEhD,GAFK,GAAG,IAAI,OAEZ,IAEN,oBAAC,sBAAD;EAA2C,SAAS,MAAM;EAAI,OAAO,MAAM;CAAQ,GAAxD,GAAG,IAAI,OAAiD;CAEvF,KAAK,MAAM,QAAQ,MAAM,OACvB,KAAK,KACH,qBAAC,UAAD,EAAA,UAAA,CACG,UAAU,KAAK,EAAE,GACjB,iBAAiB,IAAI,IACpB,oBAAC,iBAAD;EAAiB,OAAO;EAAM,OAAO,QAAQ;CAAI,CAAA,IAEjD,oBAAC,eAAD;EAAe,MAAM;EAAM,WAAU;CAAS,CAAA,CAExC,EAAA,GAPK,KAAK,EAOV,CACZ;CAEF,IAAI,IAAI,SAAS,IAAI,MAAM,YAAY,MAAM,IAAI;EAC/C,MAAM,EAAE,IAAI,SAAS,aAAa,OAAO,IAAI;EAC7C,KAAK,KACH,qBAAC,UAAD,EAAA,UAAA,CACG,UAAU,EAAE,GACb,oBAAC,eAAD;GAAe,OAAA;GAAM,MAAM;IAAE;IAAI;IAAS;IAAY,OAAO;GAAG;GAAG,WAAU;EAAS,CAAA,CAC9E,EAAA,GAHK,EAGL,CACZ;CACF;CACA,IAAI,UACF,KAAK,KACH,qBAAC,UAAD,EAAA,UAAA,CACG,UAAU,OAAO,GAClB,oBAAC,gBAAD;EACE,SAAS,MAAM;EACf,aAAY;EACZ,eAAe;GACb,eAAe,UAAU;EAC3B;CACD,CAAA,CACO,EAAA,GATI,OASJ,CACZ;CAGF,OACE,qBAAC,OAAD;EACE,aAAU;EACV,cAAY;EACZ,MAAK;EACL,cAAY,0BAA0B,MAAM;EAC5C,WAAW,GAAG,yBAAyB,SAAS;EALlD,UAAA,CAOG,KAAK,SAAS,KACb,oBAAC,OAAD;GAAK,WAAU;GAAyE,UAAA;EAAU,CAAA,GAEpG,qBAAC,OAAD;GACE,aAAU;GACV,WAAW,GAAG,sCAAsC,KAAK,SAAS,KAAK,wBAAwB;GAFjG,UAAA;IAIG,CAAC,YACA,oBAAC,QAAD;KACE,KAAK;KACL,SAAQ;KACR,MAAK;KACL,MAAM,oBAAC,UAAD,CAAW,CAAA;KACjB,eAAe,IAAI,eAAe,MAAM,EAAE;KAC3C,UAAA;IAEO,CAAA;IAEV,oBAAC,QAAD;KACE,SAAQ;KACR,MAAK;KACL,MAAM,oBAAC,gBAAD,CAAiB,CAAA;KACvB,WAAU;KACV,SAAS,UAAU,KAAA,IAAY,mBAAmB,IAAI,SAAS;KAC/D,UAAU,CAAC;KACX,eAAe,IAAI,SAAS,MAAM,IAAI,MAAM,UAAU,QAAQ,OAAO,KAAK;KAC3E,UAAA;IAEO,CAAA;IACP,YACC,oBAAC,QAAD;KACE,SAAQ;KACR,MAAK;KACL,MAAM,oBAAC,YAAD,CAAa,CAAA;KACnB,WAAU;KACV,cAAY;KACZ,SAAS;KACV,UAAA;IAEO,CAAA;GAEP;EACF,CAAA,CAAA;;AAET;AAEA,SAAS,gBAAgB,EAAE,OAAO,SAAmD;CACnF,MAAM,MAAM,oBAAoB;CAChC,MAAM,UAAU,OAAuB,IAAI;CAC3C,MAAM,UAAU,IAAI,QAAQ,IAAI,MAAM,EAAE;CACxC,iBAAiB,MAAM,IAAI,SAAS,OAAO;CAC3C,MAAM,QAAQ,YAAY,KAAK;CAE/B,OACE,qBAAC,OAAD;EACE,KAAK;EACL,aAAU;EACV,gBAAc,WAAW,KAAA;EACzB,eAAa,WAAW,KAAA;EACxB,WAAW,GACT,mFACA,WAAW,qBACb;EARF,UAAA,CAUE,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IACE,oBAAC,YAAD,EAAY,WAAU,iCAAkC,CAAA;IACxD,oBAAC,KAAD;KAAK,IAAG;KAAO,SAAQ;KAAQ,MAAK;KAAM,UAAA;IAErC,CAAA;IACL,qBAAC,KAAD;KAAK,IAAG;KAAO,SAAQ;KAAQ,MAAK;KAApC,UAAA;MAA4C;MACvC;MAAM;MAAE,UAAU,IAAI,cAAc;KACpC;;IACL,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,sBAAD;MAAsB,SAAS,MAAM;MAAI,OAAO,MAAM;KAAQ,CAAA,GAC9D,oBAAC,QAAD;MACE,SAAQ;MACR,MAAK;MACL,SAAQ;MACR,UAAU;MACV,eAAe,IAAI,YAAY,MAAM,EAAE;MAEvC,UAAA,oBAAC,YAAD,CAAa,CAAA;KACP,CAAA,CACL;;GACF;EACL,CAAA,GAAA,oBAAC,sBAAD;GAA6B;GAAc;EAAQ,CAAA,CAChD;;AAET;;;;;;ACxOA,SAAgB,sBAAsB,EAAE,OAAO,aAAyC;CACtF,MAAM,MAAM,oBAAoB;CAChC,MAAM,CAAC,WAAW,eAAe,CAAC,IAAI,OAAO;CAC7C,MAAM,UAAU,OAAuB,IAAI;CAC3C,MAAM,aAAa,OAA0B,IAAI;CACjD,MAAM,UAAU,IAAI,QAAQ,IAAI,MAAM,EAAE;CACxC,MAAM,OAAO,IAAI,gBAAgB,MAAM;CACvC,MAAM,QAAQ,YAAY,KAAK;CAE/B,MAAM,iBAAiB,IAAI,MAAM,WAAU,SAAQ,QAAQ,OAAO,KAAK,EAAE,CAAC;CAC1E,MAAM,QAAQ,mBAAmB,KAAK,IAAI,MAAM,SAAS;CACzD,iBAAiB,MAAM,IAAI,SAAS,OAAO;CAE3C,MAAM,iBAAiB,UAAyC;EAC9D,IAAI,SAAS;EACb,MAAM,WAAW,MAAM,KAAK,QAAQ,SAAS,iBAA8B,2BAA2B,KAAK,CAAC,CAAC;EAC7G,MAAM,UAAU,SAAS,WAAU,OAAM,OAAO,MAAM,MAAM;EAC5D,IAAI,YAAY,IAAI;EACpB,QAAQ,MAAM,KAAd;GACE,KAAK,cAAc;IACjB,MAAM,eAAe;IACrB,MAAM,OAAO,SAAS,UAAU;IAChC,IAAI,MAAM,KAAK,MAAM;SAChB,IAAI,CAAC,IAAI,UAAU,QAAQ,OAAO,GAAG,OAAO,GAAG,IAAI,WAAW;IACnE;GACF;GACA,KAAK,aAAa;IAChB,MAAM,eAAe;IACrB,MAAM,OAAO,SAAS,UAAU;IAChC,IAAI,MAAM,KAAK,MAAM;SAChB,IAAI,UAAU,QAAQ,GAAG,IAAI,QAAQ;IAC1C;GACF;GACA,KAAK;GACL,KAAK;IACH,MAAM,eAAe;IACrB,OAAO;EAGX;CACF;CAEA,MAAM,eAAe;EACnB,IAAI,YAAY,MAAM,EAAE;EACxB,IAAI,iBAAiB,KAAK;CAC5B;CAEA,OACE,qBAAC,SAAD;EAAe;EAAM,eAAc,SAAQ,IAAI,aAAa,OAAO,MAAM,KAAK,IAAI;EAAlF,UAAA,CACE,qBAAC,OAAD;GACE,KAAK;GACL,MAAK;GACL,cAAY,oBAAoB,MAAM,GAAG,UAAU,IAAI,cAAc;GACrE,eAAa,WAAW,KAAA;GACxB,aAAU;GACV,gBAAc,WAAW,KAAA;GACzB,gBAAc,WAAW,KAAA;GACzB,WAAW,GAAG,uBAAuB,WAAW,WAAW,uBAAuB,SAAS;GAC3F,WAAW;GATb,UAAA,CAWE,qBAAC,gBAAD;IACE,MAAK,OAAM;KACT,WAAW,UAAU;KACrB,IAAI,gBAAgB,MAAM,IAAI,SAAS,UAAU,OAAO,EAAE;IAC5D;IACA,QAAQ,oBAAC,UAAD,EAAQ,MAAK,SAAU,CAAA;IAC/B,2BAAwB;IACxB,WAAW;IACX,OAAM;IARR,UAAA;KAUE,oBAAC,YAAD,EAAY,eAAA,KAAa,CAAA;KACzB,oBAAC,QAAD;MAAM,WAAU;MAAW,UAAA;KAAqB,CAAA;KAC/C,QAAQ,KACP,oBAAC,KAAD;MAAK,IAAG;MAAO,SAAQ;MAAS,MAAK;MAAQ,eAAA;MAC1C,UAAA;KACE,CAAA;IAEO;GACf,CAAA,GAAA,UACC,oBAAC,QAAD;IAAM,eAAA;IAAY,WAAW;IAC3B,UAAA,oBAAC,OAAD,CAAQ,CAAA;GACJ,CAAA,IAEN,oBAAC,UAAD;IACE,MAAK;IACL,MAAK,OAAM,IAAI,gBAAgB,MAAM,IAAI,UAAU,EAAE;IACrD,2BAAwB;IACxB,cAAW;IACX,OAAM;IACN,WAAW;IACX,SAAS;IAET,UAAA,oBAAC,OAAD,CAAQ,CAAA;GACF,CAAA,CAEP;EACL,CAAA,GAAA,qBAAC,gBAAD;GACE,OAAM;GACN,WAAU;IACH,wBAAwB;GAC/B,YAAY;GAJd,UAAA,CAME,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,YAAD,EAAY,WAAU,iCAAkC,CAAA;KACxD,oBAAC,KAAD;MAAK,IAAG;MAAO,SAAQ;MAAQ,MAAK;MAAM,UAAA;KAErC,CAAA;KACL,oBAAC,KAAD;MAAK,IAAG;MAAO,SAAQ;MAAS,MAAK;MAAQ,WAAU;MACpD,UAAA;KACE,CAAA;KACL,oBAAC,QAAD;MACE,SAAQ;MACR,MAAK;MACL,WAAU;MACV,SAAQ;MACR,eAAe,IAAI,aAAa,IAAI;MAEpC,UAAA,oBAAC,OAAD,CAAQ,CAAA;KACF,CAAA;IACL;GACL,CAAA,GAAA,oBAAC,sBAAD;IACS;IACP,OAAO;IACP,aAAY;IACZ,gBAAgB;KACd,IAAI,aAAa,IAAI;KACrB,OAAO;IACT;GACD,CAAA,CACa;EACT,CAAA,CAAA;;AAEb;AAEA,IAAM,WAAW,OAAuB,WACtC,MAAM,MAAM,MAAK,SAAS,KAAK,OAAO,SAAS,OAAO,UAAU,QAAQ,QAAQ,MAAM,MAAM,CAAE;;;AC1JhG,SAAgB,eAAe,EAAE,SAA4B;CAC3D,MAAM,MAAM,oBAAoB;CAChC,IAAI,CAAC,IAAI,mBAAmB,OAAO;CACnC,OACE,oBAAC,oBAAD;EACS;EACP,UAAS,UAAS;GAChB,MAAM,gBAAgB;GACtB,IAAI,MAAM;GACV,IAAI,WAAW;EACjB;CACD,CAAA;AAEL;;ACkCA,SAAS,iBAAiB,EACxB,WACA,YACA,YAKC;CACD,MAAM,MAAM,oBAAoB;CAChC,OACE,qBAAC,OAAD;EACE,MAAK;EACL,cAAY,IAAI;EAChB,aAAU;GACH,wBAAwB;EAC/B,WAAW,GAIT,8CACA,SACF;EAXF,UAAA;GAaG;GACD,oBAAC,QAAD;IAAM,WAAU;IACd,UAAA,oBAAC,gBAAD,EAAgB,OAAO,WAAa,CAAA;GAChC,CAAA;GACN,oBAAC,gBAAD;IAAgB,aAAU;IAAU,UAAA,IAAI;GAA6B,CAAA;EAClE;;AAET;;;;;;;;;;;;;;;;;AAkBA,SAAgB,UAAU,EACxB,QACA,WACA,OACA,eACA,cACA,UACA,cAAc,YAAY,WAC1B,0BACA,aAAa,iBACb,WACA,YACiB;CACjB,OACE,oBAAC,mBAAD;EACU;EACG;EACJ;EACQ;EACD;EACJ;EACC;EACe;EAE1B,UAAA,oBAAC,kBAAD;GAA6B;GAAuB;GACjD;EACe,CAAA;CACD,CAAA;AAEvB;;;;;;AAOA,SAAgB,eAAe,EAAE,aAAa,qBAA0C;CACtF,MAAM,MAAM,oBAAoB;CAGhC,MAAM,QAAqB,CAAC;CAC5B,KAAK,MAAM,QAAQ,IAAI,WAAW,OAAO;EACvC,MAAM,OAAO,iBAAiB,IAAI,IAAI,oBAAC,uBAAD,EAAuB,OAAO,KAAO,CAAA,IAAI,WAAW,IAAI;EAC9F,IAAI,SAAS,MAAM,MAAM,KAAK,oBAAC,UAAD,EAAA,UAAyB,KAAe,GAAzB,KAAK,EAAoB,CAAC;CACzE;CACA,IAAI,IAAI,SAAS,CAAC,IAAI,MAAM,SAAS;EAEnC,MAAM,EAAE,IAAI,SAAS,aAAa,OAAO,IAAI;EAC7C,MAAM,KACJ,oBAAC,UAAD,EAAA,UACE,oBAAC,eAAD;GAAe,OAAA;GAAM,MAAM;IAAE;IAAI;IAAS;IAAY,OAAO;GAAG;EAAI,CAAA,EAC5D,GAFK,EAEL,CACZ;CACF;CACA,OAAO,oBAAAC,YAAA,EAAA,UAAG,MAAQ,CAAA;AACpB;AAUA,IAAM,qBAAqB,SAAwB,oBAAC,eAAD,EAAqB,KAAO,CAAA;AAE/E,UAAU,QAAQ;AAClB,UAAU,OAAO;AACjB,UAAU,eAAe;AACzB,UAAU,QAAQ;AAClB,UAAU,YAAY;;;ACxKtB,IAAa,2BAAgD;CAC3D;EAAE,IAAI;EAAM,OAAO;EAAM,UAAU;CAAK;CACxC;EAAE,IAAI;EAAU,OAAO;CAAS;CAChC;EAAE,IAAI;EAAY,OAAO;CAAW;CACpC;EAAE,IAAI;EAAgB,OAAO;CAAmB;CAChD;EAAE,IAAI;EAAe,OAAO;CAAc;CAC1C;EAAE,IAAI;EAAM,OAAO;CAAI;CACvB;EAAE,IAAI;EAAM,OAAO;CAAI;CACvB;EAAE,IAAI;EAAO,OAAO;CAAK;CACzB;EAAE,IAAI;EAAO,OAAO;CAAK;CACzB;EAAE,IAAI;EAAY,OAAO;EAAY,OAAO;CAAO;CACnD;EAAE,IAAI;EAAgB,OAAO;EAAgB,OAAO;CAAO;CAC3D;EAAE,IAAI;EAAM,OAAO;EAAM,OAAO;CAAO;AACzC"}