@osdk/react-components 0.58.0 → 0.58.1-main-f1b178d2b6aaa5013ba28dae0a518a2c077f552c

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 (185) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/build/browser/filter-list/FilterListItemApi.js.map +1 -1
  3. package/build/browser/filter-list/base/inputs/DateRangeHistogramInput.js +14 -2
  4. package/build/browser/filter-list/base/inputs/DateRangeHistogramInput.js.map +1 -1
  5. package/build/browser/filter-list/base/inputs/RelativeDateBoundInput.js +156 -0
  6. package/build/browser/filter-list/base/inputs/RelativeDateBoundInput.js.map +1 -0
  7. package/build/browser/filter-list/base/inputs/RelativeDateBoundInput.module.css +299 -0
  8. package/build/browser/filter-list/base/inputs/RelativeDateBoundInput.module.css.js +23 -0
  9. package/build/browser/filter-list/base/inputs/RelativeDateRangeInput.js +52 -0
  10. package/build/browser/filter-list/base/inputs/RelativeDateRangeInput.js.map +1 -0
  11. package/build/browser/filter-list/base/inputs/RelativeModeToggle.js +35 -0
  12. package/build/browser/filter-list/base/inputs/RelativeModeToggle.js.map +1 -0
  13. package/build/browser/filter-list/base/inputs/shared.module.css +14 -0
  14. package/build/browser/filter-list/base/inputs/shared.module.css.js +2 -0
  15. package/build/browser/filter-list/inputs/DateRangeFilterInput.js +55 -5
  16. package/build/browser/filter-list/inputs/DateRangeFilterInput.js.map +1 -1
  17. package/build/browser/filter-list/inputs/PropertyFilterInput.js +2 -1
  18. package/build/browser/filter-list/inputs/PropertyFilterInput.js.map +1 -1
  19. package/build/browser/filter-list/utils/filterStateToWhereClause.js +7 -4
  20. package/build/browser/filter-list/utils/filterStateToWhereClause.js.map +1 -1
  21. package/build/browser/filter-list/utils/resolveRelativeDate.js +75 -0
  22. package/build/browser/filter-list/utils/resolveRelativeDate.js.map +1 -0
  23. package/build/browser/filter-list/utils/summarizeFilterValue.js +6 -0
  24. package/build/browser/filter-list/utils/summarizeFilterValue.js.map +1 -1
  25. package/build/browser/public/experimental/filter-list.js +4 -0
  26. package/build/browser/public/experimental/filter-list.js.map +1 -1
  27. package/build/browser/public/filter-list.js.map +1 -1
  28. package/build/browser/styles.css +316 -0
  29. package/build/browser/util/UserAgent.js +1 -1
  30. package/build/browser/util/UserAgent.js.map +1 -1
  31. package/build/cjs/{chunk-5GHMDOID.cjs → chunk-3BAVDH3O.cjs} +4 -4
  32. package/build/cjs/{chunk-5GHMDOID.cjs.map → chunk-3BAVDH3O.cjs.map} +1 -1
  33. package/build/cjs/chunk-4UY2GA6O.cjs +11 -0
  34. package/build/cjs/{chunk-J7LQAIRU.cjs.map → chunk-4UY2GA6O.cjs.map} +1 -1
  35. package/build/cjs/{chunk-F5UUZ7BD.cjs → chunk-5J3OK3CE.cjs} +8 -8
  36. package/build/cjs/{chunk-F5UUZ7BD.cjs.map → chunk-5J3OK3CE.cjs.map} +1 -1
  37. package/build/cjs/{chunk-JNSHIKCQ.cjs → chunk-62TDTOSI.cjs} +88 -2
  38. package/build/cjs/chunk-62TDTOSI.cjs.map +1 -0
  39. package/build/cjs/{chunk-3BSEJUIR.cjs → chunk-7EPGXMLA.cjs} +4 -4
  40. package/build/cjs/{chunk-3BSEJUIR.cjs.map → chunk-7EPGXMLA.cjs.map} +1 -1
  41. package/build/cjs/chunk-7RKTNJLO.cjs +314 -0
  42. package/build/cjs/chunk-7RKTNJLO.cjs.map +1 -0
  43. package/build/cjs/chunk-BXAMDS5B.cjs +11 -0
  44. package/build/cjs/{chunk-6MIMBFOQ.cjs.map → chunk-BXAMDS5B.cjs.map} +1 -1
  45. package/build/cjs/chunk-C5SNNIDR.cjs +48 -0
  46. package/build/cjs/{chunk-TKZU2GLD.cjs.map → chunk-C5SNNIDR.cjs.map} +1 -1
  47. package/build/cjs/chunk-C6PZXG7P.cjs +12 -0
  48. package/build/cjs/{chunk-C6GTKE26.cjs.map → chunk-C6PZXG7P.cjs.map} +1 -1
  49. package/build/cjs/{chunk-SHXZCMMH.cjs → chunk-ENTG2M26.cjs} +4 -4
  50. package/build/cjs/{chunk-SHXZCMMH.cjs.map → chunk-ENTG2M26.cjs.map} +1 -1
  51. package/build/cjs/chunk-HIHWX643.cjs +11 -0
  52. package/build/cjs/{chunk-WCOINODS.cjs.map → chunk-HIHWX643.cjs.map} +1 -1
  53. package/build/cjs/{chunk-LLFJ7QN5.cjs → chunk-HTUNHTOD.cjs} +5 -5
  54. package/build/cjs/{chunk-LLFJ7QN5.cjs.map → chunk-HTUNHTOD.cjs.map} +1 -1
  55. package/build/cjs/{chunk-IJPVWQXM.cjs → chunk-IBYQJ4C3.cjs} +4 -4
  56. package/build/cjs/{chunk-IJPVWQXM.cjs.map → chunk-IBYQJ4C3.cjs.map} +1 -1
  57. package/build/cjs/{chunk-3C574XJN.cjs → chunk-IW2XTTTQ.cjs} +3 -3
  58. package/build/cjs/chunk-IW2XTTTQ.cjs.map +1 -0
  59. package/build/cjs/chunk-JHY32RPF.cjs +11 -0
  60. package/build/cjs/{chunk-TMAQHJTC.cjs.map → chunk-JHY32RPF.cjs.map} +1 -1
  61. package/build/cjs/{chunk-WZ27ETIW.cjs → chunk-JKYRTNZ4.cjs} +11 -11
  62. package/build/cjs/{chunk-WZ27ETIW.cjs.map → chunk-JKYRTNZ4.cjs.map} +1 -1
  63. package/build/cjs/{chunk-VD4NU767.cjs → chunk-JON6PVJL.cjs} +4 -4
  64. package/build/cjs/{chunk-VD4NU767.cjs.map → chunk-JON6PVJL.cjs.map} +1 -1
  65. package/build/cjs/chunk-K5CWXMZH.cjs +34 -0
  66. package/build/cjs/{chunk-C2TU7ODQ.cjs.map → chunk-K5CWXMZH.cjs.map} +1 -1
  67. package/build/cjs/{chunk-B4KQD2SF.cjs → chunk-MQGXI7KO.cjs} +911 -630
  68. package/build/cjs/chunk-MQGXI7KO.cjs.map +1 -0
  69. package/build/cjs/chunk-QELY36U7.cjs +11 -0
  70. package/build/cjs/{chunk-KFPTUFXM.cjs.map → chunk-QELY36U7.cjs.map} +1 -1
  71. package/build/cjs/{chunk-4VDVMM6Z.cjs → chunk-QJTLQGLC.cjs} +4 -4
  72. package/build/cjs/{chunk-4VDVMM6Z.cjs.map → chunk-QJTLQGLC.cjs.map} +1 -1
  73. package/build/cjs/chunk-QZH56MKK.cjs +12 -0
  74. package/build/cjs/{chunk-NHQQ6JAW.cjs.map → chunk-QZH56MKK.cjs.map} +1 -1
  75. package/build/cjs/{chunk-VBTWVD6X.cjs → chunk-RWZ7DUUE.cjs} +4 -4
  76. package/build/cjs/{chunk-VBTWVD6X.cjs.map → chunk-RWZ7DUUE.cjs.map} +1 -1
  77. package/build/cjs/{chunk-VERIEQO4.cjs → chunk-SIU7HPB2.cjs} +17 -17
  78. package/build/cjs/{chunk-VERIEQO4.cjs.map → chunk-SIU7HPB2.cjs.map} +1 -1
  79. package/build/cjs/{chunk-56C4GIAX.cjs → chunk-SXG2R3IA.cjs} +4 -4
  80. package/build/cjs/{chunk-56C4GIAX.cjs.map → chunk-SXG2R3IA.cjs.map} +1 -1
  81. package/build/cjs/chunk-TJZFSWW5.cjs +11 -0
  82. package/build/cjs/{chunk-RIE55H3T.cjs.map → chunk-TJZFSWW5.cjs.map} +1 -1
  83. package/build/cjs/{chunk-HLCVO3WS.cjs → chunk-UUBGYLQ7.cjs} +4 -4
  84. package/build/cjs/{chunk-HLCVO3WS.cjs.map → chunk-UUBGYLQ7.cjs.map} +1 -1
  85. package/build/cjs/{chunk-DTTOK4G2.cjs → chunk-W4YLF7TG.cjs} +5 -5
  86. package/build/cjs/{chunk-DTTOK4G2.cjs.map → chunk-W4YLF7TG.cjs.map} +1 -1
  87. package/build/cjs/{filter-list-CraygbR8.d.cts → filter-list-DiC8K42a.d.cts} +44 -5
  88. package/build/cjs/public/action-form.cjs +6 -6
  89. package/build/cjs/public/document-viewer.cjs +4 -4
  90. package/build/cjs/public/email-viewer.cjs +3 -3
  91. package/build/cjs/public/experimental/action-form.cjs +7 -7
  92. package/build/cjs/public/experimental/cbac-picker.cjs +11 -11
  93. package/build/cjs/public/experimental/document-viewer.cjs +5 -5
  94. package/build/cjs/public/experimental/email-viewer.cjs +5 -5
  95. package/build/cjs/public/experimental/filter-list.cjs +17 -17
  96. package/build/cjs/public/experimental/filter-list.css +350 -0
  97. package/build/cjs/public/experimental/filter-list.css.map +1 -1
  98. package/build/cjs/public/experimental/filter-list.d.cts +6 -2
  99. package/build/cjs/public/experimental/image-viewer.cjs +5 -5
  100. package/build/cjs/public/experimental/markdown-renderer.cjs +7 -7
  101. package/build/cjs/public/experimental/object-table.cjs +25 -25
  102. package/build/cjs/public/experimental/pdf-viewer.cjs +25 -25
  103. package/build/cjs/public/experimental/spreadsheet-viewer.cjs +5 -5
  104. package/build/cjs/public/experimental/tiff-renderer.cjs +7 -7
  105. package/build/cjs/public/experimental/video-viewer.cjs +5 -5
  106. package/build/cjs/public/experimental/xml-viewer.cjs +5 -5
  107. package/build/cjs/public/experimental.cjs +114 -114
  108. package/build/cjs/public/experimental.css +199 -0
  109. package/build/cjs/public/experimental.css.map +1 -1
  110. package/build/cjs/public/experimental.d.cts +2 -2
  111. package/build/cjs/public/filter-list.cjs +16 -16
  112. package/build/cjs/public/filter-list.css +350 -0
  113. package/build/cjs/public/filter-list.css.map +1 -1
  114. package/build/cjs/public/filter-list.d.cts +1 -1
  115. package/build/cjs/public/image-viewer.cjs +3 -3
  116. package/build/cjs/public/markdown-viewer.cjs +3 -3
  117. package/build/cjs/public/object-table.cjs +24 -24
  118. package/build/cjs/public/pdf-viewer.cjs +7 -7
  119. package/build/cjs/public/spreadsheet-viewer.cjs +3 -3
  120. package/build/cjs/public/tiff-viewer.cjs +3 -3
  121. package/build/cjs/public/video-viewer.cjs +3 -3
  122. package/build/cjs/public/xml-viewer.cjs +3 -3
  123. package/build/esm/filter-list/FilterListItemApi.js.map +1 -1
  124. package/build/esm/filter-list/base/inputs/DateRangeHistogramInput.js +14 -2
  125. package/build/esm/filter-list/base/inputs/DateRangeHistogramInput.js.map +1 -1
  126. package/build/esm/filter-list/base/inputs/RelativeDateBoundInput.js +156 -0
  127. package/build/esm/filter-list/base/inputs/RelativeDateBoundInput.js.map +1 -0
  128. package/build/esm/filter-list/base/inputs/RelativeDateBoundInput.module.css +299 -0
  129. package/build/esm/filter-list/base/inputs/RelativeDateRangeInput.js +52 -0
  130. package/build/esm/filter-list/base/inputs/RelativeDateRangeInput.js.map +1 -0
  131. package/build/esm/filter-list/base/inputs/RelativeModeToggle.js +35 -0
  132. package/build/esm/filter-list/base/inputs/RelativeModeToggle.js.map +1 -0
  133. package/build/esm/filter-list/base/inputs/shared.module.css +14 -0
  134. package/build/esm/filter-list/inputs/DateRangeFilterInput.js +55 -5
  135. package/build/esm/filter-list/inputs/DateRangeFilterInput.js.map +1 -1
  136. package/build/esm/filter-list/inputs/PropertyFilterInput.js +2 -1
  137. package/build/esm/filter-list/inputs/PropertyFilterInput.js.map +1 -1
  138. package/build/esm/filter-list/utils/filterStateToWhereClause.js +7 -4
  139. package/build/esm/filter-list/utils/filterStateToWhereClause.js.map +1 -1
  140. package/build/esm/filter-list/utils/resolveRelativeDate.js +75 -0
  141. package/build/esm/filter-list/utils/resolveRelativeDate.js.map +1 -0
  142. package/build/esm/filter-list/utils/summarizeFilterValue.js +6 -0
  143. package/build/esm/filter-list/utils/summarizeFilterValue.js.map +1 -1
  144. package/build/esm/public/experimental/filter-list.js +4 -0
  145. package/build/esm/public/experimental/filter-list.js.map +1 -1
  146. package/build/esm/public/filter-list.js.map +1 -1
  147. package/build/esm/util/UserAgent.js +1 -1
  148. package/build/esm/util/UserAgent.js.map +1 -1
  149. package/build/types/filter-list/FilterListItemApi.d.ts +43 -4
  150. package/build/types/filter-list/FilterListItemApi.d.ts.map +1 -1
  151. package/build/types/filter-list/base/inputs/DateRangeHistogramInput.d.ts +13 -1
  152. package/build/types/filter-list/base/inputs/DateRangeHistogramInput.d.ts.map +1 -1
  153. package/build/types/filter-list/base/inputs/RelativeDateBoundInput.d.ts +13 -0
  154. package/build/types/filter-list/base/inputs/RelativeDateBoundInput.d.ts.map +1 -0
  155. package/build/types/filter-list/base/inputs/RelativeDateRangeInput.d.ts +11 -0
  156. package/build/types/filter-list/base/inputs/RelativeDateRangeInput.d.ts.map +1 -0
  157. package/build/types/filter-list/base/inputs/RelativeModeToggle.d.ts +8 -0
  158. package/build/types/filter-list/base/inputs/RelativeModeToggle.d.ts.map +1 -0
  159. package/build/types/filter-list/inputs/DateRangeFilterInput.d.ts +2 -1
  160. package/build/types/filter-list/inputs/DateRangeFilterInput.d.ts.map +1 -1
  161. package/build/types/filter-list/inputs/PropertyFilterInput.d.ts.map +1 -1
  162. package/build/types/filter-list/utils/filterStateToWhereClause.d.ts.map +1 -1
  163. package/build/types/filter-list/utils/resolveRelativeDate.d.ts +21 -0
  164. package/build/types/filter-list/utils/resolveRelativeDate.d.ts.map +1 -0
  165. package/build/types/filter-list/utils/summarizeFilterValue.d.ts.map +1 -1
  166. package/build/types/public/experimental/filter-list.d.ts +4 -0
  167. package/build/types/public/experimental/filter-list.d.ts.map +1 -1
  168. package/build/types/public/filter-list.d.ts +1 -1
  169. package/build/types/public/filter-list.d.ts.map +1 -1
  170. package/package.json +8 -8
  171. package/build/cjs/chunk-3C574XJN.cjs.map +0 -1
  172. package/build/cjs/chunk-6MIMBFOQ.cjs +0 -11
  173. package/build/cjs/chunk-B4KQD2SF.cjs.map +0 -1
  174. package/build/cjs/chunk-C2TU7ODQ.cjs +0 -34
  175. package/build/cjs/chunk-C6GTKE26.cjs +0 -12
  176. package/build/cjs/chunk-J7LQAIRU.cjs +0 -11
  177. package/build/cjs/chunk-JNSHIKCQ.cjs.map +0 -1
  178. package/build/cjs/chunk-KFPTUFXM.cjs +0 -11
  179. package/build/cjs/chunk-NHQQ6JAW.cjs +0 -12
  180. package/build/cjs/chunk-NSCCMDOJ.cjs +0 -404
  181. package/build/cjs/chunk-NSCCMDOJ.cjs.map +0 -1
  182. package/build/cjs/chunk-RIE55H3T.cjs +0 -11
  183. package/build/cjs/chunk-TKZU2GLD.cjs +0 -48
  184. package/build/cjs/chunk-TMAQHJTC.cjs +0 -11
  185. package/build/cjs/chunk-WCOINODS.cjs +0 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @osdk/react-components
2
2
 
3
+ ## 0.58.1-main-f1b178d2b6aaa5013ba28dae0a518a2c077f552c
4
+
5
+ ### Patch Changes
6
+
7
+ - f6bcb14: Adds Relative date functionality to the DATE_RANGE filter. Add optional props to enable the relative mode, and relevant API input changes.
8
+ - @osdk/client@2.69.1-main-f1b178d2b6aaa5013ba28dae0a518a2c077f552c
9
+ - @osdk/api@2.69.1-main-f1b178d2b6aaa5013ba28dae0a518a2c077f552c
10
+ - @osdk/react@2.69.1-main-f1b178d2b6aaa5013ba28dae0a518a2c077f552c
11
+
3
12
  ## 0.58.0
4
13
 
5
14
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"FilterListItemApi.js","names":[],"sources":["FilterListItemApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n CompileTimeMetadata,\n ObjectTypeDefinition,\n PropertyKeys,\n WirePropertyTypes,\n} from \"@osdk/api\";\nimport type { ReactNode } from \"react\";\n\nimport type { CustomFilterState } from \"./types/CustomRendererTypes.js\";\nimport type { KeywordSearchFilterState } from \"./types/KeywordSearchTypes.js\";\nimport type {\n HasLinkFilterState,\n LinkedPropertyFilterState,\n} from \"./types/LinkedFilterTypes.js\";\n\n/**\n * Helper type to extract the property type from an ObjectTypeDefinition given a property key\n */\nexport type PropertyTypeFromKey<\n Q extends ObjectTypeDefinition,\n K extends PropertyKeys<Q>,\n> = CompileTimeMetadata<Q>[\"properties\"][K][\"type\"];\n\n/**\n * Fields shared by every filter definition, regardless of kind.\n */\nexport interface FilterDefinitionControls {\n /**\n * When `false`, the header monocle (search-values icon) is hidden even for\n * filter components that ordinarily support in-filter search. Useful for\n * `MULTI_SELECT`, which already has its own inline search field.\n *\n * @default true\n */\n searchField?: boolean;\n\n /**\n * Optional unique identifier for stable keying across filter reorders.\n * Set it explicitly when that derived value would collide, e.g. two filters on the\n * same property.\n *\n * This is the key used in `defaultFilterStates`; `getFilterKey(definition)`\n * returns it.\n *\n * @default a value derived from the definition (its `key`, or its link and property names)\n */\n id?: string;\n\n /**\n * Controls whether this filter is rendered.\n * When false, the filter is hidden but its state is preserved.\n * @default true\n */\n isVisible?: boolean;\n}\n\n/**\n * All available filter component types\n */\nexport type FilterComponentType =\n | \"LISTOGRAM\"\n | \"DATE_RANGE\"\n | \"NUMBER_RANGE\"\n | \"TEXT_TAGS\"\n | \"CONTAINS_TEXT\"\n | \"SINGLE_SELECT\"\n | \"MULTI_SELECT\"\n | \"SINGLE_DATE\"\n | \"MULTI_DATE\"\n | \"TIMELINE\"\n | \"TOGGLE\";\n\n/**\n * Gets valid component types for a given property type\n */\nexport type ValidComponentsForPropertyType<P extends WirePropertyTypes> =\n P extends \"boolean\"\n ? \"LISTOGRAM\" | \"SINGLE_SELECT\" | \"TOGGLE\"\n : P extends \"string\"\n ?\n | \"LISTOGRAM\"\n | \"TEXT_TAGS\"\n | \"CONTAINS_TEXT\"\n | \"SINGLE_SELECT\"\n | \"MULTI_SELECT\"\n : P extends \"datetime\" | \"timestamp\"\n ? \"DATE_RANGE\" | \"SINGLE_DATE\" | \"MULTI_DATE\" | \"TIMELINE\"\n : P extends\n | \"double\"\n | \"integer\"\n | \"long\"\n | \"float\"\n | \"short\"\n | \"byte\"\n | \"decimal\"\n ? \"NUMBER_RANGE\" | \"SINGLE_SELECT\" | \"MULTI_SELECT\"\n : never;\n\n/**\n * Union of all possible filter states\n */\nexport type FilterState =\n | ExactMatchFilterState<string | boolean>\n | DateRangeFilterState\n | ContainsTextFilterState\n | NumberRangeFilterState\n | SelectFilterState<string | boolean | number>\n | SelectFilterState<Date>\n | TimelineFilterState\n | ToggleFilterState\n | HasLinkFilterState\n | LinkedPropertyFilterState\n | KeywordSearchFilterState\n | CustomFilterState;\n\n/**\n * Maps component types to their corresponding state types\n */\nexport interface FilterStateByComponentType {\n LISTOGRAM: ExactMatchFilterState<string | boolean>;\n DATE_RANGE: DateRangeFilterState;\n TEXT_TAGS: ExactMatchFilterState<string>;\n CONTAINS_TEXT: ContainsTextFilterState;\n NUMBER_RANGE: NumberRangeFilterState;\n SINGLE_SELECT: SelectFilterState<string | boolean | number>;\n MULTI_SELECT: SelectFilterState<string | boolean | number>;\n SINGLE_DATE: SelectFilterState<Date>;\n MULTI_DATE: SelectFilterState<Date>;\n TIMELINE: TimelineFilterState;\n TOGGLE: ToggleFilterState;\n}\n\n/**\n * All filter state discriminator types\n */\nexport type FilterStateType =\n | \"EXACT_MATCH\"\n | \"DATE_RANGE\"\n | \"NUMBER_RANGE\"\n | \"CONTAINS_TEXT\"\n | \"SELECT\"\n | \"TIMELINE\"\n | \"TOGGLE\"\n | \"hasLink\"\n | \"linkedProperty\"\n | \"keywordSearch\"\n | \"custom\";\n\n/**\n * Base interface for all filter states\n * Contains common properties shared across all filter types\n */\nexport interface BaseFilterState {\n /**\n * The type of filter component\n */\n type: FilterStateType;\n\n /**\n * If true, the objects satisfying the filter are excluded\n * @default false\n */\n isExcluding?: boolean;\n\n /**\n * If true, include objects that have no value\n * @default false\n */\n includeNull?: boolean;\n}\n\nexport interface ExactMatchFilterState<\n T = string | boolean,\n> extends BaseFilterState {\n type: \"EXACT_MATCH\";\n values: T[];\n}\n\nexport interface DateRangeFilterState extends BaseFilterState {\n type: \"DATE_RANGE\";\n /**\n * The earliest date the user can select\n */\n minValue?: Date;\n /**\n * The latest date the user can select\n */\n maxValue?: Date;\n}\n\nexport interface ContainsTextFilterState extends BaseFilterState {\n type: \"CONTAINS_TEXT\";\n value?: string;\n}\n\nexport interface NumberRangeFilterState extends BaseFilterState {\n type: \"NUMBER_RANGE\";\n /**\n * Minimum numeric value (inclusive)\n */\n minValue?: number;\n /**\n * Maximum numeric value (inclusive)\n */\n maxValue?: number;\n}\n\n/**\n * Consolidated state type for select-based filters.\n * Used by SINGLE_SELECT, MULTI_SELECT, SINGLE_DATE, and MULTI_DATE.\n */\nexport interface SelectFilterState<\n T = string | boolean | number | Date,\n> extends BaseFilterState {\n type: \"SELECT\";\n selectedValues: T[];\n}\n\nexport interface TimelineFilterState extends BaseFilterState {\n type: \"TIMELINE\";\n startDate?: Date;\n endDate?: Date;\n granularity?: \"day\" | \"week\" | \"month\" | \"quarter\" | \"year\";\n}\n\nexport interface ToggleFilterState extends BaseFilterState {\n type: \"TOGGLE\";\n enabled: boolean;\n}\n\n/**\n * Optional date display formatter. Mixed into `PropertyFilterDefinition`\n * only when the property is `datetime` or `timestamp` — see\n * {@link PropertyFilterDateExtras}.\n *\n * `formatDate` overrides the displayed string everywhere the filter\n * surfaces a date: the shared `DateRangePicker` / `DatePicker` idle text,\n * the date-range histogram tooltip and period subtitle, the multi-date\n * chip text, and timeline labels. The picker's internal value remains\n * ISO `YYYY-MM-DD` so cross-locale viewers see a consistent input format\n * regardless of `formatDate`.\n *\n * Receives a `Date` in local time. If the property is a UTC ISO string and\n * you want a different timezone, do that conversion inside your callback.\n */\nexport interface DateFormattingProps {\n formatDate?: (date: Date) => string;\n}\n\n/**\n * Conditionally adds `formatDate` to a property filter definition only for\n * `datetime` / `timestamp` properties. For other property types this field\n * is typed as `never` so attempting to set it is a TypeScript error.\n */\nexport type PropertyFilterDateExtras<P extends WirePropertyTypes> = P extends\n | \"datetime\"\n | \"timestamp\"\n ? DateFormattingProps\n : { formatDate?: never };\n\ninterface PropertyFilterDefinitionBase<\n Q extends ObjectTypeDefinition,\n K extends PropertyKeys<Q> = PropertyKeys<Q>,\n C extends ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>> =\n ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>>,\n> extends FilterDefinitionControls {\n /**\n * Discriminator for filter definition type\n */\n type: \"PROPERTY\";\n\n /**\n * The property key to filter on\n */\n key: K;\n\n /**\n * Display label for the filter\n */\n label?: string;\n\n /**\n * The filter component type to render\n * Must be compatible with the property type derived from the key, see ValidComponentsForPropertyType\n */\n filterComponent: C;\n\n /**\n * Seeds the filter's state on mount, FilterList owns the state from then on\n *\n * @default undefined (filter starts empty)\n */\n defaultFilterState?: FilterStateByComponentType[C];\n\n /**\n * @deprecated Rename to `defaultFilterState`.\n */\n filterState?: FilterStateByComponentType[C];\n\n /**\n * Maps filter values to colors for visual differentiation.\n * Used by LISTOGRAM (per-row bar colors).\n */\n colorMap?: Record<string, string>;\n\n /**\n * Configuration for LISTOGRAM display mode.\n * Only applies when filterComponent is \"LISTOGRAM\".\n */\n listogramConfig?: {\n displayMode?: \"full\" | \"count\" | \"minimal\";\n /**\n * Number of items shown before \"View all\" link appears\n * @default 5\n */\n maxVisibleItems?: number;\n };\n\n /**\n * Custom display function for filter values.\n * Replaces the default string display in dropdown items, chips, and listogram rows.\n * When the function returns a string, that string is also used for search matching\n * within filter dropdowns. When it returns a non-string `ReactNode`, search falls\n * back to the raw value.\n */\n renderValue?: (value: string) => ReactNode;\n\n /**\n * Show aggregation counts next to filter option values.\n * Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT components.\n * @default true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT\n */\n showCount?: boolean;\n\n /**\n * When true, clicking a bar in the histogram replaces the filter range\n * with that bucket's `[min, max]`. Only applies to histogram-rendering\n * filter components (`NUMBER_RANGE` and `DATE_RANGE`); ignored on other\n * component types.\n *\n * Click replaces the current range — clicking a second bar discards the\n * previous selection. Multi-bucket selection / shift+click union is NOT\n * supported in v1.\n *\n * @default false\n */\n clickToFilter?: boolean;\n}\n\n/**\n * A property filter definition specifies configuration for filtering on a single property\n *\n * The component type C must be compatible with the property type derived from the key.\n * For example, boolean properties can only use LISTOGRAM or SINGLE_SELECT,\n * while string properties can use LISTOGRAM, TEXT_TAGS, CONTAINS_TEXT, SINGLE_SELECT, or MULTI_SELECT.\n *\n * Date and datetime properties may additionally specify `formatDate` — see\n * {@link PropertyFilterDateExtras}.\n */\nexport type PropertyFilterDefinition<\n Q extends ObjectTypeDefinition,\n K extends PropertyKeys<Q> = PropertyKeys<Q>,\n C extends ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>> =\n ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>>,\n> = PropertyFilterDefinitionBase<Q, K, C> &\n PropertyFilterDateExtras<PropertyTypeFromKey<Q, K>>;\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"FilterListItemApi.js","names":[],"sources":["FilterListItemApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n CompileTimeMetadata,\n ObjectTypeDefinition,\n PropertyKeys,\n WirePropertyTypes,\n} from \"@osdk/api\";\nimport type { ReactNode } from \"react\";\n\nimport type { CustomFilterState } from \"./types/CustomRendererTypes.js\";\nimport type { KeywordSearchFilterState } from \"./types/KeywordSearchTypes.js\";\nimport type {\n HasLinkFilterState,\n LinkedPropertyFilterState,\n} from \"./types/LinkedFilterTypes.js\";\n\n/**\n * Helper type to extract the property type from an ObjectTypeDefinition given a property key\n */\nexport type PropertyTypeFromKey<\n Q extends ObjectTypeDefinition,\n K extends PropertyKeys<Q>,\n> = CompileTimeMetadata<Q>[\"properties\"][K][\"type\"];\n\n/**\n * Fields shared by every filter definition, regardless of kind.\n */\nexport interface FilterDefinitionControls {\n /**\n * When `false`, the header monocle (search-values icon) is hidden even for\n * filter components that ordinarily support in-filter search. Useful for\n * `MULTI_SELECT`, which already has its own inline search field.\n *\n * @default true\n */\n searchField?: boolean;\n\n /**\n * Optional unique identifier for stable keying across filter reorders.\n * Set it explicitly when that derived value would collide, e.g. two filters on the\n * same property.\n *\n * This is the key used in `defaultFilterStates`; `getFilterKey(definition)`\n * returns it.\n *\n * @default a value derived from the definition (its `key`, or its link and property names)\n */\n id?: string;\n\n /**\n * Controls whether this filter is rendered.\n * When false, the filter is hidden but its state is preserved.\n * @default true\n */\n isVisible?: boolean;\n}\n\n/**\n * All available filter component types\n */\nexport type FilterComponentType =\n | \"LISTOGRAM\"\n | \"DATE_RANGE\"\n | \"NUMBER_RANGE\"\n | \"TEXT_TAGS\"\n | \"CONTAINS_TEXT\"\n | \"SINGLE_SELECT\"\n | \"MULTI_SELECT\"\n | \"SINGLE_DATE\"\n | \"MULTI_DATE\"\n | \"TIMELINE\"\n | \"TOGGLE\";\n\n/**\n * Gets valid component types for a given property type\n */\nexport type ValidComponentsForPropertyType<P extends WirePropertyTypes> =\n P extends \"boolean\"\n ? \"LISTOGRAM\" | \"SINGLE_SELECT\" | \"TOGGLE\"\n : P extends \"string\"\n ?\n | \"LISTOGRAM\"\n | \"TEXT_TAGS\"\n | \"CONTAINS_TEXT\"\n | \"SINGLE_SELECT\"\n | \"MULTI_SELECT\"\n : P extends \"datetime\" | \"timestamp\"\n ? \"DATE_RANGE\" | \"SINGLE_DATE\" | \"MULTI_DATE\" | \"TIMELINE\"\n : P extends\n | \"double\"\n | \"integer\"\n | \"long\"\n | \"float\"\n | \"short\"\n | \"byte\"\n | \"decimal\"\n ? \"NUMBER_RANGE\" | \"SINGLE_SELECT\" | \"MULTI_SELECT\"\n : never;\n\n/**\n * Union of all possible filter states\n */\nexport type FilterState =\n | ExactMatchFilterState<string | boolean>\n | DateRangeFilterState\n | ContainsTextFilterState\n | NumberRangeFilterState\n | SelectFilterState<string | boolean | number>\n | SelectFilterState<Date>\n | TimelineFilterState\n | ToggleFilterState\n | HasLinkFilterState\n | LinkedPropertyFilterState\n | KeywordSearchFilterState\n | CustomFilterState;\n\n/**\n * Maps component types to their corresponding state types\n */\nexport interface FilterStateByComponentType {\n LISTOGRAM: ExactMatchFilterState<string | boolean>;\n DATE_RANGE: DateRangeFilterState;\n TEXT_TAGS: ExactMatchFilterState<string>;\n CONTAINS_TEXT: ContainsTextFilterState;\n NUMBER_RANGE: NumberRangeFilterState;\n SINGLE_SELECT: SelectFilterState<string | boolean | number>;\n MULTI_SELECT: SelectFilterState<string | boolean | number>;\n SINGLE_DATE: SelectFilterState<Date>;\n MULTI_DATE: SelectFilterState<Date>;\n TIMELINE: TimelineFilterState;\n TOGGLE: ToggleFilterState;\n}\n\n/**\n * All filter state discriminator types\n */\nexport type FilterStateType =\n | \"EXACT_MATCH\"\n | \"DATE_RANGE\"\n | \"NUMBER_RANGE\"\n | \"CONTAINS_TEXT\"\n | \"SELECT\"\n | \"TIMELINE\"\n | \"TOGGLE\"\n | \"hasLink\"\n | \"linkedProperty\"\n | \"keywordSearch\"\n | \"custom\";\n\n/**\n * Base interface for all filter states\n * Contains common properties shared across all filter types\n */\nexport interface BaseFilterState {\n /**\n * The type of filter component\n */\n type: FilterStateType;\n\n /**\n * If true, the objects satisfying the filter are excluded\n * @default false\n */\n isExcluding?: boolean;\n\n /**\n * If true, include objects that have no value\n * @default false\n */\n includeNull?: boolean;\n}\n\nexport interface ExactMatchFilterState<\n T = string | boolean,\n> extends BaseFilterState {\n type: \"EXACT_MATCH\";\n values: T[];\n}\n\n/**\n * Describes one bound of a relative date range.\n *\n * Combined with a direction this produces an absolute `Date` anchored to \"now\".\n * For example `{ count: 7, unit: \"days\", direction: \"ago\" }` resolves to 7 days\n * before the current time.\n */\nexport interface RelativeDateBound {\n /** Number of units (e.g. 7 for \"7 days ago\"). */\n count: number;\n /** Time unit. */\n unit: \"days\" | \"weeks\" | \"months\" | \"years\";\n /** Direction relative to now. */\n direction: \"ago\" | \"fromNow\";\n}\n\n/**\n * Groups the two relative bounds for a `DATE_RANGE` filter.\n * Presence of this object on the filter state means relative mode is ON.\n * `null` for either bound means \"Indefinitely\" (no constraint on that side).\n */\nexport interface RelativeDateState {\n relativeMin: RelativeDateBound | null;\n relativeMax: RelativeDateBound | null;\n}\n\nexport interface DateRangeFilterState extends BaseFilterState {\n type: \"DATE_RANGE\";\n /**\n * The earliest date the user can select\n */\n minValue?: Date;\n /**\n * The latest date the user can select\n */\n maxValue?: Date;\n\n /**\n * When present, the filter is in relative-date mode.\n * When `undefined`, the filter uses absolute `minValue` / `maxValue`.\n */\n relativeState?: RelativeDateState;\n}\n\nexport interface ContainsTextFilterState extends BaseFilterState {\n type: \"CONTAINS_TEXT\";\n value?: string;\n}\n\nexport interface NumberRangeFilterState extends BaseFilterState {\n type: \"NUMBER_RANGE\";\n /**\n * Minimum numeric value (inclusive)\n */\n minValue?: number;\n /**\n * Maximum numeric value (inclusive)\n */\n maxValue?: number;\n}\n\n/**\n * Consolidated state type for select-based filters.\n * Used by SINGLE_SELECT, MULTI_SELECT, SINGLE_DATE, and MULTI_DATE.\n */\nexport interface SelectFilterState<\n T = string | boolean | number | Date,\n> extends BaseFilterState {\n type: \"SELECT\";\n selectedValues: T[];\n}\n\nexport interface TimelineFilterState extends BaseFilterState {\n type: \"TIMELINE\";\n startDate?: Date;\n endDate?: Date;\n granularity?: \"day\" | \"week\" | \"month\" | \"quarter\" | \"year\";\n}\n\nexport interface ToggleFilterState extends BaseFilterState {\n type: \"TOGGLE\";\n enabled: boolean;\n}\n\n/**\n * Optional date display formatter. Mixed into `PropertyFilterDefinition`\n * only when the property is `datetime` or `timestamp` — see\n * {@link PropertyFilterDateExtras}.\n *\n * `formatDate` overrides the displayed string everywhere the filter\n * surfaces a date: the shared `DateRangePicker` / `DatePicker` idle text,\n * the date-range histogram tooltip and period subtitle, the multi-date\n * chip text, and timeline labels. The picker's internal value remains\n * ISO `YYYY-MM-DD` so cross-locale viewers see a consistent input format\n * regardless of `formatDate`.\n *\n * Receives a `Date` in local time. If the property is a UTC ISO string and\n * you want a different timezone, do that conversion inside your callback.\n */\nexport interface DateFormattingProps {\n formatDate?: (date: Date) => string;\n}\n\n/**\n * Props specific to `DATE_RANGE` filters on `datetime` / `timestamp`\n * properties. Controls whether the user can switch to a relative-date\n * input mode.\n */\nexport interface DateRangeRelativeProps {\n /**\n * When `true`, the `DATE_RANGE` filter shows an Absolute / Relative toggle.\n * Has no effect on filter components other than `DATE_RANGE`.\n *\n * @default false\n */\n enableRelativeMode?: boolean;\n}\n\nexport type PropertyFilterDateExtras<P extends WirePropertyTypes> = P extends\n | \"datetime\"\n | \"timestamp\"\n ? DateFormattingProps & DateRangeRelativeProps\n : { formatDate?: never; enableRelativeMode?: never };\n\ninterface PropertyFilterDefinitionBase<\n Q extends ObjectTypeDefinition,\n K extends PropertyKeys<Q> = PropertyKeys<Q>,\n C extends ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>> =\n ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>>,\n> extends FilterDefinitionControls {\n /**\n * Discriminator for filter definition type\n */\n type: \"PROPERTY\";\n\n /**\n * The property key to filter on\n */\n key: K;\n\n /**\n * Display label for the filter\n */\n label?: string;\n\n /**\n * The filter component type to render\n * Must be compatible with the property type derived from the key, see ValidComponentsForPropertyType\n */\n filterComponent: C;\n\n /**\n * Seeds the filter's state on mount, FilterList owns the state from then on\n *\n * @default undefined (filter starts empty)\n */\n defaultFilterState?: FilterStateByComponentType[C];\n\n /**\n * @deprecated Rename to `defaultFilterState`.\n */\n filterState?: FilterStateByComponentType[C];\n\n /**\n * Maps filter values to colors for visual differentiation.\n * Used by LISTOGRAM (per-row bar colors).\n */\n colorMap?: Record<string, string>;\n\n /**\n * Configuration for LISTOGRAM display mode.\n * Only applies when filterComponent is \"LISTOGRAM\".\n */\n listogramConfig?: {\n displayMode?: \"full\" | \"count\" | \"minimal\";\n /**\n * Number of items shown before \"View all\" link appears\n * @default 5\n */\n maxVisibleItems?: number;\n };\n\n /**\n * Custom display function for filter values.\n * Replaces the default string display in dropdown items, chips, and listogram rows.\n * When the function returns a string, that string is also used for search matching\n * within filter dropdowns. When it returns a non-string `ReactNode`, search falls\n * back to the raw value.\n */\n renderValue?: (value: string) => ReactNode;\n\n /**\n * Show aggregation counts next to filter option values.\n * Applies to LISTOGRAM, SINGLE_SELECT, and MULTI_SELECT components.\n * @default true for LISTOGRAM and MULTI_SELECT, false for SINGLE_SELECT\n */\n showCount?: boolean;\n\n /**\n * When true, clicking a bar in the histogram replaces the filter range\n * with that bucket's `[min, max]`. Only applies to histogram-rendering\n * filter components (`NUMBER_RANGE` and `DATE_RANGE`); ignored on other\n * component types.\n *\n * Click replaces the current range — clicking a second bar discards the\n * previous selection. Multi-bucket selection / shift+click union is NOT\n * supported in v1.\n *\n * @default false\n */\n clickToFilter?: boolean;\n}\n\n/**\n * A property filter definition specifies configuration for filtering on a single property\n *\n * The component type C must be compatible with the property type derived from the key.\n * For example, boolean properties can only use LISTOGRAM or SINGLE_SELECT,\n * while string properties can use LISTOGRAM, TEXT_TAGS, CONTAINS_TEXT, SINGLE_SELECT, or MULTI_SELECT.\n *\n * Date and datetime properties may additionally specify `formatDate` — see\n * {@link PropertyFilterDateExtras}.\n */\nexport type PropertyFilterDefinition<\n Q extends ObjectTypeDefinition,\n K extends PropertyKeys<Q> = PropertyKeys<Q>,\n C extends ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>> =\n ValidComponentsForPropertyType<PropertyTypeFromKey<Q, K>>,\n> = PropertyFilterDefinitionBase<Q, K, C> &\n PropertyFilterDateExtras<PropertyTypeFromKey<Q, K>>;\n"],"mappings":"","ignoreList":[]}
@@ -19,6 +19,8 @@ import React, { memo, useMemo } from "react";
19
19
  import { formatDateForInput } from "../../../shared/dateUtils.js";
20
20
  import { createDateHistogramBuckets } from "./createDateHistogramBuckets.js";
21
21
  import { RangeInput } from "./RangeInput.js";
22
+ import { RelativeDateRangeInput } from "./RelativeDateRangeInput.js";
23
+ import { RelativeModeToggle } from "./RelativeModeToggle.js";
22
24
  const defaultDateConfig = {
23
25
  inputType: "date",
24
26
  formatValue: formatDateForInput,
@@ -32,6 +34,10 @@ const defaultDateConfig = {
32
34
  function DateRangeHistogramInputInner({
33
35
  formatDate,
34
36
  valueCountPairs,
37
+ enableRelativeMode,
38
+ relativeState,
39
+ onToggleRelative,
40
+ onRelativeChange,
35
41
  ...rest
36
42
  }) {
37
43
  const config = useMemo(() => formatDate != null ? {
@@ -71,11 +77,17 @@ function DateRangeHistogramInputInner({
71
77
  subtitle
72
78
  };
73
79
  }, [valueCountPairs, formatDate]);
74
- return /*#__PURE__*/React.createElement(RangeInput, _extends({}, rest, {
80
+ return /*#__PURE__*/React.createElement(React.Fragment, null, enableRelativeMode === true && onToggleRelative != null && /*#__PURE__*/React.createElement(RelativeModeToggle, {
81
+ checked: relativeState != null,
82
+ onCheckedChange: onToggleRelative
83
+ }), enableRelativeMode === true && relativeState != null && onRelativeChange ? /*#__PURE__*/React.createElement(RelativeDateRangeInput, {
84
+ relativeState: relativeState,
85
+ onRelativeChange: onRelativeChange
86
+ }) : /*#__PURE__*/React.createElement(RangeInput, _extends({}, rest, {
75
87
  valueCountPairs: valueCountPairs,
76
88
  config: config,
77
89
  histogramData: histogramData
78
- }));
90
+ })));
79
91
  }
80
92
  export const DateRangeHistogramInput = /*#__PURE__*/memo(DateRangeHistogramInputInner);
81
93
  //# sourceMappingURL=DateRangeHistogramInput.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DateRangeHistogramInput.js","names":["React","memo","useMemo","formatDateForInput","createDateHistogramBuckets","RangeInput","defaultDateConfig","inputType","formatValue","parseValue","undefined","toNumber","d","getTime","fromNumber","t","Date","minLabel","maxLabel","formatTooltip","min","max","count","toLocaleString","DateRangeHistogramInputInner","formatDate","valueCountPairs","rest","config","histogramData","length","minMs","Infinity","maxMs","value","Number","isFinite","buckets","subtitle","createElement","_extends","DateRangeHistogramInput"],"sources":["DateRangeHistogramInput.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { memo, useMemo } from \"react\";\n\nimport { formatDateForInput } from \"../../../shared/dateUtils.js\";\nimport { createDateHistogramBuckets } from \"./createDateHistogramBuckets.js\";\nimport { RangeInput, type RangeInputConfig } from \"./RangeInput.js\";\n\nconst defaultDateConfig: RangeInputConfig<Date> = {\n inputType: \"date\",\n formatValue: formatDateForInput,\n parseValue: () => undefined,\n toNumber: (d) => d.getTime(),\n fromNumber: (t) => new Date(t),\n minLabel: \"From\",\n maxLabel: \"To\",\n formatTooltip: (min, max, count) =>\n `${formatDateForInput(min)} - ${formatDateForInput(\n max,\n )}: ${count.toLocaleString()}`,\n};\n\ninterface DateRangeHistogramInputProps {\n valueCountPairs: Array<{ value: Date; count: number }>;\n isLoading: boolean;\n minValue: Date | undefined;\n maxValue: Date | undefined;\n onChange: (min: Date | undefined, max: Date | undefined) => void;\n showHistogram?: boolean;\n className?: string;\n style?: React.CSSProperties;\n /**\n * Consumer-provided display formatter. Routes through the shared\n * `DateRangePicker`'s idle text, the histogram tooltip, and the period\n * subtitle.\n * The picker's internal value remains ISO `YYYY-MM-DD`.\n */\n formatDate?: (date: Date) => string;\n clickToFilter?: boolean;\n}\n\nfunction DateRangeHistogramInputInner({\n formatDate,\n valueCountPairs,\n ...rest\n}: DateRangeHistogramInputProps): React.ReactElement {\n const config = useMemo<RangeInputConfig<Date>>(\n () =>\n formatDate != null\n ? {\n ...defaultDateConfig,\n formatDate,\n formatTooltip: (min, max, count) =>\n `${formatDate(min)} - ${formatDate(\n max,\n )}: ${count.toLocaleString()}`,\n }\n : defaultDateConfig,\n [formatDate],\n );\n\n const histogramData = useMemo(() => {\n if (valueCountPairs.length === 0) {\n return undefined;\n }\n let minMs = Infinity;\n let maxMs = -Infinity;\n for (const { value } of valueCountPairs) {\n const t = value.getTime();\n if (t < minMs) {\n minMs = t;\n }\n if (t > maxMs) {\n maxMs = t;\n }\n }\n if (!Number.isFinite(minMs) || !Number.isFinite(maxMs)) {\n return undefined;\n }\n const { buckets, subtitle } = createDateHistogramBuckets(\n valueCountPairs,\n { min: new Date(minMs), max: new Date(maxMs) },\n formatDate,\n );\n return { buckets, subtitle };\n }, [valueCountPairs, formatDate]);\n\n return (\n <RangeInput\n {...rest}\n valueCountPairs={valueCountPairs}\n config={config}\n histogramData={histogramData}\n />\n );\n}\n\nexport const DateRangeHistogramInput = memo(\n DateRangeHistogramInputInner,\n) as typeof DateRangeHistogramInputInner;\n"],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,KAAK,IAAIC,IAAI,EAAEC,OAAO,QAAQ,OAAO;AAE5C,SAASC,kBAAkB,QAAQ,8BAA8B;AACjE,SAASC,0BAA0B,QAAQ,iCAAiC;AAC5E,SAASC,UAAU,QAA+B,iBAAiB;AAEnE,MAAMC,iBAAyC,GAAG;EAChDC,SAAS,EAAE,MAAM;EACjBC,WAAW,EAAEL,kBAAkB;EAC/BM,UAAU,EAAEA,CAAA,KAAMC,SAAS;EAC3BC,QAAQ,EAAGC,CAAC,IAAKA,CAAC,CAACC,OAAO,CAAC,CAAC;EAC5BC,UAAU,EAAGC,CAAC,IAAK,IAAIC,IAAI,CAACD,CAAC,CAAC;EAC9BE,QAAQ,EAAE,MAAM;EAChBC,QAAQ,EAAE,IAAI;EACdC,aAAa,EAAEA,CAACC,GAAG,EAAEC,GAAG,EAAEC,KAAK,KAC7B,GAAGnB,kBAAkB,CAACiB,GAAG,CAAC,MAAMjB,kBAAkB,CAChDkB,GACF,CAAC,KAAKC,KAAK,CAACC,cAAc,CAAC,CAAC;AAChC,CAAC;AAqBD,SAASC,4BAA4BA,CAAC;EACpCC,UAAU;EACVC,eAAe;EACf,GAAGC;AACyB,CAAC,EAAsB;EACnD,MAAMC,MAAM,GAAG1B,OAAO,CACpB,MACEuB,UAAU,IAAI,IAAI,GACd;IACE,GAAGnB,iBAAiB;IACpBmB,UAAU;IACVN,aAAa,EAAEA,CAACC,GAAG,EAAEC,GAAG,EAAEC,KAAK,KAC7B,GAAGG,UAAU,CAACL,GAAG,CAAC,MAAMK,UAAU,CAChCJ,GACF,CAAC,KAAKC,KAAK,CAACC,cAAc,CAAC,CAAC;EAChC,CAAC,GACDjB,iBAAiB,EACvB,CAACmB,UAAU,CACb,CAAC;EAED,MAAMI,aAAa,GAAG3B,OAAO,CAAC,MAAM;IAClC,IAAIwB,eAAe,CAACI,MAAM,KAAK,CAAC,EAAE;MAChC,OAAOpB,SAAS;IAClB;IACA,IAAIqB,KAAK,GAAGC,QAAQ;IACpB,IAAIC,KAAK,GAAG,CAACD,QAAQ;IACrB,KAAK,MAAM;MAAEE;IAAM,CAAC,IAAIR,eAAe,EAAE;MACvC,MAAMX,CAAC,GAAGmB,KAAK,CAACrB,OAAO,CAAC,CAAC;MACzB,IAAIE,CAAC,GAAGgB,KAAK,EAAE;QACbA,KAAK,GAAGhB,CAAC;MACX;MACA,IAAIA,CAAC,GAAGkB,KAAK,EAAE;QACbA,KAAK,GAAGlB,CAAC;MACX;IACF;IACA,IAAI,CAACoB,MAAM,CAACC,QAAQ,CAACL,KAAK,CAAC,IAAI,CAACI,MAAM,CAACC,QAAQ,CAACH,KAAK,CAAC,EAAE;MACtD,OAAOvB,SAAS;IAClB;IACA,MAAM;MAAE2B,OAAO;MAAEC;IAAS,CAAC,GAAGlC,0BAA0B,CACtDsB,eAAe,EACf;MAAEN,GAAG,EAAE,IAAIJ,IAAI,CAACe,KAAK,CAAC;MAAEV,GAAG,EAAE,IAAIL,IAAI,CAACiB,KAAK;IAAE,CAAC,EAC9CR,UACF,CAAC;IACD,OAAO;MAAEY,OAAO;MAAEC;IAAS,CAAC;EAC9B,CAAC,EAAE,CAACZ,eAAe,EAAED,UAAU,CAAC,CAAC;EAEjC,oBACEzB,KAAA,CAAAuC,aAAA,CAAClC,UAAU,EAAAmC,QAAA,KACLb,IAAI;IACRD,eAAe,EAAEA,eAAgB;IACjCE,MAAM,EAAEA,MAAO;IACfC,aAAa,EAAEA;EAAc,EAC9B,CAAC;AAEN;AAEA,OAAO,MAAMY,uBAAuB,gBAAGxC,IAAI,CACzCuB,4BACF,CAAwC","ignoreList":[]}
1
+ {"version":3,"file":"DateRangeHistogramInput.js","names":["React","memo","useMemo","formatDateForInput","createDateHistogramBuckets","RangeInput","RelativeDateRangeInput","RelativeModeToggle","defaultDateConfig","inputType","formatValue","parseValue","undefined","toNumber","d","getTime","fromNumber","t","Date","minLabel","maxLabel","formatTooltip","min","max","count","toLocaleString","DateRangeHistogramInputInner","formatDate","valueCountPairs","enableRelativeMode","relativeState","onToggleRelative","onRelativeChange","rest","config","histogramData","length","minMs","Infinity","maxMs","value","Number","isFinite","buckets","subtitle","createElement","Fragment","checked","onCheckedChange","_extends","DateRangeHistogramInput"],"sources":["DateRangeHistogramInput.tsx"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { memo, useMemo } from \"react\";\n\nimport { formatDateForInput } from \"../../../shared/dateUtils.js\";\nimport type { RelativeDateState } from \"../../FilterListItemApi.js\";\nimport { createDateHistogramBuckets } from \"./createDateHistogramBuckets.js\";\nimport { RangeInput, type RangeInputConfig } from \"./RangeInput.js\";\nimport { RelativeDateRangeInput } from \"./RelativeDateRangeInput.js\";\nimport { RelativeModeToggle } from \"./RelativeModeToggle.js\";\n\nconst defaultDateConfig: RangeInputConfig<Date> = {\n inputType: \"date\",\n formatValue: formatDateForInput,\n parseValue: () => undefined,\n toNumber: (d) => d.getTime(),\n fromNumber: (t) => new Date(t),\n minLabel: \"From\",\n maxLabel: \"To\",\n formatTooltip: (min, max, count) =>\n `${formatDateForInput(min)} - ${formatDateForInput(\n max,\n )}: ${count.toLocaleString()}`,\n};\n\ninterface DateRangeHistogramInputProps {\n valueCountPairs: Array<{ value: Date; count: number }>;\n isLoading: boolean;\n minValue: Date | undefined;\n maxValue: Date | undefined;\n onChange: (min: Date | undefined, max: Date | undefined) => void;\n showHistogram?: boolean;\n className?: string;\n style?: React.CSSProperties;\n /**\n * Consumer-provided display formatter. Routes through the shared\n * `DateRangePicker`'s idle text, the histogram tooltip, and the period\n * subtitle.\n * The picker's internal value remains ISO `YYYY-MM-DD`.\n */\n formatDate?: (date: Date) => string;\n clickToFilter?: boolean;\n\n /**\n * When `true`, renders an Absolute / Relative toggle above the histogram.\n * @default false\n */\n enableRelativeMode?: boolean;\n /** Current relative state. Present = relative mode ON. */\n relativeState?: RelativeDateState;\n /** Called when the Absolute/Relative toggle changes. */\n onToggleRelative?: (checked: boolean) => void;\n /** Called when either relative bound changes. */\n onRelativeChange?: (relativeState: RelativeDateState) => void;\n}\n\nfunction DateRangeHistogramInputInner({\n formatDate,\n valueCountPairs,\n enableRelativeMode,\n relativeState,\n onToggleRelative,\n onRelativeChange,\n ...rest\n}: DateRangeHistogramInputProps): React.ReactElement {\n const config = useMemo<RangeInputConfig<Date>>(\n () =>\n formatDate != null\n ? {\n ...defaultDateConfig,\n formatDate,\n formatTooltip: (min, max, count) =>\n `${formatDate(min)} - ${formatDate(\n max,\n )}: ${count.toLocaleString()}`,\n }\n : defaultDateConfig,\n [formatDate],\n );\n\n const histogramData = useMemo(() => {\n if (valueCountPairs.length === 0) {\n return undefined;\n }\n let minMs = Infinity;\n let maxMs = -Infinity;\n for (const { value } of valueCountPairs) {\n const t = value.getTime();\n if (t < minMs) {\n minMs = t;\n }\n if (t > maxMs) {\n maxMs = t;\n }\n }\n if (!Number.isFinite(minMs) || !Number.isFinite(maxMs)) {\n return undefined;\n }\n const { buckets, subtitle } = createDateHistogramBuckets(\n valueCountPairs,\n { min: new Date(minMs), max: new Date(maxMs) },\n formatDate,\n );\n return { buckets, subtitle };\n }, [valueCountPairs, formatDate]);\n\n const showRelativeUI = enableRelativeMode === true && relativeState != null;\n\n return (\n <>\n {enableRelativeMode === true && onToggleRelative != null && (\n <RelativeModeToggle\n checked={relativeState != null}\n onCheckedChange={onToggleRelative}\n />\n )}\n\n {showRelativeUI && onRelativeChange ? (\n <RelativeDateRangeInput\n relativeState={relativeState}\n onRelativeChange={onRelativeChange}\n />\n ) : (\n <RangeInput\n {...rest}\n valueCountPairs={valueCountPairs}\n config={config}\n histogramData={histogramData}\n />\n )}\n </>\n );\n}\n\nexport const DateRangeHistogramInput = memo(\n DateRangeHistogramInputInner,\n) as typeof DateRangeHistogramInputInner;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,156 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { Input } from "@base-ui/react/input";
18
+ import { Popover } from "@base-ui/react/popover";
19
+ import { Radio } from "@base-ui/react/radio";
20
+ import { RadioGroup } from "@base-ui/react/radio-group";
21
+ import { CaretDown } from "@blueprintjs/icons";
22
+ import React, { memo, useCallback, useId } from "react";
23
+ import { Select } from "../../../base-components/select/Select.js";
24
+ import { formatRelativeBound } from "../../utils/resolveRelativeDate.js";
25
+ import styles from "./RelativeDateBoundInput.module.css.js";
26
+ const UNIT_LABELS = {
27
+ days: "day(s)",
28
+ weeks: "week(s)",
29
+ months: "month(s)",
30
+ years: "year(s)"
31
+ };
32
+ const DIRECTION_LABELS = {
33
+ ago: "ago",
34
+ fromNow: "from now"
35
+ };
36
+ const DEFAULT_BOUND = {
37
+ count: 0,
38
+ unit: "days",
39
+ direction: "ago"
40
+ };
41
+ function RelativeDateBoundInputInner({
42
+ value,
43
+ onChange,
44
+ placeholder
45
+ }) {
46
+ const labelId = useId();
47
+ const mode = value != null ? "custom" : "indefinitely";
48
+ const currentBound = value ?? DEFAULT_BOUND;
49
+ const displayText = value != null ? formatRelativeBound(value) : undefined;
50
+ const handleModeChange = useCallback(nextMode => {
51
+ if (nextMode === "indefinitely") {
52
+ onChange(null);
53
+ } else {
54
+ // Intentional: switching from Indefinitely to Custom resets to
55
+ // DEFAULT_BOUND. The previous custom value is not preserved because
56
+ // Indefinitely clears the bound (value becomes null).
57
+ onChange(currentBound);
58
+ }
59
+ }, [onChange, currentBound]);
60
+ const handleCountChange = useCallback(e => {
61
+ const parsed = parseInt(e.target.value, 10);
62
+ const count = Number.isNaN(parsed) || parsed < 0 ? 0 : parsed;
63
+ onChange({
64
+ ...currentBound,
65
+ count
66
+ });
67
+ }, [onChange, currentBound]);
68
+ const handleUnitChange = useCallback(nextUnit => {
69
+ if (nextUnit != null) {
70
+ onChange({
71
+ ...currentBound,
72
+ unit: nextUnit
73
+ });
74
+ }
75
+ }, [onChange, currentBound]);
76
+ const handleDirectionChange = useCallback(nextDirection => {
77
+ if (nextDirection != null) {
78
+ onChange({
79
+ ...currentBound,
80
+ direction: nextDirection
81
+ });
82
+ }
83
+ }, [onChange, currentBound]);
84
+ const isCustom = mode === "custom";
85
+ return /*#__PURE__*/React.createElement(Popover.Root, null, /*#__PURE__*/React.createElement(Popover.Trigger, {
86
+ className: styles.trigger
87
+ }, /*#__PURE__*/React.createElement("div", {
88
+ className: styles.triggerValueContainer
89
+ }, /*#__PURE__*/React.createElement("span", {
90
+ className: displayText != null ? styles.triggerValue : styles.triggerPlaceholder
91
+ }, displayText ?? placeholder)), /*#__PURE__*/React.createElement("span", {
92
+ className: styles.triggerIcon
93
+ }, /*#__PURE__*/React.createElement(CaretDown, null))), /*#__PURE__*/React.createElement(Popover.Portal, null, /*#__PURE__*/React.createElement(Popover.Positioner, {
94
+ className: styles.positioner,
95
+ sideOffset: 4
96
+ }, /*#__PURE__*/React.createElement(Popover.Popup, {
97
+ className: styles.popover
98
+ }, /*#__PURE__*/React.createElement(RadioGroup, {
99
+ className: styles.radioGroup,
100
+ value: mode,
101
+ onValueChange: handleModeChange,
102
+ "aria-labelledby": labelId
103
+ }, /*#__PURE__*/React.createElement("div", {
104
+ className: styles.radioItem
105
+ }, /*#__PURE__*/React.createElement(Radio.Root, {
106
+ value: "custom",
107
+ className: styles.radioRoot,
108
+ "aria-label": `${placeholder} custom`
109
+ }, /*#__PURE__*/React.createElement(Radio.Indicator, {
110
+ className: styles.radioIndicator
111
+ })), /*#__PURE__*/React.createElement("div", {
112
+ className: styles.customRow
113
+ }, /*#__PURE__*/React.createElement(Input, {
114
+ type: "number",
115
+ className: styles.countInput,
116
+ value: isCustom ? String(currentBound.count) : "0",
117
+ onChange: handleCountChange,
118
+ disabled: !isCustom,
119
+ min: 0,
120
+ "aria-label": `${placeholder} count`
121
+ }), /*#__PURE__*/React.createElement("div", {
122
+ className: styles.unitSelect
123
+ }, /*#__PURE__*/React.createElement(Select.Root, {
124
+ value: currentBound.unit,
125
+ onValueChange: handleUnitChange,
126
+ disabled: !isCustom
127
+ }, /*#__PURE__*/React.createElement(Select.Trigger, {
128
+ placeholder: UNIT_LABELS[currentBound.unit]
129
+ }, /*#__PURE__*/React.createElement(Select.Value, null, selected => UNIT_LABELS[selected])), /*#__PURE__*/React.createElement(Select.Portal, null, /*#__PURE__*/React.createElement(Select.Positioner, null, /*#__PURE__*/React.createElement(Select.Popup, null, Object.entries(UNIT_LABELS).map(([val, label]) => /*#__PURE__*/React.createElement(Select.Item, {
130
+ key: val,
131
+ value: val
132
+ }, label))))))), /*#__PURE__*/React.createElement("div", {
133
+ className: styles.directionSelect
134
+ }, /*#__PURE__*/React.createElement(Select.Root, {
135
+ value: currentBound.direction,
136
+ onValueChange: handleDirectionChange,
137
+ disabled: !isCustom
138
+ }, /*#__PURE__*/React.createElement(Select.Trigger, {
139
+ placeholder: DIRECTION_LABELS[currentBound.direction]
140
+ }, /*#__PURE__*/React.createElement(Select.Value, null, selected => DIRECTION_LABELS[selected])), /*#__PURE__*/React.createElement(Select.Portal, null, /*#__PURE__*/React.createElement(Select.Positioner, null, /*#__PURE__*/React.createElement(Select.Popup, null, Object.entries(DIRECTION_LABELS).map(([val, label]) => /*#__PURE__*/React.createElement(Select.Item, {
141
+ key: val,
142
+ value: val
143
+ }, label))))))))), /*#__PURE__*/React.createElement("div", {
144
+ className: styles.radioItem
145
+ }, /*#__PURE__*/React.createElement(Radio.Root, {
146
+ value: "indefinitely",
147
+ className: styles.radioRoot,
148
+ "aria-label": "Indefinitely"
149
+ }, /*#__PURE__*/React.createElement(Radio.Indicator, {
150
+ className: styles.radioIndicator
151
+ })), /*#__PURE__*/React.createElement("span", {
152
+ className: styles.radioLabel
153
+ }, "Indefinitely")))))));
154
+ }
155
+ export const RelativeDateBoundInput = /*#__PURE__*/memo(RelativeDateBoundInputInner);
156
+ //# sourceMappingURL=RelativeDateBoundInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RelativeDateBoundInput.js","names":["Input","Popover","Radio","RadioGroup","CaretDown","React","memo","useCallback","useId","Select","formatRelativeBound","styles","UNIT_LABELS","days","weeks","months","years","DIRECTION_LABELS","ago","fromNow","DEFAULT_BOUND","count","unit","direction","RelativeDateBoundInputInner","value","onChange","placeholder","labelId","mode","currentBound","displayText","undefined","handleModeChange","nextMode","handleCountChange","e","parsed","parseInt","target","Number","isNaN","handleUnitChange","nextUnit","handleDirectionChange","nextDirection","isCustom","createElement","Root","Trigger","className","trigger","triggerValueContainer","triggerValue","triggerPlaceholder","triggerIcon","Portal","Positioner","positioner","sideOffset","Popup","popover","radioGroup","onValueChange","radioItem","radioRoot","Indicator","radioIndicator","customRow","type","countInput","String","disabled","min","unitSelect","Value","selected","Object","entries","map","val","label","Item","key","directionSelect","radioLabel","RelativeDateBoundInput"],"sources":["RelativeDateBoundInput.tsx"],"sourcesContent":["/*\n * Copyright 2026 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Input } from \"@base-ui/react/input\";\nimport { Popover } from \"@base-ui/react/popover\";\nimport { Radio } from \"@base-ui/react/radio\";\nimport { RadioGroup } from \"@base-ui/react/radio-group\";\nimport { CaretDown } from \"@blueprintjs/icons\";\nimport React, { memo, useCallback, useId } from \"react\";\n\nimport { Select } from \"../../../base-components/select/Select.js\";\nimport type { RelativeDateBound } from \"../../FilterListItemApi.js\";\nimport { formatRelativeBound } from \"../../utils/resolveRelativeDate.js\";\n\nimport styles from \"./RelativeDateBoundInput.module.css\";\n\ntype RelativeDateUnit = RelativeDateBound[\"unit\"];\ntype RelativeDateDirection = RelativeDateBound[\"direction\"];\n\nconst UNIT_LABELS: Record<RelativeDateUnit, string> = {\n days: \"day(s)\",\n weeks: \"week(s)\",\n months: \"month(s)\",\n years: \"year(s)\",\n};\n\nconst DIRECTION_LABELS: Record<RelativeDateDirection, string> = {\n ago: \"ago\",\n fromNow: \"from now\",\n};\n\nconst DEFAULT_BOUND: RelativeDateBound = {\n count: 0,\n unit: \"days\",\n direction: \"ago\",\n};\n\ninterface RelativeDateBoundInputProps {\n /** Current bound value, or `null` for \"Indefinitely\". */\n value: RelativeDateBound | null;\n /** Callback when the bound changes. `null` means \"Indefinitely\". */\n onChange: (value: RelativeDateBound | null) => void;\n /** Placeholder shown when no value is set, e.g. \"From\" or \"To\". */\n placeholder: string;\n}\n\nfunction RelativeDateBoundInputInner({\n value,\n onChange,\n placeholder,\n}: RelativeDateBoundInputProps): React.ReactElement {\n const labelId = useId();\n const mode: \"custom\" | \"indefinitely\" =\n value != null ? \"custom\" : \"indefinitely\";\n\n const currentBound = value ?? DEFAULT_BOUND;\n\n const displayText = value != null ? formatRelativeBound(value) : undefined;\n\n const handleModeChange = useCallback(\n (nextMode: unknown) => {\n if (nextMode === \"indefinitely\") {\n onChange(null);\n } else {\n // Intentional: switching from Indefinitely to Custom resets to\n // DEFAULT_BOUND. The previous custom value is not preserved because\n // Indefinitely clears the bound (value becomes null).\n onChange(currentBound);\n }\n },\n [onChange, currentBound],\n );\n\n const handleCountChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const parsed = parseInt(e.target.value, 10);\n const count = Number.isNaN(parsed) || parsed < 0 ? 0 : parsed;\n onChange({ ...currentBound, count });\n },\n [onChange, currentBound],\n );\n\n const handleUnitChange = useCallback(\n (nextUnit: RelativeDateUnit | null) => {\n if (nextUnit != null) {\n onChange({ ...currentBound, unit: nextUnit });\n }\n },\n [onChange, currentBound],\n );\n\n const handleDirectionChange = useCallback(\n (nextDirection: RelativeDateDirection | null) => {\n if (nextDirection != null) {\n onChange({ ...currentBound, direction: nextDirection });\n }\n },\n [onChange, currentBound],\n );\n\n const isCustom = mode === \"custom\";\n\n return (\n <Popover.Root>\n <Popover.Trigger className={styles.trigger}>\n <div className={styles.triggerValueContainer}>\n <span\n className={\n displayText != null\n ? styles.triggerValue\n : styles.triggerPlaceholder\n }\n >\n {displayText ?? placeholder}\n </span>\n </div>\n <span className={styles.triggerIcon}>\n <CaretDown />\n </span>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner className={styles.positioner} sideOffset={4}>\n <Popover.Popup className={styles.popover}>\n <RadioGroup\n className={styles.radioGroup}\n value={mode}\n onValueChange={handleModeChange}\n aria-labelledby={labelId}\n >\n {/* Custom relative bound */}\n <div className={styles.radioItem}>\n <Radio.Root\n value=\"custom\"\n className={styles.radioRoot}\n aria-label={`${placeholder} custom`}\n >\n <Radio.Indicator className={styles.radioIndicator} />\n </Radio.Root>\n <div className={styles.customRow}>\n <Input\n type=\"number\"\n className={styles.countInput}\n value={isCustom ? String(currentBound.count) : \"0\"}\n onChange={handleCountChange}\n disabled={!isCustom}\n min={0}\n aria-label={`${placeholder} count`}\n />\n <div className={styles.unitSelect}>\n <Select.Root<RelativeDateUnit>\n value={currentBound.unit}\n onValueChange={handleUnitChange}\n disabled={!isCustom}\n >\n <Select.Trigger\n placeholder={UNIT_LABELS[currentBound.unit]}\n >\n <Select.Value>\n {(selected: RelativeDateUnit) =>\n UNIT_LABELS[selected]\n }\n </Select.Value>\n </Select.Trigger>\n <Select.Portal>\n <Select.Positioner>\n <Select.Popup>\n {Object.entries(UNIT_LABELS).map(([val, label]) => (\n <Select.Item key={val} value={val}>\n {label}\n </Select.Item>\n ))}\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n </div>\n <div className={styles.directionSelect}>\n <Select.Root<RelativeDateDirection>\n value={currentBound.direction}\n onValueChange={handleDirectionChange}\n disabled={!isCustom}\n >\n <Select.Trigger\n placeholder={DIRECTION_LABELS[currentBound.direction]}\n >\n <Select.Value>\n {(selected: RelativeDateDirection) =>\n DIRECTION_LABELS[selected]\n }\n </Select.Value>\n </Select.Trigger>\n <Select.Portal>\n <Select.Positioner>\n <Select.Popup>\n {Object.entries(DIRECTION_LABELS).map(\n ([val, label]) => (\n <Select.Item key={val} value={val}>\n {label}\n </Select.Item>\n ),\n )}\n </Select.Popup>\n </Select.Positioner>\n </Select.Portal>\n </Select.Root>\n </div>\n </div>\n </div>\n\n {/* Indefinitely */}\n <div className={styles.radioItem}>\n <Radio.Root\n value=\"indefinitely\"\n className={styles.radioRoot}\n aria-label=\"Indefinitely\"\n >\n <Radio.Indicator className={styles.radioIndicator} />\n </Radio.Root>\n <span className={styles.radioLabel}>Indefinitely</span>\n </div>\n </RadioGroup>\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n\nexport const RelativeDateBoundInput = memo(\n RelativeDateBoundInputInner,\n) as typeof RelativeDateBoundInputInner;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,299 @@
1
+ /*
2
+ * Copyright 2026 Palantir Technologies, Inc. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ /* ---- Trigger (mirrors Select.Trigger styling) ---- */
18
+
19
+ .trigger {
20
+ display: inline-flex;
21
+ align-items: center;
22
+ justify-content: space-between;
23
+ gap: var(--osdk-select-spacing, var(--osdk-surface-spacing));
24
+ width: 100%;
25
+ min-height: var(--osdk-select-min-height, 30px);
26
+ padding: var(
27
+ --osdk-select-trigger-padding,
28
+ calc(var(--osdk-surface-spacing) * 1.5)
29
+ calc(var(--osdk-surface-spacing) * 2.5)
30
+ );
31
+ cursor: pointer;
32
+ border-radius: var(
33
+ --osdk-select-border-radius,
34
+ var(--osdk-surface-border-radius)
35
+ );
36
+ border: var(--osdk-select-border-width, var(--osdk-surface-border-width))
37
+ solid
38
+ var(--osdk-select-border-color, var(--osdk-surface-border-color-default));
39
+ box-shadow: var(--osdk-button-shadow);
40
+ background-color: var(
41
+ --osdk-select-trigger-bg,
42
+ var(--osdk-button-secondary-bg)
43
+ );
44
+ color: var(
45
+ --osdk-select-trigger-color,
46
+ var(--osdk-typography-color-default-rest)
47
+ );
48
+ font-family: var(
49
+ --osdk-select-font-family,
50
+ var(--osdk-typography-family-default)
51
+ );
52
+ font-size: var(
53
+ --osdk-select-font-size,
54
+ var(--osdk-typography-size-body-medium)
55
+ );
56
+ line-height: var(
57
+ --osdk-select-line-height,
58
+ var(--osdk-typography-line-height-default)
59
+ );
60
+ transition:
61
+ background-color
62
+ var(
63
+ --osdk-select-transition-duration,
64
+ var(--osdk-emphasis-transition-duration)
65
+ )
66
+ var(--osdk-select-transition-ease, var(--osdk-emphasis-ease-default)),
67
+ border-color
68
+ var(
69
+ --osdk-select-transition-duration,
70
+ var(--osdk-emphasis-transition-duration)
71
+ )
72
+ var(--osdk-select-transition-ease, var(--osdk-emphasis-ease-default));
73
+
74
+ &:hover {
75
+ background-color: var(
76
+ --osdk-select-trigger-bg-hover,
77
+ var(--osdk-button-secondary-bg-hover)
78
+ );
79
+ }
80
+
81
+ &:active {
82
+ background-color: var(
83
+ --osdk-select-trigger-bg-active,
84
+ var(--osdk-button-secondary-bg-active)
85
+ );
86
+ }
87
+
88
+ &:focus:not(:focus-visible) {
89
+ outline: none;
90
+ }
91
+
92
+ &:focus-visible {
93
+ outline: var(--osdk-input-focus-outline);
94
+ outline-offset: var(--osdk-input-focus-outline-offset);
95
+ }
96
+
97
+ &[data-popup-open]:focus-visible {
98
+ outline: none;
99
+ }
100
+
101
+ &[data-popup-open] {
102
+ border-color: var(
103
+ --osdk-select-border-color-active,
104
+ var(--osdk-intent-primary-rest)
105
+ );
106
+ }
107
+ }
108
+
109
+ .triggerValueContainer {
110
+ flex: 1;
111
+ display: grid;
112
+ min-width: 0;
113
+
114
+ & > * {
115
+ grid-area: 1 / 1;
116
+ overflow: hidden;
117
+ text-overflow: ellipsis;
118
+ white-space: nowrap;
119
+ }
120
+ }
121
+
122
+ .triggerValue {
123
+ text-align: left;
124
+ }
125
+
126
+ .triggerPlaceholder {
127
+ text-align: left;
128
+ color: var(
129
+ --osdk-select-placeholder-color,
130
+ var(--osdk-typography-color-muted)
131
+ );
132
+ pointer-events: none;
133
+ }
134
+
135
+ .triggerIcon {
136
+ display: flex;
137
+ align-items: center;
138
+ justify-content: center;
139
+ line-height: 0;
140
+ color: var(--osdk-select-icon-color, var(--osdk-iconography-color-muted));
141
+ flex-shrink: 0;
142
+ transition: transform
143
+ var(
144
+ --osdk-select-transition-duration,
145
+ var(--osdk-emphasis-transition-duration)
146
+ )
147
+ var(--osdk-select-transition-ease, var(--osdk-emphasis-ease-default));
148
+
149
+ [data-popup-open] > & {
150
+ transform: rotate(180deg);
151
+ }
152
+ }
153
+
154
+ /* ---- Range layout (From – To side-by-side) ---- */
155
+
156
+ .rangeRoot {
157
+ display: flex;
158
+ align-items: center;
159
+ gap: var(--osdk-filter-range-inputs-gap);
160
+ min-width: 0;
161
+ }
162
+
163
+ .separator {
164
+ color: var(--osdk-filter-range-separator-color);
165
+ font-family: var(--osdk-filter-input-font-family);
166
+ font-size: var(--osdk-filter-input-font-size);
167
+ flex-shrink: 0;
168
+ }
169
+
170
+ /* ---- Popover ---- */
171
+
172
+ .positioner {
173
+ z-index: var(--osdk-datetime-popover-z-index);
174
+
175
+ &[data-anchor-hidden] {
176
+ visibility: hidden;
177
+ }
178
+ }
179
+
180
+ .popover {
181
+ width: max-content;
182
+ background: var(--osdk-datetime-popover-bg);
183
+ color: var(--osdk-typography-color-default-rest);
184
+ padding: var(--osdk-datetime-popover-padding);
185
+ box-shadow: var(--osdk-datetime-popover-shadow);
186
+ border-radius: var(--osdk-surface-border-radius);
187
+ display: flex;
188
+ flex-direction: column;
189
+ gap: var(--osdk-radio-gap);
190
+ }
191
+
192
+ /* ---- Radio options inside popover ---- */
193
+
194
+ .radioGroup {
195
+ display: flex;
196
+ flex-direction: column;
197
+ gap: var(--osdk-radio-gap);
198
+ }
199
+
200
+ .radioItem {
201
+ display: flex;
202
+ align-items: center;
203
+ gap: var(--osdk-radio-item-gap);
204
+ }
205
+
206
+ .radioRoot {
207
+ display: flex;
208
+ align-items: center;
209
+ justify-content: center;
210
+ width: var(--osdk-radio-size);
211
+ height: var(--osdk-radio-size);
212
+ border-radius: 50%;
213
+ border: var(--osdk-radio-border);
214
+ cursor: pointer;
215
+ flex-shrink: 0;
216
+
217
+ &[data-unchecked] {
218
+ background-color: var(--osdk-radio-bg);
219
+
220
+ &:hover {
221
+ background-color: var(--osdk-radio-bg-hover);
222
+ }
223
+ }
224
+
225
+ &[data-checked] {
226
+ background-color: var(--osdk-radio-bg-checked);
227
+
228
+ &:hover {
229
+ background-color: var(--osdk-radio-bg-checked-hover);
230
+ }
231
+
232
+ &:active {
233
+ background-color: var(--osdk-radio-bg-checked-active);
234
+ }
235
+ }
236
+
237
+ &:focus-visible {
238
+ outline: var(--osdk-focus-outline);
239
+ outline-offset: calc(-1 * var(--osdk-focus-visible-outline-offset));
240
+ }
241
+ }
242
+
243
+ .radioIndicator {
244
+ width: var(--osdk-radio-indicator-size);
245
+ height: var(--osdk-radio-indicator-size);
246
+ border-radius: 50%;
247
+ background-color: var(--osdk-radio-indicator-color);
248
+
249
+ &[data-unchecked] {
250
+ display: none;
251
+ }
252
+ }
253
+
254
+ .radioLabel {
255
+ font-family: var(--osdk-typography-family-default);
256
+ font-size: var(--osdk-typography-size-body-medium);
257
+ line-height: var(--osdk-typography-line-height-default);
258
+ color: var(--osdk-typography-color-default-rest);
259
+ cursor: pointer;
260
+ }
261
+
262
+ .customRow {
263
+ display: flex;
264
+ align-items: center;
265
+ gap: calc(var(--osdk-surface-spacing) * 1.5);
266
+ flex-wrap: nowrap;
267
+ }
268
+
269
+ .countInput {
270
+ width: calc(var(--osdk-surface-spacing) * 12);
271
+ flex-shrink: 0;
272
+ font-family: var(--osdk-filter-input-font-family);
273
+ font-size: var(--osdk-filter-input-font-size);
274
+ padding: var(--osdk-filter-input-padding);
275
+ border: var(--osdk-filter-input-border);
276
+ border-radius: var(--osdk-filter-input-border-radius);
277
+ background: var(--osdk-filter-input-bg);
278
+ color: var(--osdk-filter-input-color);
279
+
280
+ &:focus {
281
+ border-color: var(--osdk-filter-input-focus-border);
282
+ outline: var(--osdk-filter-input-focus-outline-width) solid
283
+ var(--osdk-filter-input-focus-outline-color);
284
+ outline-offset: var(--osdk-filter-input-focus-outline-offset);
285
+ }
286
+
287
+ &:disabled {
288
+ opacity: var(--osdk-disabled-opacity);
289
+ cursor: not-allowed;
290
+ }
291
+ }
292
+
293
+ .unitSelect {
294
+ min-width: calc(var(--osdk-surface-spacing) * 20);
295
+ }
296
+
297
+ .directionSelect {
298
+ min-width: calc(var(--osdk-surface-spacing) * 22);
299
+ }