@osdk/react-components 0.12.0 → 0.13.0

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 (328) hide show
  1. package/AGENTS.md +4 -0
  2. package/CHANGELOG.md +11 -0
  3. package/build/browser/action-form/ActionForm.js +19 -11
  4. package/build/browser/action-form/ActionForm.js.map +1 -1
  5. package/build/browser/action-form/ActionFormApi.js.map +1 -1
  6. package/build/browser/action-form/BaseForm.js +19 -13
  7. package/build/browser/action-form/BaseForm.js.map +1 -1
  8. package/build/browser/action-form/BaseForm.module.css +7 -7
  9. package/build/browser/action-form/FormField.js +5 -2
  10. package/build/browser/action-form/FormField.js.map +1 -1
  11. package/build/browser/action-form/FormField.module.css +6 -1
  12. package/build/browser/action-form/FormField.module.css.js +1 -0
  13. package/build/browser/action-form/FormFieldApi.js +7 -1
  14. package/build/browser/action-form/FormFieldApi.js.map +1 -1
  15. package/build/browser/action-form/FormHeader.module.css +2 -2
  16. package/build/browser/action-form/fields/DateCalendar.js +41 -3
  17. package/build/browser/action-form/fields/DateCalendar.js.map +1 -1
  18. package/build/browser/action-form/fields/DateCalendar.module.css +59 -10
  19. package/build/browser/action-form/fields/DateCalendar.module.css.js +5 -1
  20. package/build/browser/action-form/fields/DateRangeCalendar.js +8 -5
  21. package/build/browser/action-form/fields/DateRangeCalendar.js.map +1 -1
  22. package/build/browser/action-form/fields/DateRangeInputField.js +76 -61
  23. package/build/browser/action-form/fields/DateRangeInputField.js.map +1 -1
  24. package/build/browser/action-form/fields/DateRangeInputField.module.css +0 -15
  25. package/build/browser/action-form/fields/DateRangeInputField.module.css.js +1 -2
  26. package/build/browser/action-form/fields/DatetimePickerField.js +74 -40
  27. package/build/browser/action-form/fields/DatetimePickerField.js.map +1 -1
  28. package/build/browser/action-form/fields/DatetimePickerField.module.css +2 -9
  29. package/build/browser/action-form/fields/FieldBridge.js +1 -1
  30. package/build/browser/action-form/fields/FieldBridge.js.map +1 -1
  31. package/build/browser/action-form/fields/FilePickerField.js +47 -39
  32. package/build/browser/action-form/fields/FilePickerField.js.map +1 -1
  33. package/build/browser/action-form/fields/FilePickerField.module.css +43 -31
  34. package/build/browser/action-form/fields/FilePickerField.module.css.js +2 -2
  35. package/build/browser/action-form/fields/FormFieldRenderer.js +9 -0
  36. package/build/browser/action-form/fields/FormFieldRenderer.js.map +1 -1
  37. package/build/browser/action-form/fields/RadioButtonsField.module.css +3 -3
  38. package/build/browser/action-form/fields/SwitchField.js +34 -0
  39. package/build/browser/action-form/fields/SwitchField.js.map +1 -0
  40. package/build/browser/action-form/fields/TimePicker.js +165 -26
  41. package/build/browser/action-form/fields/TimePicker.js.map +1 -1
  42. package/build/browser/action-form/fields/TimePicker.module.css +27 -2
  43. package/build/browser/action-form/fields/TimePicker.module.css.js +3 -1
  44. package/build/browser/action-form/fields/calendarShared.js +5 -0
  45. package/build/browser/action-form/fields/calendarShared.js.map +1 -1
  46. package/build/browser/action-form/fields/useDateEditState.js +3 -4
  47. package/build/browser/action-form/fields/useDateEditState.js.map +1 -1
  48. package/build/browser/base-components/action-button/ActionButton.js +2 -1
  49. package/build/browser/base-components/action-button/ActionButton.js.map +1 -1
  50. package/build/browser/base-components/action-button/ActionButton.module.css +19 -0
  51. package/build/browser/base-components/action-button/ActionButton.module.css.js +2 -1
  52. package/build/browser/base-components/combobox/Combobox.module.css +31 -3
  53. package/build/browser/base-components/select/Select.module.css +18 -0
  54. package/build/browser/base-components/switch/Switch.module.css +18 -6
  55. package/build/browser/filter-list/base/inputs/ListogramInput.js +34 -6
  56. package/build/browser/filter-list/base/inputs/ListogramInput.js.map +1 -1
  57. package/build/browser/filter-list/base/inputs/ListogramInput.module.css +11 -5
  58. package/build/browser/filter-list/base/inputs/ListogramInput.module.css.js +1 -1
  59. package/build/browser/filter-list/base/inputs/MultiSelectInput.js +20 -12
  60. package/build/browser/filter-list/base/inputs/MultiSelectInput.js.map +1 -1
  61. package/build/browser/filter-list/base/inputs/NoValueLabel.js +36 -0
  62. package/build/browser/filter-list/base/inputs/NoValueLabel.js.map +1 -0
  63. package/build/browser/filter-list/base/inputs/NoValueLabel.module.css +20 -0
  64. package/build/browser/filter-list/base/inputs/NoValueLabel.module.css.js +6 -0
  65. package/build/browser/filter-list/base/inputs/NullValueWrapper.js +4 -3
  66. package/build/browser/filter-list/base/inputs/NullValueWrapper.js.map +1 -1
  67. package/build/browser/filter-list/base/inputs/NullValueWrapper.module.css +10 -7
  68. package/build/browser/filter-list/base/inputs/NullValueWrapper.module.css.js +1 -1
  69. package/build/browser/filter-list/base/inputs/SingleSelectInput.js +13 -8
  70. package/build/browser/filter-list/base/inputs/SingleSelectInput.js.map +1 -1
  71. package/build/browser/filter-list/base/inputs/TextTagsInput.js +6 -2
  72. package/build/browser/filter-list/base/inputs/TextTagsInput.js.map +1 -1
  73. package/build/browser/filter-list/hooks/useFilterListState.js +7 -6
  74. package/build/browser/filter-list/hooks/useFilterListState.js.map +1 -1
  75. package/build/browser/filter-list/hooks/useStableMapEntries.js +35 -0
  76. package/build/browser/filter-list/hooks/useStableMapEntries.js.map +1 -0
  77. package/build/browser/filter-list/utils/filterValues.js +13 -0
  78. package/build/browser/filter-list/utils/filterValues.js.map +1 -1
  79. package/build/browser/object-table/DefaultCellRenderer.js +12 -2
  80. package/build/browser/object-table/DefaultCellRenderer.js.map +1 -1
  81. package/build/browser/object-table/EditableCell.js +14 -4
  82. package/build/browser/object-table/EditableCell.js.map +1 -1
  83. package/build/browser/object-table/EditableCell.module.css +4 -0
  84. package/build/browser/object-table/EditableCell.module.css.js +1 -0
  85. package/build/browser/object-table/ObjectTable.js +3 -1
  86. package/build/browser/object-table/ObjectTable.js.map +1 -1
  87. package/build/browser/object-table/ObjectTableApi.js.map +1 -1
  88. package/build/browser/object-table/Table.js +8 -4
  89. package/build/browser/object-table/Table.js.map +1 -1
  90. package/build/browser/object-table/TableBody.js +4 -2
  91. package/build/browser/object-table/TableBody.js.map +1 -1
  92. package/build/browser/object-table/TableRow.js +12 -4
  93. package/build/browser/object-table/TableRow.js.map +1 -1
  94. package/build/browser/object-table/hooks/useColumnDefs.js.map +1 -1
  95. package/build/browser/object-table/utils/editableUtils.js +39 -0
  96. package/build/browser/object-table/utils/editableUtils.js.map +1 -0
  97. package/build/browser/object-table/utils/shouldShowEditableCell.js +1 -1
  98. package/build/browser/object-table/utils/shouldShowEditableCell.js.map +1 -1
  99. package/build/browser/object-table/utils/types.js.map +1 -1
  100. package/build/browser/styles.css +331 -130
  101. package/build/browser/tokens/component-tokens/button.css +15 -0
  102. package/build/browser/tokens/component-tokens/combobox.css +9 -0
  103. package/build/browser/tokens/component-tokens/datetime-picker.css +2 -2
  104. package/build/browser/tokens/component-tokens/file-picker.css +0 -10
  105. package/build/browser/tokens/component-tokens/filter-list.css +9 -6
  106. package/build/browser/tokens/component-tokens/form-section.css +1 -1
  107. package/build/browser/tokens/component-tokens/form.css +9 -5
  108. package/build/browser/tokens/component-tokens/table.css +3 -5
  109. package/build/browser/tokens.css +1 -0
  110. package/build/browser/util/UserAgent.js +1 -1
  111. package/build/cjs/{DateCalendar-2W4QHEEI.css → DateCalendar-G7RC2FCG.css} +105 -8
  112. package/build/cjs/DateCalendar-G7RC2FCG.css.map +1 -0
  113. package/build/cjs/DateCalendar-RX7HP2XP.cjs +26 -0
  114. package/build/cjs/{DateCalendar-QGSYBWJB.cjs.map → DateCalendar-RX7HP2XP.cjs.map} +1 -1
  115. package/build/cjs/{DateRangeCalendar-M63S2LLG.css → DateRangeCalendar-JBVYJDBJ.css} +105 -8
  116. package/build/cjs/DateRangeCalendar-JBVYJDBJ.css.map +1 -0
  117. package/build/cjs/DateRangeCalendar-OHT4IUWQ.cjs +54 -0
  118. package/build/cjs/DateRangeCalendar-OHT4IUWQ.cjs.map +1 -0
  119. package/build/cjs/{chunk-T7I6O43T.cjs → chunk-6SPXSFPI.cjs} +237 -85
  120. package/build/cjs/chunk-6SPXSFPI.cjs.map +1 -0
  121. package/build/cjs/{chunk-SZXVBDSA.cjs → chunk-6UDBHYSO.cjs} +3 -3
  122. package/build/cjs/{chunk-SZXVBDSA.cjs.map → chunk-6UDBHYSO.cjs.map} +1 -1
  123. package/build/cjs/{chunk-YBDS5WQP.cjs → chunk-7H6WXQ35.cjs} +4 -4
  124. package/build/cjs/{chunk-YBDS5WQP.cjs.map → chunk-7H6WXQ35.cjs.map} +1 -1
  125. package/build/cjs/{chunk-VVJFMOZI.cjs → chunk-I3OSD6CF.cjs} +19 -45
  126. package/build/cjs/chunk-I3OSD6CF.cjs.map +1 -0
  127. package/build/cjs/chunk-MD4KDE44.cjs +41 -0
  128. package/build/cjs/chunk-MD4KDE44.cjs.map +1 -0
  129. package/build/cjs/{chunk-YPXTSEE7.cjs → chunk-MLFMSZJQ.cjs} +85 -38
  130. package/build/cjs/chunk-MLFMSZJQ.cjs.map +1 -0
  131. package/build/cjs/chunk-MQYOHGPY.cjs +52 -0
  132. package/build/cjs/chunk-MQYOHGPY.cjs.map +1 -0
  133. package/build/cjs/{chunk-BJDCC446.cjs → chunk-PTTCWNZZ.cjs} +417 -364
  134. package/build/cjs/chunk-PTTCWNZZ.cjs.map +1 -0
  135. package/build/cjs/{chunk-B2GRQRWU.cjs → chunk-TOJSJN3L.cjs} +44 -8
  136. package/build/cjs/chunk-TOJSJN3L.cjs.map +1 -0
  137. package/build/cjs/{chunk-JLESWL47.cjs → chunk-V7XWTJV7.cjs} +4 -2
  138. package/build/cjs/chunk-V7XWTJV7.cjs.map +1 -0
  139. package/build/cjs/{chunk-L5LPFCXT.cjs → chunk-W2IASYE4.cjs} +163 -125
  140. package/build/cjs/chunk-W2IASYE4.cjs.map +1 -0
  141. package/build/cjs/chunk-X337DNCW.cjs +45 -0
  142. package/build/cjs/chunk-X337DNCW.cjs.map +1 -0
  143. package/build/cjs/{chunk-SB2VTP67.cjs → chunk-Z7VHLTKD.cjs} +2 -64
  144. package/build/cjs/chunk-Z7VHLTKD.cjs.map +1 -0
  145. package/build/cjs/public/experimental/action-form.cjs +11 -9
  146. package/build/cjs/public/experimental/action-form.css +223 -68
  147. package/build/cjs/public/experimental/action-form.css.map +1 -1
  148. package/build/cjs/public/experimental/action-form.d.cts +83 -74
  149. package/build/cjs/public/experimental/filter-list.cjs +9 -8
  150. package/build/cjs/public/experimental/filter-list.css +38 -19
  151. package/build/cjs/public/experimental/filter-list.css.map +1 -1
  152. package/build/cjs/public/experimental/object-table.cjs +14 -12
  153. package/build/cjs/public/experimental/object-table.css +152 -59
  154. package/build/cjs/public/experimental/object-table.css.map +1 -1
  155. package/build/cjs/public/experimental/object-table.d.cts +39 -20
  156. package/build/cjs/public/experimental/pdf-viewer.cjs +24 -24
  157. package/build/cjs/public/experimental.cjs +46 -44
  158. package/build/cjs/public/experimental.css +242 -139
  159. package/build/cjs/public/experimental.css.map +1 -1
  160. package/build/cjs/public/primitives.cjs +8 -7
  161. package/build/cjs/public/primitives.css +15 -0
  162. package/build/cjs/public/primitives.css.map +1 -1
  163. package/build/cjs/public/primitives.d.cts +1 -0
  164. package/build/esm/action-form/ActionForm.js +19 -11
  165. package/build/esm/action-form/ActionForm.js.map +1 -1
  166. package/build/esm/action-form/ActionFormApi.js.map +1 -1
  167. package/build/esm/action-form/BaseForm.js +19 -13
  168. package/build/esm/action-form/BaseForm.js.map +1 -1
  169. package/build/esm/action-form/BaseForm.module.css +7 -7
  170. package/build/esm/action-form/FormField.js +5 -2
  171. package/build/esm/action-form/FormField.js.map +1 -1
  172. package/build/esm/action-form/FormField.module.css +6 -1
  173. package/build/esm/action-form/FormFieldApi.js +7 -1
  174. package/build/esm/action-form/FormFieldApi.js.map +1 -1
  175. package/build/esm/action-form/FormHeader.module.css +2 -2
  176. package/build/esm/action-form/fields/DateCalendar.js +41 -3
  177. package/build/esm/action-form/fields/DateCalendar.js.map +1 -1
  178. package/build/esm/action-form/fields/DateCalendar.module.css +59 -10
  179. package/build/esm/action-form/fields/DateRangeCalendar.js +8 -5
  180. package/build/esm/action-form/fields/DateRangeCalendar.js.map +1 -1
  181. package/build/esm/action-form/fields/DateRangeInputField.js +76 -61
  182. package/build/esm/action-form/fields/DateRangeInputField.js.map +1 -1
  183. package/build/esm/action-form/fields/DateRangeInputField.module.css +0 -15
  184. package/build/esm/action-form/fields/DatetimePickerField.js +74 -40
  185. package/build/esm/action-form/fields/DatetimePickerField.js.map +1 -1
  186. package/build/esm/action-form/fields/DatetimePickerField.module.css +2 -9
  187. package/build/esm/action-form/fields/FieldBridge.js +1 -1
  188. package/build/esm/action-form/fields/FieldBridge.js.map +1 -1
  189. package/build/esm/action-form/fields/FilePickerField.js +47 -39
  190. package/build/esm/action-form/fields/FilePickerField.js.map +1 -1
  191. package/build/esm/action-form/fields/FilePickerField.module.css +43 -31
  192. package/build/esm/action-form/fields/FormFieldRenderer.js +9 -0
  193. package/build/esm/action-form/fields/FormFieldRenderer.js.map +1 -1
  194. package/build/esm/action-form/fields/RadioButtonsField.module.css +3 -3
  195. package/build/esm/action-form/fields/SwitchField.js +34 -0
  196. package/build/esm/action-form/fields/SwitchField.js.map +1 -0
  197. package/build/esm/action-form/fields/TimePicker.js +165 -26
  198. package/build/esm/action-form/fields/TimePicker.js.map +1 -1
  199. package/build/esm/action-form/fields/TimePicker.module.css +27 -2
  200. package/build/esm/action-form/fields/calendarShared.js +5 -0
  201. package/build/esm/action-form/fields/calendarShared.js.map +1 -1
  202. package/build/esm/action-form/fields/useDateEditState.js +3 -4
  203. package/build/esm/action-form/fields/useDateEditState.js.map +1 -1
  204. package/build/esm/base-components/action-button/ActionButton.js +2 -1
  205. package/build/esm/base-components/action-button/ActionButton.js.map +1 -1
  206. package/build/esm/base-components/action-button/ActionButton.module.css +19 -0
  207. package/build/esm/base-components/combobox/Combobox.module.css +31 -3
  208. package/build/esm/base-components/select/Select.module.css +18 -0
  209. package/build/esm/base-components/switch/Switch.module.css +18 -6
  210. package/build/esm/filter-list/base/inputs/ListogramInput.js +34 -6
  211. package/build/esm/filter-list/base/inputs/ListogramInput.js.map +1 -1
  212. package/build/esm/filter-list/base/inputs/ListogramInput.module.css +11 -5
  213. package/build/esm/filter-list/base/inputs/MultiSelectInput.js +20 -12
  214. package/build/esm/filter-list/base/inputs/MultiSelectInput.js.map +1 -1
  215. package/build/esm/filter-list/base/inputs/NoValueLabel.js +36 -0
  216. package/build/esm/filter-list/base/inputs/NoValueLabel.js.map +1 -0
  217. package/build/esm/filter-list/base/inputs/NoValueLabel.module.css +20 -0
  218. package/build/esm/filter-list/base/inputs/NullValueWrapper.js +4 -3
  219. package/build/esm/filter-list/base/inputs/NullValueWrapper.js.map +1 -1
  220. package/build/esm/filter-list/base/inputs/NullValueWrapper.module.css +10 -7
  221. package/build/esm/filter-list/base/inputs/SingleSelectInput.js +13 -8
  222. package/build/esm/filter-list/base/inputs/SingleSelectInput.js.map +1 -1
  223. package/build/esm/filter-list/base/inputs/TextTagsInput.js +6 -2
  224. package/build/esm/filter-list/base/inputs/TextTagsInput.js.map +1 -1
  225. package/build/esm/filter-list/hooks/useFilterListState.js +7 -6
  226. package/build/esm/filter-list/hooks/useFilterListState.js.map +1 -1
  227. package/build/esm/filter-list/hooks/useStableMapEntries.js +35 -0
  228. package/build/esm/filter-list/hooks/useStableMapEntries.js.map +1 -0
  229. package/build/esm/filter-list/utils/filterValues.js +13 -0
  230. package/build/esm/filter-list/utils/filterValues.js.map +1 -1
  231. package/build/esm/object-table/DefaultCellRenderer.js +12 -2
  232. package/build/esm/object-table/DefaultCellRenderer.js.map +1 -1
  233. package/build/esm/object-table/EditableCell.js +14 -4
  234. package/build/esm/object-table/EditableCell.js.map +1 -1
  235. package/build/esm/object-table/EditableCell.module.css +4 -0
  236. package/build/esm/object-table/ObjectTable.js +3 -1
  237. package/build/esm/object-table/ObjectTable.js.map +1 -1
  238. package/build/esm/object-table/ObjectTableApi.js.map +1 -1
  239. package/build/esm/object-table/Table.js +8 -4
  240. package/build/esm/object-table/Table.js.map +1 -1
  241. package/build/esm/object-table/TableBody.js +4 -2
  242. package/build/esm/object-table/TableBody.js.map +1 -1
  243. package/build/esm/object-table/TableRow.js +12 -4
  244. package/build/esm/object-table/TableRow.js.map +1 -1
  245. package/build/esm/object-table/hooks/useColumnDefs.js.map +1 -1
  246. package/build/esm/object-table/utils/editableUtils.js +39 -0
  247. package/build/esm/object-table/utils/editableUtils.js.map +1 -0
  248. package/build/esm/object-table/utils/shouldShowEditableCell.js +1 -1
  249. package/build/esm/object-table/utils/shouldShowEditableCell.js.map +1 -1
  250. package/build/esm/object-table/utils/types.js.map +1 -1
  251. package/build/esm/tokens/component-tokens/button.css +15 -0
  252. package/build/esm/tokens/component-tokens/combobox.css +9 -0
  253. package/build/esm/tokens/component-tokens/datetime-picker.css +2 -2
  254. package/build/esm/tokens/component-tokens/file-picker.css +0 -10
  255. package/build/esm/tokens/component-tokens/filter-list.css +9 -6
  256. package/build/esm/tokens/component-tokens/form-section.css +1 -1
  257. package/build/esm/tokens/component-tokens/form.css +9 -5
  258. package/build/esm/tokens/component-tokens/table.css +3 -5
  259. package/build/esm/tokens.css +1 -0
  260. package/build/esm/util/UserAgent.js +1 -1
  261. package/build/types/action-form/ActionFormApi.d.ts +8 -8
  262. package/build/types/action-form/ActionFormApi.d.ts.map +1 -1
  263. package/build/types/action-form/BaseForm.d.ts.map +1 -1
  264. package/build/types/action-form/FormFieldApi.d.ts +29 -22
  265. package/build/types/action-form/FormFieldApi.d.ts.map +1 -1
  266. package/build/types/action-form/fields/DateCalendar.d.ts +6 -1
  267. package/build/types/action-form/fields/DateCalendar.d.ts.map +1 -1
  268. package/build/types/action-form/fields/DateRangeCalendar.d.ts.map +1 -1
  269. package/build/types/action-form/fields/DateRangeInputField.d.ts.map +1 -1
  270. package/build/types/action-form/fields/DatetimePickerField.d.ts.map +1 -1
  271. package/build/types/action-form/fields/FieldBridge.d.ts.map +1 -1
  272. package/build/types/action-form/fields/FilePickerField.d.ts.map +1 -1
  273. package/build/types/action-form/fields/FormFieldRenderer.d.ts.map +1 -1
  274. package/build/types/action-form/fields/SwitchField.d.ts +7 -0
  275. package/build/types/action-form/fields/SwitchField.d.ts.map +1 -0
  276. package/build/types/action-form/fields/TimePicker.d.ts +4 -5
  277. package/build/types/action-form/fields/TimePicker.d.ts.map +1 -1
  278. package/build/types/action-form/fields/useDateEditState.d.ts +2 -2
  279. package/build/types/base-components/action-button/ActionButton.d.ts +1 -0
  280. package/build/types/base-components/action-button/ActionButton.d.ts.map +1 -1
  281. package/build/types/filter-list/base/inputs/ListogramInput.d.ts.map +1 -1
  282. package/build/types/filter-list/base/inputs/MultiSelectInput.d.ts.map +1 -1
  283. package/build/types/filter-list/base/inputs/NoValueLabel.d.ts +15 -0
  284. package/build/types/filter-list/base/inputs/NoValueLabel.d.ts.map +1 -0
  285. package/build/types/filter-list/base/inputs/NullValueWrapper.d.ts.map +1 -1
  286. package/build/types/filter-list/base/inputs/SingleSelectInput.d.ts.map +1 -1
  287. package/build/types/filter-list/base/inputs/TextTagsInput.d.ts.map +1 -1
  288. package/build/types/filter-list/hooks/useFilterListState.d.ts.map +1 -1
  289. package/build/types/filter-list/hooks/useStableMapEntries.d.ts +9 -0
  290. package/build/types/filter-list/hooks/useStableMapEntries.d.ts.map +1 -0
  291. package/build/types/filter-list/utils/filterValues.d.ts +7 -0
  292. package/build/types/filter-list/utils/filterValues.d.ts.map +1 -1
  293. package/build/types/object-table/DefaultCellRenderer.d.ts.map +1 -1
  294. package/build/types/object-table/EditableCell.d.ts +1 -1
  295. package/build/types/object-table/EditableCell.d.ts.map +1 -1
  296. package/build/types/object-table/ObjectTableApi.d.ts +26 -7
  297. package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
  298. package/build/types/object-table/Table.d.ts +9 -2
  299. package/build/types/object-table/Table.d.ts.map +1 -1
  300. package/build/types/object-table/TableBody.d.ts +2 -1
  301. package/build/types/object-table/TableBody.d.ts.map +1 -1
  302. package/build/types/object-table/TableRow.d.ts +2 -1
  303. package/build/types/object-table/TableRow.d.ts.map +1 -1
  304. package/build/types/object-table/utils/editableUtils.d.ts +16 -0
  305. package/build/types/object-table/utils/editableUtils.d.ts.map +1 -0
  306. package/build/types/object-table/utils/shouldShowEditableCell.d.ts +2 -1
  307. package/build/types/object-table/utils/shouldShowEditableCell.d.ts.map +1 -1
  308. package/build/types/object-table/utils/types.d.ts +4 -11
  309. package/build/types/object-table/utils/types.d.ts.map +1 -1
  310. package/docs/ActionForm.md +176 -0
  311. package/docs/CSSVariables.md +31 -30
  312. package/docs/ObjectTable.md +141 -16
  313. package/package.json +6 -5
  314. package/build/cjs/DateCalendar-2W4QHEEI.css.map +0 -1
  315. package/build/cjs/DateCalendar-QGSYBWJB.cjs +0 -24
  316. package/build/cjs/DateRangeCalendar-JHO2BF3Z.cjs +0 -48
  317. package/build/cjs/DateRangeCalendar-JHO2BF3Z.cjs.map +0 -1
  318. package/build/cjs/DateRangeCalendar-M63S2LLG.css.map +0 -1
  319. package/build/cjs/chunk-B2GRQRWU.cjs.map +0 -1
  320. package/build/cjs/chunk-BJDCC446.cjs.map +0 -1
  321. package/build/cjs/chunk-JLESWL47.cjs.map +0 -1
  322. package/build/cjs/chunk-L5LPFCXT.cjs.map +0 -1
  323. package/build/cjs/chunk-SB2VTP67.cjs.map +0 -1
  324. package/build/cjs/chunk-T7I6O43T.cjs.map +0 -1
  325. package/build/cjs/chunk-UCTQICPR.cjs +0 -10
  326. package/build/cjs/chunk-UCTQICPR.cjs.map +0 -1
  327. package/build/cjs/chunk-VVJFMOZI.cjs.map +0 -1
  328. package/build/cjs/chunk-YPXTSEE7.cjs.map +0 -1
@@ -18,9 +18,10 @@ import { Button } from "@base-ui/react/button";
18
18
  import classnames from "classnames";
19
19
  import React, { memo, useCallback, useMemo, useState } from "react";
20
20
  import { Checkbox } from "../../../base-components/checkbox/Checkbox.js";
21
- import { filterValuesBySearch } from "../../utils/filterValues.js";
21
+ import { filterValuesBySearch, isEmptyValue } from "../../utils/filterValues.js";
22
22
  import styles from "./ListogramInput.module.css";
23
23
  import { ListogramSkeleton } from "./ListogramSkeleton.js";
24
+ import { NoValueLabel } from "./NoValueLabel.js";
24
25
  import sharedStyles from "./shared.module.css";
25
26
  import { useStableData } from "./useStableData.js";
26
27
  function ListogramInputInner({
@@ -41,7 +42,33 @@ function ListogramInputInner({
41
42
  renderValue
42
43
  }) {
43
44
  const [isExpanded, setIsExpanded] = useState(false);
44
- const stableValues = useStableData(values, isLoading);
45
+
46
+ // Aggregations may return both "" and null as separate rows; merge them
47
+ // into a single "No value" placeholder at the position of the first match.
48
+ const dedupedValues = useMemo(() => {
49
+ const out = [];
50
+ let emptyCount = 0;
51
+ let firstEmptyIndex = -1;
52
+ for (const v of values) {
53
+ if (v.value === "" || v.value == null) {
54
+ if (firstEmptyIndex === -1) {
55
+ firstEmptyIndex = out.length;
56
+ }
57
+ emptyCount += v.count;
58
+ } else {
59
+ out.push(v);
60
+ }
61
+ }
62
+ if (firstEmptyIndex >= 0 && emptyCount > 0) {
63
+ out.splice(firstEmptyIndex, 0, {
64
+ value: "",
65
+ count: emptyCount,
66
+ isNull: true
67
+ });
68
+ }
69
+ return out;
70
+ }, [values]);
71
+ const stableValues = useStableData(dedupedValues, isLoading);
45
72
  const selectedSet = useMemo(() => new Set(selectedValues), [selectedValues]);
46
73
  const toggleValue = useCallback(value => {
47
74
  if (selectedSet.has(value)) {
@@ -82,8 +109,7 @@ function ListogramInputInner({
82
109
  }) => {
83
110
  const percentage = maxCount > 0 ? count / maxCount * 100 : 0;
84
111
  const perRowColor = colorMap?.[value];
85
- const isEmpty = value === "";
86
- const displayLabel = isEmpty ? "No value" : renderValue?.(value) ?? value;
112
+ const isEmpty = isEmptyValue(value);
87
113
  return /*#__PURE__*/React.createElement(Button, {
88
114
  key: value,
89
115
  className: styles.row
@@ -107,9 +133,11 @@ function ListogramInputInner({
107
133
  onCheckedChange: () => toggleValue(value),
108
134
  isExcluding: isExcluding
109
135
  })), /*#__PURE__*/React.createElement("span", {
110
- className: classnames(styles.label, isEmpty && styles.emptyLabel),
136
+ className: styles.label,
111
137
  "data-excluding": isExcluding && selectedSet.has(value) || undefined
112
- }, displayLabel), showCount && displayMode !== "minimal" && /*#__PURE__*/React.createElement("span", {
138
+ }, isEmpty ? /*#__PURE__*/React.createElement(NoValueLabel, {
139
+ className: styles.noValueLabel
140
+ }) : renderValue?.(value) ?? value), showCount && displayMode !== "minimal" && /*#__PURE__*/React.createElement("span", {
113
141
  className: styles.count
114
142
  }, count.toLocaleString()), displayMode === "full" && /*#__PURE__*/React.createElement("span", {
115
143
  className: styles.bar
@@ -1 +1 @@
1
- {"version":3,"file":"ListogramInput.js","names":["Button","classnames","React","memo","useCallback","useMemo","useState","Checkbox","filterValuesBySearch","styles","ListogramSkeleton","sharedStyles","useStableData","ListogramInputInner","values","maxCount","isLoading","error","selectedValues","onChange","colorMap","displayMode","showCount","isExcluding","className","style","maxVisibleItems","searchQuery","renderValue","isExpanded","setIsExpanded","stableValues","selectedSet","Set","toggleValue","value","has","filter","v","filteredValues","sortedValues","selected","unselected","displayValues","slice","hasMore","length","createElement","listogram","errorMessage","message","emptyMessage","container","map","count","percentage","perRowColor","isEmpty","displayLabel","key","row","onClick","undefined","checkbox","e","stopPropagation","checked","onCheckedChange","label","emptyLabel","toLocaleString","bar","barFill","type","viewAllButton","ListogramInput"],"sources":["ListogramInput.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 { Button } from \"@base-ui/react/button\";\nimport classnames from \"classnames\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\nimport { Checkbox } from \"../../../base-components/checkbox/Checkbox.js\";\nimport type { PropertyAggregationValue } from \"../../types/AggregationTypes.js\";\nimport { filterValuesBySearch } from \"../../utils/filterValues.js\";\nimport styles from \"./ListogramInput.module.css\";\nimport { ListogramSkeleton } from \"./ListogramSkeleton.js\";\nimport sharedStyles from \"./shared.module.css\";\nimport { useStableData } from \"./useStableData.js\";\n\nexport type ListogramDisplayMode = \"full\" | \"count\" | \"minimal\";\n\ninterface ListogramInputProps {\n values: PropertyAggregationValue[];\n maxCount: number;\n isLoading: boolean;\n error: Error | null;\n selectedValues: string[];\n onChange: (values: string[]) => void;\n colorMap?: Record<string, string>;\n displayMode?: ListogramDisplayMode;\n showCount?: boolean;\n isExcluding?: boolean;\n className?: string;\n style?: React.CSSProperties;\n maxVisibleItems?: number;\n searchQuery?: string;\n renderValue?: (value: string) => string;\n}\n\nfunction ListogramInputInner({\n values,\n maxCount,\n isLoading,\n error,\n selectedValues,\n onChange,\n colorMap,\n displayMode = \"full\",\n showCount = true,\n isExcluding,\n className,\n style,\n maxVisibleItems,\n searchQuery,\n renderValue,\n}: ListogramInputProps): React.ReactElement {\n const [isExpanded, setIsExpanded] = useState(false);\n\n const stableValues = useStableData(values, isLoading);\n\n const selectedSet = useMemo(() => new Set(selectedValues), [selectedValues]);\n\n const toggleValue = useCallback(\n (value: string) => {\n if (selectedSet.has(value)) {\n onChange(selectedValues.filter((v) => v !== value));\n } else {\n onChange([...selectedValues, value]);\n }\n },\n [selectedValues, selectedSet, onChange],\n );\n\n const filteredValues = useMemo(() => {\n if (searchQuery) {\n return filterValuesBySearch(\n stableValues,\n searchQuery,\n (v) => renderValue?.(v.value) ?? v.value,\n );\n }\n return stableValues;\n }, [stableValues, searchQuery, renderValue]);\n\n const sortedValues = useMemo(() => {\n const selected = filteredValues.filter((v) => selectedSet.has(v.value));\n const unselected = filteredValues.filter((v) => !selectedSet.has(v.value));\n return [...selected, ...unselected];\n }, [filteredValues, selectedSet]);\n\n const displayValues = useMemo(() => {\n if (isExpanded || !maxVisibleItems) return sortedValues;\n return sortedValues.slice(0, maxVisibleItems);\n }, [sortedValues, maxVisibleItems, isExpanded]);\n\n const hasMore = maxVisibleItems != null\n && sortedValues.length > maxVisibleItems;\n\n return (\n <div\n className={classnames(styles.listogram, className)}\n style={style}\n data-loading={isLoading && filteredValues.length > 0}\n >\n {error && (\n <div className={sharedStyles.errorMessage}>\n Error loading values: {error.message}\n </div>\n )}\n\n {!error && filteredValues.length === 0 && isLoading && (\n <ListogramSkeleton />\n )}\n {!error && filteredValues.length === 0 && !isLoading && (\n <div className={sharedStyles.emptyMessage}>No values available</div>\n )}\n\n {filteredValues.length > 0 && (\n <div className={styles.container}>\n {displayValues.map(({ value, count }) => {\n const percentage = maxCount > 0 ? (count / maxCount) * 100 : 0;\n const perRowColor = colorMap?.[value];\n const isEmpty = value === \"\";\n const displayLabel = isEmpty\n ? \"No value\"\n : (renderValue?.(value) ?? value);\n\n return (\n <Button\n key={value}\n className={styles.row}\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => toggleValue(value)}\n aria-pressed={selectedSet.has(value)}\n style={perRowColor || percentage > 0\n ? ({\n \"--osdk-filter-listogram-bar-fill-scale\": percentage / 100,\n ...(perRowColor\n ? {\n \"--osdk-filter-listogram-row-bar-color\": perRowColor,\n }\n : undefined),\n } as React.CSSProperties)\n : undefined}\n >\n <span\n className={styles.checkbox}\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={selectedSet.has(value)}\n // eslint-disable-next-line react/jsx-no-bind\n onCheckedChange={() => toggleValue(value)}\n isExcluding={isExcluding}\n />\n </span>\n <span\n className={classnames(\n styles.label,\n isEmpty && styles.emptyLabel,\n )}\n data-excluding={(isExcluding && selectedSet.has(value))\n || undefined}\n >\n {displayLabel}\n </span>\n {showCount && displayMode !== \"minimal\" && (\n <span className={styles.count}>{count.toLocaleString()}</span>\n )}\n {displayMode === \"full\" && (\n <span className={styles.bar}>\n <span className={styles.barFill} />\n </span>\n )}\n </Button>\n );\n })}\n\n {hasMore && !isExpanded && (\n <Button\n type=\"button\"\n className={styles.viewAllButton}\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => setIsExpanded(true)}\n >\n View all ({sortedValues.length})\n </Button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport const ListogramInput = memo(\n ListogramInputInner,\n) as typeof ListogramInputInner;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"ListogramInput.js","names":["Button","classnames","React","memo","useCallback","useMemo","useState","Checkbox","filterValuesBySearch","isEmptyValue","styles","ListogramSkeleton","NoValueLabel","sharedStyles","useStableData","ListogramInputInner","values","maxCount","isLoading","error","selectedValues","onChange","colorMap","displayMode","showCount","isExcluding","className","style","maxVisibleItems","searchQuery","renderValue","isExpanded","setIsExpanded","dedupedValues","out","emptyCount","firstEmptyIndex","v","value","length","count","push","splice","isNull","stableValues","selectedSet","Set","toggleValue","has","filter","filteredValues","sortedValues","selected","unselected","displayValues","slice","hasMore","createElement","listogram","errorMessage","message","emptyMessage","container","map","percentage","perRowColor","isEmpty","key","row","onClick","undefined","checkbox","e","stopPropagation","checked","onCheckedChange","label","noValueLabel","toLocaleString","bar","barFill","type","viewAllButton","ListogramInput"],"sources":["ListogramInput.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 { Button } from \"@base-ui/react/button\";\nimport classnames from \"classnames\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\nimport { Checkbox } from \"../../../base-components/checkbox/Checkbox.js\";\nimport type { PropertyAggregationValue } from \"../../types/AggregationTypes.js\";\nimport {\n filterValuesBySearch,\n isEmptyValue,\n} from \"../../utils/filterValues.js\";\nimport styles from \"./ListogramInput.module.css\";\nimport { ListogramSkeleton } from \"./ListogramSkeleton.js\";\nimport { NoValueLabel } from \"./NoValueLabel.js\";\nimport sharedStyles from \"./shared.module.css\";\nimport { useStableData } from \"./useStableData.js\";\n\nexport type ListogramDisplayMode = \"full\" | \"count\" | \"minimal\";\n\ninterface ListogramInputProps {\n values: PropertyAggregationValue[];\n maxCount: number;\n isLoading: boolean;\n error: Error | null;\n selectedValues: string[];\n onChange: (values: string[]) => void;\n colorMap?: Record<string, string>;\n displayMode?: ListogramDisplayMode;\n showCount?: boolean;\n isExcluding?: boolean;\n className?: string;\n style?: React.CSSProperties;\n maxVisibleItems?: number;\n searchQuery?: string;\n renderValue?: (value: string) => string;\n}\n\nfunction ListogramInputInner({\n values,\n maxCount,\n isLoading,\n error,\n selectedValues,\n onChange,\n colorMap,\n displayMode = \"full\",\n showCount = true,\n isExcluding,\n className,\n style,\n maxVisibleItems,\n searchQuery,\n renderValue,\n}: ListogramInputProps): React.ReactElement {\n const [isExpanded, setIsExpanded] = useState(false);\n\n // Aggregations may return both \"\" and null as separate rows; merge them\n // into a single \"No value\" placeholder at the position of the first match.\n const dedupedValues = useMemo(() => {\n const out: PropertyAggregationValue[] = [];\n let emptyCount = 0;\n let firstEmptyIndex = -1;\n for (const v of values) {\n if (v.value === \"\" || v.value == null) {\n if (firstEmptyIndex === -1) {\n firstEmptyIndex = out.length;\n }\n emptyCount += v.count;\n } else {\n out.push(v);\n }\n }\n if (firstEmptyIndex >= 0 && emptyCount > 0) {\n out.splice(firstEmptyIndex, 0, {\n value: \"\",\n count: emptyCount,\n isNull: true,\n });\n }\n return out;\n }, [values]);\n\n const stableValues = useStableData(dedupedValues, isLoading);\n\n const selectedSet = useMemo(() => new Set(selectedValues), [selectedValues]);\n\n const toggleValue = useCallback(\n (value: string) => {\n if (selectedSet.has(value)) {\n onChange(selectedValues.filter((v) => v !== value));\n } else {\n onChange([...selectedValues, value]);\n }\n },\n [selectedValues, selectedSet, onChange],\n );\n\n const filteredValues = useMemo(() => {\n if (searchQuery) {\n return filterValuesBySearch(\n stableValues,\n searchQuery,\n (v) => renderValue?.(v.value) ?? v.value,\n );\n }\n return stableValues;\n }, [stableValues, searchQuery, renderValue]);\n\n const sortedValues = useMemo(() => {\n const selected = filteredValues.filter((v) => selectedSet.has(v.value));\n const unselected = filteredValues.filter((v) => !selectedSet.has(v.value));\n return [...selected, ...unselected];\n }, [filteredValues, selectedSet]);\n\n const displayValues = useMemo(() => {\n if (isExpanded || !maxVisibleItems) return sortedValues;\n return sortedValues.slice(0, maxVisibleItems);\n }, [sortedValues, maxVisibleItems, isExpanded]);\n\n const hasMore = maxVisibleItems != null\n && sortedValues.length > maxVisibleItems;\n\n return (\n <div\n className={classnames(styles.listogram, className)}\n style={style}\n data-loading={isLoading && filteredValues.length > 0}\n >\n {error && (\n <div className={sharedStyles.errorMessage}>\n Error loading values: {error.message}\n </div>\n )}\n\n {!error && filteredValues.length === 0 && isLoading && (\n <ListogramSkeleton />\n )}\n {!error && filteredValues.length === 0 && !isLoading && (\n <div className={sharedStyles.emptyMessage}>No values available</div>\n )}\n\n {filteredValues.length > 0 && (\n <div className={styles.container}>\n {displayValues.map(({ value, count }) => {\n const percentage = maxCount > 0 ? (count / maxCount) * 100 : 0;\n const perRowColor = colorMap?.[value];\n const isEmpty = isEmptyValue(value);\n\n return (\n <Button\n key={value}\n className={styles.row}\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => toggleValue(value)}\n aria-pressed={selectedSet.has(value)}\n style={perRowColor || percentage > 0\n ? ({\n \"--osdk-filter-listogram-bar-fill-scale\": percentage / 100,\n ...(perRowColor\n ? {\n \"--osdk-filter-listogram-row-bar-color\": perRowColor,\n }\n : undefined),\n } as React.CSSProperties)\n : undefined}\n >\n <span\n className={styles.checkbox}\n onClick={(e) => e.stopPropagation()}\n >\n <Checkbox\n checked={selectedSet.has(value)}\n // eslint-disable-next-line react/jsx-no-bind\n onCheckedChange={() => toggleValue(value)}\n isExcluding={isExcluding}\n />\n </span>\n <span\n className={styles.label}\n data-excluding={(isExcluding && selectedSet.has(value))\n || undefined}\n >\n {isEmpty\n ? <NoValueLabel className={styles.noValueLabel} />\n : (renderValue?.(value) ?? value)}\n </span>\n {showCount && displayMode !== \"minimal\" && (\n <span className={styles.count}>{count.toLocaleString()}</span>\n )}\n {displayMode === \"full\" && (\n <span className={styles.bar}>\n <span className={styles.barFill} />\n </span>\n )}\n </Button>\n );\n })}\n\n {hasMore && !isExpanded && (\n <Button\n type=\"button\"\n className={styles.viewAllButton}\n // eslint-disable-next-line react/jsx-no-bind\n onClick={() => setIsExpanded(true)}\n >\n View all ({sortedValues.length})\n </Button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nexport const ListogramInput = memo(\n ListogramInputInner,\n) as typeof ListogramInputInner;\n"],"mappings":"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","ignoreList":[]}
@@ -20,6 +20,17 @@
20
20
  transition: opacity var(--osdk-filter-content-fade-duration);
21
21
  }
22
22
 
23
+ .noValueLabel {
24
+ color: var(
25
+ --osdk-filter-listogram-empty-label-color,
26
+ var(--osdk-filter-no-value-color)
27
+ );
28
+ font-style: var(
29
+ --osdk-filter-listogram-empty-label-font-style,
30
+ var(--osdk-filter-no-value-font-style)
31
+ );
32
+ }
33
+
23
34
  .listogram[data-loading="true"] {
24
35
  opacity: 0.5;
25
36
  }
@@ -77,11 +88,6 @@
77
88
  text-decoration: line-through;
78
89
  }
79
90
 
80
- .emptyLabel {
81
- color: var(--osdk-filter-listogram-empty-label-color);
82
- font-style: var(--osdk-filter-listogram-empty-label-font-style);
83
- }
84
-
85
91
  .bar {
86
92
  width: var(--osdk-filter-listogram-bar-width);
87
93
  flex-shrink: 0;
@@ -17,7 +17,9 @@
17
17
  import classnames from "classnames";
18
18
  import React, { memo, useCallback, useMemo } from "react";
19
19
  import { Combobox } from "../../../base-components/combobox/Combobox.js";
20
+ import { isEmptyValue } from "../../utils/filterValues.js";
20
21
  import styles from "./MultiSelectInput.module.css";
22
+ import { NoValueLabel } from "./NoValueLabel.js";
21
23
  import sharedStyles from "./shared.module.css";
22
24
  function MultiSelectInputInner({
23
25
  values,
@@ -43,18 +45,24 @@ function MultiSelectInputInner({
43
45
  count
44
46
  }) => [value, count])), [values]);
45
47
  const comboboxFilter = useMemo(() => renderValue ? (itemValue, query) => renderValue(itemValue).toLowerCase().includes(query.toLowerCase()) : undefined, [renderValue]);
46
- const renderItem = useCallback(value => /*#__PURE__*/React.createElement(Combobox.Item, {
47
- key: value,
48
- value: value
49
- }, /*#__PURE__*/React.createElement(Combobox.ItemIndicator, null), /*#__PURE__*/React.createElement("span", {
50
- className: styles.itemLabel
51
- }, renderValue ? renderValue(value) : value), showCounts && /*#__PURE__*/React.createElement("span", {
52
- className: styles.itemCount
53
- }, "(", (countByValue.get(value) ?? 0).toLocaleString(), ")")), [countByValue, showCounts, renderValue]);
54
- const renderChips = useCallback(selectedItems => /*#__PURE__*/React.createElement(React.Fragment, null, selectedItems.map(value => /*#__PURE__*/React.createElement(Combobox.Chip, {
55
- key: value,
56
- "aria-label": value
57
- }, renderValue ? renderValue(value) : value, /*#__PURE__*/React.createElement(Combobox.ChipRemove, null))), /*#__PURE__*/React.createElement(Combobox.Input, {
48
+ const renderItem = useCallback(value => {
49
+ const isEmpty = isEmptyValue(value);
50
+ return /*#__PURE__*/React.createElement(Combobox.Item, {
51
+ key: value,
52
+ value: value
53
+ }, /*#__PURE__*/React.createElement(Combobox.ItemIndicator, null), /*#__PURE__*/React.createElement("span", {
54
+ className: styles.itemLabel
55
+ }, isEmpty ? /*#__PURE__*/React.createElement(NoValueLabel, null) : renderValue ? renderValue(value) : value), showCounts && /*#__PURE__*/React.createElement("span", {
56
+ className: styles.itemCount
57
+ }, "(", (countByValue.get(value) ?? 0).toLocaleString(), ")"));
58
+ }, [countByValue, showCounts, renderValue]);
59
+ const renderChips = useCallback(selectedItems => /*#__PURE__*/React.createElement(React.Fragment, null, selectedItems.map(value => {
60
+ const isEmpty = isEmptyValue(value);
61
+ return /*#__PURE__*/React.createElement(Combobox.Chip, {
62
+ key: value,
63
+ "aria-label": isEmpty ? "No value" : value
64
+ }, isEmpty ? /*#__PURE__*/React.createElement(NoValueLabel, null) : renderValue ? renderValue(value) : value, /*#__PURE__*/React.createElement(Combobox.ChipRemove, null));
65
+ }), /*#__PURE__*/React.createElement(Combobox.Input, {
58
66
  placeholder: selectedItems.length > 0 ? "" : placeholder,
59
67
  "aria-label": ariaLabel
60
68
  })), [placeholder, ariaLabel, renderValue]);
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelectInput.js","names":["classnames","React","memo","useCallback","useMemo","Combobox","styles","sharedStyles","MultiSelectInputInner","values","isLoading","error","selectedValues","onChange","className","style","placeholder","showCounts","ariaLabel","renderValue","handleValueChange","newValues","items","map","value","countByValue","Map","count","comboboxFilter","itemValue","query","toLowerCase","includes","undefined","renderItem","createElement","Item","key","ItemIndicator","itemLabel","itemCount","get","toLocaleString","renderChips","selectedItems","Fragment","Chip","ChipRemove","Input","length","multiSelect","errorMessage","message","emptyMessage","Root","multiple","onValueChange","filter","loadingMessage","Chips","Value","Portal","Positioner","Popup","Empty","List","MultiSelectInput"],"sources":["MultiSelectInput.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 classnames from \"classnames\";\nimport React, { memo, useCallback, useMemo } from \"react\";\nimport { Combobox } from \"../../../base-components/combobox/Combobox.js\";\nimport type { PropertyAggregationValue } from \"../../types/AggregationTypes.js\";\nimport styles from \"./MultiSelectInput.module.css\";\nimport sharedStyles from \"./shared.module.css\";\n\ninterface MultiSelectInputProps {\n values: PropertyAggregationValue[];\n isLoading: boolean;\n error: Error | null;\n selectedValues: string[];\n onChange: (values: string[]) => void;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n showCounts?: boolean;\n ariaLabel?: string;\n renderValue?: (value: string) => string;\n}\n\nfunction MultiSelectInputInner({\n values,\n isLoading,\n error,\n selectedValues,\n onChange,\n className,\n style,\n placeholder = \"Select values...\",\n showCounts = true,\n ariaLabel = \"Search values\",\n renderValue,\n}: MultiSelectInputProps): React.ReactElement {\n const handleValueChange = useCallback(\n (newValues: string[] | null) => {\n onChange(newValues ?? []);\n },\n [onChange],\n );\n\n const items = useMemo(\n () => values.map(({ value }) => value),\n [values],\n );\n\n const countByValue = useMemo(\n () => new Map(values.map(({ value, count }) => [value, count])),\n [values],\n );\n\n const comboboxFilter = useMemo(\n () =>\n renderValue\n ? (itemValue: string, query: string) =>\n renderValue(itemValue).toLowerCase().includes(query.toLowerCase())\n : undefined,\n [renderValue],\n );\n\n const renderItem = useCallback(\n (value: string) => (\n <Combobox.Item key={value} value={value}>\n <Combobox.ItemIndicator />\n <span className={styles.itemLabel}>\n {renderValue ? renderValue(value) : value}\n </span>\n {showCounts && (\n <span className={styles.itemCount}>\n ({(countByValue.get(value) ?? 0).toLocaleString()})\n </span>\n )}\n </Combobox.Item>\n ),\n [countByValue, showCounts, renderValue],\n );\n\n const renderChips = useCallback(\n (selectedItems: string[]) => (\n <>\n {selectedItems.map((value) => (\n <Combobox.Chip\n key={value}\n aria-label={value}\n >\n {renderValue ? renderValue(value) : value}\n <Combobox.ChipRemove />\n </Combobox.Chip>\n ))}\n <Combobox.Input\n placeholder={selectedItems.length > 0 ? \"\" : placeholder}\n aria-label={ariaLabel}\n />\n </>\n ),\n [placeholder, ariaLabel, renderValue],\n );\n\n return (\n <div\n className={classnames(styles.multiSelect, className)}\n style={style}\n data-loading={isLoading}\n >\n {error && (\n <div className={sharedStyles.errorMessage}>\n Error loading options: {error.message}\n </div>\n )}\n\n {!error && values.length === 0 && (\n <div className={sharedStyles.emptyMessage}>\n {isLoading ? \"Loading options...\" : \"No options available\"}\n </div>\n )}\n\n {(values.length > 0 || isLoading) && (\n <Combobox.Root<string, true>\n multiple={true}\n value={selectedValues}\n onValueChange={handleValueChange}\n items={items}\n filter={comboboxFilter}\n >\n {isLoading && (\n <div className={sharedStyles.loadingMessage}>\n Updating...\n </div>\n )}\n\n <Combobox.Chips>\n <Combobox.Value>{renderChips}</Combobox.Value>\n </Combobox.Chips>\n\n <Combobox.Portal>\n <Combobox.Positioner>\n <Combobox.Popup>\n <Combobox.Empty>No matching options</Combobox.Empty>\n <Combobox.List>{renderItem}</Combobox.List>\n </Combobox.Popup>\n </Combobox.Positioner>\n </Combobox.Portal>\n </Combobox.Root>\n )}\n </div>\n );\n}\n\nexport const MultiSelectInput = memo(\n MultiSelectInputInner,\n) as typeof MultiSelectInputInner;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"MultiSelectInput.js","names":["classnames","React","memo","useCallback","useMemo","Combobox","isEmptyValue","styles","NoValueLabel","sharedStyles","MultiSelectInputInner","values","isLoading","error","selectedValues","onChange","className","style","placeholder","showCounts","ariaLabel","renderValue","handleValueChange","newValues","items","map","value","countByValue","Map","count","comboboxFilter","itemValue","query","toLowerCase","includes","undefined","renderItem","isEmpty","createElement","Item","key","ItemIndicator","itemLabel","itemCount","get","toLocaleString","renderChips","selectedItems","Fragment","Chip","ChipRemove","Input","length","multiSelect","errorMessage","message","emptyMessage","Root","multiple","onValueChange","filter","loadingMessage","Chips","Value","Portal","Positioner","Popup","Empty","List","MultiSelectInput"],"sources":["MultiSelectInput.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 classnames from \"classnames\";\nimport React, { memo, useCallback, useMemo } from \"react\";\nimport { Combobox } from \"../../../base-components/combobox/Combobox.js\";\nimport type { PropertyAggregationValue } from \"../../types/AggregationTypes.js\";\nimport { isEmptyValue } from \"../../utils/filterValues.js\";\nimport styles from \"./MultiSelectInput.module.css\";\nimport { NoValueLabel } from \"./NoValueLabel.js\";\nimport sharedStyles from \"./shared.module.css\";\n\ninterface MultiSelectInputProps {\n values: PropertyAggregationValue[];\n isLoading: boolean;\n error: Error | null;\n selectedValues: string[];\n onChange: (values: string[]) => void;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n showCounts?: boolean;\n ariaLabel?: string;\n renderValue?: (value: string) => string;\n}\n\nfunction MultiSelectInputInner({\n values,\n isLoading,\n error,\n selectedValues,\n onChange,\n className,\n style,\n placeholder = \"Select values...\",\n showCounts = true,\n ariaLabel = \"Search values\",\n renderValue,\n}: MultiSelectInputProps): React.ReactElement {\n const handleValueChange = useCallback(\n (newValues: string[] | null) => {\n onChange(newValues ?? []);\n },\n [onChange],\n );\n\n const items = useMemo(\n () => values.map(({ value }) => value),\n [values],\n );\n\n const countByValue = useMemo(\n () => new Map(values.map(({ value, count }) => [value, count])),\n [values],\n );\n\n const comboboxFilter = useMemo(\n () =>\n renderValue\n ? (itemValue: string, query: string) =>\n renderValue(itemValue).toLowerCase().includes(query.toLowerCase())\n : undefined,\n [renderValue],\n );\n\n const renderItem = useCallback(\n (value: string) => {\n const isEmpty = isEmptyValue(value);\n return (\n <Combobox.Item key={value} value={value}>\n <Combobox.ItemIndicator />\n <span className={styles.itemLabel}>\n {isEmpty\n ? <NoValueLabel />\n : (renderValue ? renderValue(value) : value)}\n </span>\n {showCounts && (\n <span className={styles.itemCount}>\n ({(countByValue.get(value) ?? 0).toLocaleString()})\n </span>\n )}\n </Combobox.Item>\n );\n },\n [countByValue, showCounts, renderValue],\n );\n\n const renderChips = useCallback(\n (selectedItems: string[]) => (\n <>\n {selectedItems.map((value) => {\n const isEmpty = isEmptyValue(value);\n return (\n <Combobox.Chip\n key={value}\n aria-label={isEmpty ? \"No value\" : value}\n >\n {isEmpty\n ? <NoValueLabel />\n : (renderValue ? renderValue(value) : value)}\n <Combobox.ChipRemove />\n </Combobox.Chip>\n );\n })}\n <Combobox.Input\n placeholder={selectedItems.length > 0 ? \"\" : placeholder}\n aria-label={ariaLabel}\n />\n </>\n ),\n [placeholder, ariaLabel, renderValue],\n );\n\n return (\n <div\n className={classnames(styles.multiSelect, className)}\n style={style}\n data-loading={isLoading}\n >\n {error && (\n <div className={sharedStyles.errorMessage}>\n Error loading options: {error.message}\n </div>\n )}\n\n {!error && values.length === 0 && (\n <div className={sharedStyles.emptyMessage}>\n {isLoading ? \"Loading options...\" : \"No options available\"}\n </div>\n )}\n\n {(values.length > 0 || isLoading) && (\n <Combobox.Root<string, true>\n multiple={true}\n value={selectedValues}\n onValueChange={handleValueChange}\n items={items}\n filter={comboboxFilter}\n >\n {isLoading && (\n <div className={sharedStyles.loadingMessage}>\n Updating...\n </div>\n )}\n\n <Combobox.Chips>\n <Combobox.Value>{renderChips}</Combobox.Value>\n </Combobox.Chips>\n\n <Combobox.Portal>\n <Combobox.Positioner>\n <Combobox.Popup>\n <Combobox.Empty>No matching options</Combobox.Empty>\n <Combobox.List>{renderItem}</Combobox.List>\n </Combobox.Popup>\n </Combobox.Positioner>\n </Combobox.Portal>\n </Combobox.Root>\n )}\n </div>\n );\n}\n\nexport const MultiSelectInput = memo(\n MultiSelectInputInner,\n) as typeof MultiSelectInputInner;\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,36 @@
1
+ /*
2
+ * Copyright 2025 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 classnames from "classnames";
18
+ import React, { memo } from "react";
19
+ import styles from "./NoValueLabel.module.css";
20
+ /**
21
+ * Canonical "No value" rendering for empty/null filter values.
22
+ * Italic, muted span used in dropdowns, listogram buckets, and
23
+ * NullValueWrapper.
24
+ *
25
+ * Style is configurable via the `--osdk-filter-no-value-color` and
26
+ * `--osdk-filter-no-value-font-style` CSS variables.
27
+ */
28
+ function NoValueLabelInner({
29
+ className
30
+ }) {
31
+ return /*#__PURE__*/React.createElement("span", {
32
+ className: classnames(styles.noValue, className)
33
+ }, "No value");
34
+ }
35
+ export const NoValueLabel = /*#__PURE__*/memo(NoValueLabelInner);
36
+ //# sourceMappingURL=NoValueLabel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoValueLabel.js","names":["classnames","React","memo","styles","NoValueLabelInner","className","createElement","noValue","NoValueLabel"],"sources":["NoValueLabel.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 classnames from \"classnames\";\nimport React, { memo } from \"react\";\nimport styles from \"./NoValueLabel.module.css\";\n\ninterface NoValueLabelProps {\n className?: string;\n}\n\n/**\n * Canonical \"No value\" rendering for empty/null filter values.\n * Italic, muted span used in dropdowns, listogram buckets, and\n * NullValueWrapper.\n *\n * Style is configurable via the `--osdk-filter-no-value-color` and\n * `--osdk-filter-no-value-font-style` CSS variables.\n */\nfunction NoValueLabelInner(\n { className }: NoValueLabelProps,\n): React.ReactElement {\n return (\n <span className={classnames(styles.noValue, className)}>\n No value\n </span>\n );\n}\n\nexport const NoValueLabel = memo(NoValueLabelInner) as typeof NoValueLabelInner;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,UAAU,MAAM,YAAY;AACnC,OAAOC,KAAK,IAAIC,IAAI,QAAQ,OAAO;AACnC,OAAOC,MAAM,MAAM,2BAA2B;AAM9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASC,iBAAiBA,CACxB;EAAEC;AAA6B,CAAC,EACZ;EACpB,oBACEJ,KAAA,CAAAK,aAAA;IAAMD,SAAS,EAAEL,UAAU,CAACG,MAAM,CAACI,OAAO,EAAEF,SAAS;EAAE,GAAC,UAElD,CAAC;AAEX;AAEA,OAAO,MAAMG,YAAY,gBAAGN,IAAI,CAACE,iBAAiB,CAA6B","ignoreList":[]}
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright 2025 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
+ .noValue {
18
+ color: var(--osdk-filter-no-value-color);
19
+ font-style: var(--osdk-filter-no-value-font-style);
20
+ }
@@ -17,6 +17,7 @@
17
17
  import classnames from "classnames";
18
18
  import React, { memo, useCallback } from "react";
19
19
  import { Checkbox } from "../../../base-components/checkbox/Checkbox.js";
20
+ import { NoValueLabel } from "./NoValueLabel.js";
20
21
  import styles from "./NullValueWrapper.module.css";
21
22
  import sharedStyles from "./shared.module.css";
22
23
  function NullValueWrapperInner({
@@ -45,9 +46,9 @@ function NullValueWrapperInner({
45
46
  }, /*#__PURE__*/React.createElement(Checkbox, {
46
47
  checked: includeNull,
47
48
  onCheckedChange: handleToggle
48
- }), /*#__PURE__*/React.createElement("span", {
49
- className: styles.nullLabelText
50
- }, "No value")), showNullCount && !error && /*#__PURE__*/React.createElement("span", {
49
+ }), /*#__PURE__*/React.createElement(NoValueLabel, {
50
+ className: styles.noValueLabel
51
+ })), showNullCount && !error && /*#__PURE__*/React.createElement("span", {
51
52
  className: styles.count
52
53
  }, nullCount.toLocaleString())), error && /*#__PURE__*/React.createElement("div", {
53
54
  className: sharedStyles.errorMessage
@@ -1 +1 @@
1
- {"version":3,"file":"NullValueWrapper.js","names":["classnames","React","memo","useCallback","Checkbox","styles","sharedStyles","NullValueWrapperInner","nullCount","isLoading","error","includeNull","onIncludeNullChange","showNullCount","children","className","style","handleToggle","createElement","nullWrapper","nullValueRow","nullLabel","checked","onCheckedChange","nullLabelText","count","toLocaleString","errorMessage","NullValueWrapper"],"sources":["NullValueWrapper.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 classnames from \"classnames\";\nimport React, { memo, useCallback } from \"react\";\nimport { Checkbox } from \"../../../base-components/checkbox/Checkbox.js\";\nimport styles from \"./NullValueWrapper.module.css\";\nimport sharedStyles from \"./shared.module.css\";\n\ninterface NullValueWrapperProps {\n nullCount: number;\n isLoading: boolean;\n error?: Error | null;\n includeNull?: boolean;\n onIncludeNullChange: (include: boolean) => void;\n showNullCount?: boolean;\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nfunction NullValueWrapperInner({\n nullCount,\n isLoading,\n error,\n includeNull = false,\n onIncludeNullChange,\n showNullCount = true,\n children,\n className,\n style,\n}: NullValueWrapperProps): React.ReactElement {\n const handleToggle = useCallback(() => {\n onIncludeNullChange(!includeNull);\n }, [includeNull, onIncludeNullChange]);\n\n return (\n <div className={classnames(styles.nullWrapper, className)} style={style}>\n {children}\n\n <div\n className={styles.nullValueRow}\n data-checked={includeNull}\n data-loading={isLoading}\n >\n <label className={styles.nullLabel}>\n <Checkbox checked={includeNull} onCheckedChange={handleToggle} />\n <span className={styles.nullLabelText}>No value</span>\n </label>\n {showNullCount && !error && (\n <span className={styles.count}>\n {nullCount.toLocaleString()}\n </span>\n )}\n </div>\n {error && (\n <div className={sharedStyles.errorMessage}>\n Failed to load null count\n </div>\n )}\n </div>\n );\n}\n\nexport const NullValueWrapper = memo(\n NullValueWrapperInner,\n) as typeof NullValueWrapperInner;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,UAAU,MAAM,YAAY;AACnC,OAAOC,KAAK,IAAIC,IAAI,EAAEC,WAAW,QAAQ,OAAO;AAChD,SAASC,QAAQ,QAAQ,+CAA+C;AACxE,OAAOC,MAAM,MAAM,+BAA+B;AAClD,OAAOC,YAAY,MAAM,qBAAqB;AAc9C,SAASC,qBAAqBA,CAAC;EAC7BC,SAAS;EACTC,SAAS;EACTC,KAAK;EACLC,WAAW,GAAG,KAAK;EACnBC,mBAAmB;EACnBC,aAAa,GAAG,IAAI;EACpBC,QAAQ;EACRC,SAAS;EACTC;AACqB,CAAC,EAAsB;EAC5C,MAAMC,YAAY,GAAGd,WAAW,CAAC,MAAM;IACrCS,mBAAmB,CAAC,CAACD,WAAW,CAAC;EACnC,CAAC,EAAE,CAACA,WAAW,EAAEC,mBAAmB,CAAC,CAAC;EAEtC,oBACEX,KAAA,CAAAiB,aAAA;IAAKH,SAAS,EAAEf,UAAU,CAACK,MAAM,CAACc,WAAW,EAAEJ,SAAS,CAAE;IAACC,KAAK,EAAEA;EAAM,GACrEF,QAAQ,eAETb,KAAA,CAAAiB,aAAA;IACEH,SAAS,EAAEV,MAAM,CAACe,YAAa;IAC/B,gBAAcT,WAAY;IAC1B,gBAAcF;EAAU,gBAExBR,KAAA,CAAAiB,aAAA;IAAOH,SAAS,EAAEV,MAAM,CAACgB;EAAU,gBACjCpB,KAAA,CAAAiB,aAAA,CAACd,QAAQ;IAACkB,OAAO,EAAEX,WAAY;IAACY,eAAe,EAAEN;EAAa,CAAE,CAAC,eACjEhB,KAAA,CAAAiB,aAAA;IAAMH,SAAS,EAAEV,MAAM,CAACmB;EAAc,GAAC,UAAc,CAChD,CAAC,EACPX,aAAa,IAAI,CAACH,KAAK,iBACtBT,KAAA,CAAAiB,aAAA;IAAMH,SAAS,EAAEV,MAAM,CAACoB;EAAM,GAC3BjB,SAAS,CAACkB,cAAc,CAAC,CACtB,CAEL,CAAC,EACLhB,KAAK,iBACJT,KAAA,CAAAiB,aAAA;IAAKH,SAAS,EAAET,YAAY,CAACqB;EAAa,GAAC,2BAEtC,CAEJ,CAAC;AAEV;AAEA,OAAO,MAAMC,gBAAgB,gBAAG1B,IAAI,CAClCK,qBACF,CAAiC","ignoreList":[]}
1
+ {"version":3,"file":"NullValueWrapper.js","names":["classnames","React","memo","useCallback","Checkbox","NoValueLabel","styles","sharedStyles","NullValueWrapperInner","nullCount","isLoading","error","includeNull","onIncludeNullChange","showNullCount","children","className","style","handleToggle","createElement","nullWrapper","nullValueRow","nullLabel","checked","onCheckedChange","noValueLabel","count","toLocaleString","errorMessage","NullValueWrapper"],"sources":["NullValueWrapper.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 classnames from \"classnames\";\nimport React, { memo, useCallback } from \"react\";\nimport { Checkbox } from \"../../../base-components/checkbox/Checkbox.js\";\nimport { NoValueLabel } from \"./NoValueLabel.js\";\nimport styles from \"./NullValueWrapper.module.css\";\nimport sharedStyles from \"./shared.module.css\";\n\ninterface NullValueWrapperProps {\n nullCount: number;\n isLoading: boolean;\n error?: Error | null;\n includeNull?: boolean;\n onIncludeNullChange: (include: boolean) => void;\n showNullCount?: boolean;\n children: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n}\n\nfunction NullValueWrapperInner({\n nullCount,\n isLoading,\n error,\n includeNull = false,\n onIncludeNullChange,\n showNullCount = true,\n children,\n className,\n style,\n}: NullValueWrapperProps): React.ReactElement {\n const handleToggle = useCallback(() => {\n onIncludeNullChange(!includeNull);\n }, [includeNull, onIncludeNullChange]);\n\n return (\n <div className={classnames(styles.nullWrapper, className)} style={style}>\n {children}\n\n <div\n className={styles.nullValueRow}\n data-checked={includeNull}\n data-loading={isLoading}\n >\n <label className={styles.nullLabel}>\n <Checkbox checked={includeNull} onCheckedChange={handleToggle} />\n <NoValueLabel className={styles.noValueLabel} />\n </label>\n {showNullCount && !error && (\n <span className={styles.count}>\n {nullCount.toLocaleString()}\n </span>\n )}\n </div>\n {error && (\n <div className={sharedStyles.errorMessage}>\n Failed to load null count\n </div>\n )}\n </div>\n );\n}\n\nexport const NullValueWrapper = memo(\n NullValueWrapperInner,\n) as typeof NullValueWrapperInner;\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,OAAOA,UAAU,MAAM,YAAY;AACnC,OAAOC,KAAK,IAAIC,IAAI,EAAEC,WAAW,QAAQ,OAAO;AAChD,SAASC,QAAQ,QAAQ,+CAA+C;AACxE,SAASC,YAAY,QAAQ,mBAAmB;AAChD,OAAOC,MAAM,MAAM,+BAA+B;AAClD,OAAOC,YAAY,MAAM,qBAAqB;AAc9C,SAASC,qBAAqBA,CAAC;EAC7BC,SAAS;EACTC,SAAS;EACTC,KAAK;EACLC,WAAW,GAAG,KAAK;EACnBC,mBAAmB;EACnBC,aAAa,GAAG,IAAI;EACpBC,QAAQ;EACRC,SAAS;EACTC;AACqB,CAAC,EAAsB;EAC5C,MAAMC,YAAY,GAAGf,WAAW,CAAC,MAAM;IACrCU,mBAAmB,CAAC,CAACD,WAAW,CAAC;EACnC,CAAC,EAAE,CAACA,WAAW,EAAEC,mBAAmB,CAAC,CAAC;EAEtC,oBACEZ,KAAA,CAAAkB,aAAA;IAAKH,SAAS,EAAEhB,UAAU,CAACM,MAAM,CAACc,WAAW,EAAEJ,SAAS,CAAE;IAACC,KAAK,EAAEA;EAAM,GACrEF,QAAQ,eAETd,KAAA,CAAAkB,aAAA;IACEH,SAAS,EAAEV,MAAM,CAACe,YAAa;IAC/B,gBAAcT,WAAY;IAC1B,gBAAcF;EAAU,gBAExBT,KAAA,CAAAkB,aAAA;IAAOH,SAAS,EAAEV,MAAM,CAACgB;EAAU,gBACjCrB,KAAA,CAAAkB,aAAA,CAACf,QAAQ;IAACmB,OAAO,EAAEX,WAAY;IAACY,eAAe,EAAEN;EAAa,CAAE,CAAC,eACjEjB,KAAA,CAAAkB,aAAA,CAACd,YAAY;IAACW,SAAS,EAAEV,MAAM,CAACmB;EAAa,CAAE,CAC1C,CAAC,EACPX,aAAa,IAAI,CAACH,KAAK,iBACtBV,KAAA,CAAAkB,aAAA;IAAMH,SAAS,EAAEV,MAAM,CAACoB;EAAM,GAC3BjB,SAAS,CAACkB,cAAc,CAAC,CACtB,CAEL,CAAC,EACLhB,KAAK,iBACJV,KAAA,CAAAkB,aAAA;IAAKH,SAAS,EAAET,YAAY,CAACqB;EAAa,GAAC,2BAEtC,CAEJ,CAAC;AAEV;AAEA,OAAO,MAAMC,gBAAgB,gBAAG3B,IAAI,CAClCM,qBACF,CAAiC","ignoreList":[]}
@@ -20,6 +20,16 @@
20
20
  gap: var(--osdk-filter-null-wrapper-gap);
21
21
  }
22
22
 
23
+ .noValueLabel {
24
+ color: var(
25
+ --osdk-filter-null-label-color,
26
+ var(--osdk-filter-no-value-color)
27
+ );
28
+ font-family: var(--osdk-filter-null-label-font-family, inherit);
29
+ font-size: var(--osdk-filter-null-label-font-size, inherit);
30
+ line-height: var(--osdk-filter-null-label-line-height, inherit);
31
+ }
32
+
23
33
  .nullValueRow {
24
34
  display: flex;
25
35
  align-items: center;
@@ -35,13 +45,6 @@
35
45
  cursor: pointer;
36
46
  }
37
47
 
38
- .nullLabelText {
39
- font-family: var(--osdk-filter-null-label-font-family);
40
- font-size: var(--osdk-filter-null-label-font-size);
41
- line-height: var(--osdk-filter-null-label-line-height);
42
- color: var(--osdk-filter-null-label-color);
43
- }
44
-
45
48
  .count {
46
49
  font-family: var(--osdk-filter-null-count-font-family);
47
50
  font-size: var(--osdk-filter-null-count-font-size);
@@ -17,6 +17,8 @@
17
17
  import classnames from "classnames";
18
18
  import React, { memo, useCallback, useMemo } from "react";
19
19
  import { Combobox } from "../../../base-components/combobox/Combobox.js";
20
+ import { isEmptyValue } from "../../utils/filterValues.js";
21
+ import { NoValueLabel } from "./NoValueLabel.js";
20
22
  import sharedStyles from "./shared.module.css";
21
23
  import styles from "./SingleSelectInput.module.css";
22
24
  function SingleSelectInputInner({
@@ -44,14 +46,17 @@ function SingleSelectInputInner({
44
46
  count
45
47
  }) => [value, count])), [values]);
46
48
  const comboboxFilter = useMemo(() => renderValue ? (itemValue, query) => renderValue(itemValue).toLowerCase().includes(query.toLowerCase()) : undefined, [renderValue]);
47
- const renderItem = useCallback(value => /*#__PURE__*/React.createElement(Combobox.Item, {
48
- key: value,
49
- value: value
50
- }, /*#__PURE__*/React.createElement(Combobox.ItemIndicator, null), /*#__PURE__*/React.createElement("span", {
51
- className: styles.itemLabel
52
- }, renderValue ? renderValue(value) : value), showCounts && /*#__PURE__*/React.createElement("span", {
53
- className: styles.itemCount
54
- }, "(", (countByValue.get(value) ?? 0).toLocaleString(), ")")), [countByValue, showCounts, renderValue]);
49
+ const renderItem = useCallback(value => {
50
+ const isEmpty = isEmptyValue(value);
51
+ return /*#__PURE__*/React.createElement(Combobox.Item, {
52
+ key: value,
53
+ value: value
54
+ }, /*#__PURE__*/React.createElement(Combobox.ItemIndicator, null), /*#__PURE__*/React.createElement("span", {
55
+ className: styles.itemLabel
56
+ }, isEmpty ? /*#__PURE__*/React.createElement(NoValueLabel, null) : renderValue ? renderValue(value) : value), showCounts && /*#__PURE__*/React.createElement("span", {
57
+ className: styles.itemCount
58
+ }, "(", (countByValue.get(value) ?? 0).toLocaleString(), ")"));
59
+ }, [countByValue, showCounts, renderValue]);
55
60
  return /*#__PURE__*/React.createElement("div", {
56
61
  className: classnames(styles.singleSelect, className),
57
62
  style: style,
@@ -1 +1 @@
1
- {"version":3,"file":"SingleSelectInput.js","names":["classnames","React","memo","useCallback","useMemo","Combobox","sharedStyles","styles","SingleSelectInputInner","values","isLoading","error","selectedValue","onChange","className","style","placeholder","showClearButton","showCounts","ariaLabel","renderValue","handleValueChange","value","undefined","items","map","countByValue","Map","count","comboboxFilter","itemValue","query","toLowerCase","includes","renderItem","createElement","Item","key","ItemIndicator","itemLabel","itemCount","get","toLocaleString","singleSelect","loadingMessage","errorMessage","message","length","emptyMessage","selectContainer","Root","onValueChange","filter","SearchInput","Clear","clearButton","Portal","Positioner","Popup","Empty","List","SingleSelectInput"],"sources":["SingleSelectInput.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 classnames from \"classnames\";\nimport React, { memo, useCallback, useMemo } from \"react\";\nimport { Combobox } from \"../../../base-components/combobox/Combobox.js\";\nimport type { PropertyAggregationValue } from \"../../types/AggregationTypes.js\";\nimport sharedStyles from \"./shared.module.css\";\nimport styles from \"./SingleSelectInput.module.css\";\n\ninterface SingleSelectInputProps {\n values: PropertyAggregationValue[];\n isLoading: boolean;\n error: Error | null;\n selectedValue: string | undefined;\n onChange: (value: string | undefined) => void;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n showClearButton?: boolean;\n showCounts?: boolean;\n ariaLabel?: string;\n renderValue?: (value: string) => string;\n}\n\nfunction SingleSelectInputInner({\n values,\n isLoading,\n error,\n selectedValue,\n onChange,\n className,\n style,\n placeholder = \"Select a value...\",\n showClearButton = true,\n showCounts = false,\n ariaLabel = \"Select value\",\n renderValue,\n}: SingleSelectInputProps): React.ReactElement {\n const handleValueChange = useCallback(\n (value: string | null) => {\n onChange(value ?? undefined);\n },\n [onChange],\n );\n\n const items = useMemo(\n () => values.map(({ value }) => value),\n [values],\n );\n\n const countByValue = useMemo(\n () => new Map(values.map(({ value, count }) => [value, count])),\n [values],\n );\n\n const comboboxFilter = useMemo(\n () =>\n renderValue\n ? (itemValue: string, query: string) =>\n renderValue(itemValue).toLowerCase().includes(query.toLowerCase())\n : undefined,\n [renderValue],\n );\n\n const renderItem = useCallback(\n (value: string) => (\n <Combobox.Item key={value} value={value}>\n <Combobox.ItemIndicator />\n <span className={styles.itemLabel}>\n {renderValue ? renderValue(value) : value}\n </span>\n {showCounts && (\n <span className={styles.itemCount}>\n ({(countByValue.get(value) ?? 0).toLocaleString()})\n </span>\n )}\n </Combobox.Item>\n ),\n [countByValue, showCounts, renderValue],\n );\n\n return (\n <div\n className={classnames(styles.singleSelect, className)}\n style={style}\n data-loading={isLoading}\n >\n {isLoading && (\n <div className={sharedStyles.loadingMessage}>\n Loading options...\n </div>\n )}\n\n {error && (\n <div className={sharedStyles.errorMessage}>\n Error loading options: {error.message}\n </div>\n )}\n\n {!isLoading && !error && values.length === 0 && (\n <div className={sharedStyles.emptyMessage}>\n No options available\n </div>\n )}\n\n {(values.length > 0 || isLoading) && (\n <div className={styles.selectContainer}>\n <Combobox.Root<string>\n value={selectedValue ?? null}\n onValueChange={handleValueChange}\n items={items}\n filter={comboboxFilter}\n >\n <Combobox.SearchInput\n placeholder={placeholder}\n aria-label={ariaLabel}\n />\n {showClearButton && selectedValue !== undefined && (\n <Combobox.Clear className={styles.clearButton} />\n )}\n <Combobox.Portal>\n <Combobox.Positioner>\n <Combobox.Popup>\n <Combobox.Empty>No matching options</Combobox.Empty>\n <Combobox.List>{renderItem}</Combobox.List>\n </Combobox.Popup>\n </Combobox.Positioner>\n </Combobox.Portal>\n </Combobox.Root>\n </div>\n )}\n </div>\n );\n}\n\nexport const SingleSelectInput = memo(\n SingleSelectInputInner,\n) as typeof SingleSelectInputInner;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"SingleSelectInput.js","names":["classnames","React","memo","useCallback","useMemo","Combobox","isEmptyValue","NoValueLabel","sharedStyles","styles","SingleSelectInputInner","values","isLoading","error","selectedValue","onChange","className","style","placeholder","showClearButton","showCounts","ariaLabel","renderValue","handleValueChange","value","undefined","items","map","countByValue","Map","count","comboboxFilter","itemValue","query","toLowerCase","includes","renderItem","isEmpty","createElement","Item","key","ItemIndicator","itemLabel","itemCount","get","toLocaleString","singleSelect","loadingMessage","errorMessage","message","length","emptyMessage","selectContainer","Root","onValueChange","filter","SearchInput","Clear","clearButton","Portal","Positioner","Popup","Empty","List","SingleSelectInput"],"sources":["SingleSelectInput.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 classnames from \"classnames\";\nimport React, { memo, useCallback, useMemo } from \"react\";\nimport { Combobox } from \"../../../base-components/combobox/Combobox.js\";\nimport type { PropertyAggregationValue } from \"../../types/AggregationTypes.js\";\nimport { isEmptyValue } from \"../../utils/filterValues.js\";\nimport { NoValueLabel } from \"./NoValueLabel.js\";\nimport sharedStyles from \"./shared.module.css\";\nimport styles from \"./SingleSelectInput.module.css\";\n\ninterface SingleSelectInputProps {\n values: PropertyAggregationValue[];\n isLoading: boolean;\n error: Error | null;\n selectedValue: string | undefined;\n onChange: (value: string | undefined) => void;\n className?: string;\n style?: React.CSSProperties;\n placeholder?: string;\n showClearButton?: boolean;\n showCounts?: boolean;\n ariaLabel?: string;\n renderValue?: (value: string) => string;\n}\n\nfunction SingleSelectInputInner({\n values,\n isLoading,\n error,\n selectedValue,\n onChange,\n className,\n style,\n placeholder = \"Select a value...\",\n showClearButton = true,\n showCounts = false,\n ariaLabel = \"Select value\",\n renderValue,\n}: SingleSelectInputProps): React.ReactElement {\n const handleValueChange = useCallback(\n (value: string | null) => {\n onChange(value ?? undefined);\n },\n [onChange],\n );\n\n const items = useMemo(\n () => values.map(({ value }) => value),\n [values],\n );\n\n const countByValue = useMemo(\n () => new Map(values.map(({ value, count }) => [value, count])),\n [values],\n );\n\n const comboboxFilter = useMemo(\n () =>\n renderValue\n ? (itemValue: string, query: string) =>\n renderValue(itemValue).toLowerCase().includes(query.toLowerCase())\n : undefined,\n [renderValue],\n );\n\n const renderItem = useCallback(\n (value: string) => {\n const isEmpty = isEmptyValue(value);\n return (\n <Combobox.Item key={value} value={value}>\n <Combobox.ItemIndicator />\n <span className={styles.itemLabel}>\n {isEmpty\n ? <NoValueLabel />\n : (renderValue ? renderValue(value) : value)}\n </span>\n {showCounts && (\n <span className={styles.itemCount}>\n ({(countByValue.get(value) ?? 0).toLocaleString()})\n </span>\n )}\n </Combobox.Item>\n );\n },\n [countByValue, showCounts, renderValue],\n );\n\n return (\n <div\n className={classnames(styles.singleSelect, className)}\n style={style}\n data-loading={isLoading}\n >\n {isLoading && (\n <div className={sharedStyles.loadingMessage}>\n Loading options...\n </div>\n )}\n\n {error && (\n <div className={sharedStyles.errorMessage}>\n Error loading options: {error.message}\n </div>\n )}\n\n {!isLoading && !error && values.length === 0 && (\n <div className={sharedStyles.emptyMessage}>\n No options available\n </div>\n )}\n\n {(values.length > 0 || isLoading) && (\n <div className={styles.selectContainer}>\n <Combobox.Root<string>\n value={selectedValue ?? null}\n onValueChange={handleValueChange}\n items={items}\n filter={comboboxFilter}\n >\n <Combobox.SearchInput\n placeholder={placeholder}\n aria-label={ariaLabel}\n />\n {showClearButton && selectedValue !== undefined && (\n <Combobox.Clear className={styles.clearButton} />\n )}\n <Combobox.Portal>\n <Combobox.Positioner>\n <Combobox.Popup>\n <Combobox.Empty>No matching options</Combobox.Empty>\n <Combobox.List>{renderItem}</Combobox.List>\n </Combobox.Popup>\n </Combobox.Positioner>\n </Combobox.Portal>\n </Combobox.Root>\n </div>\n )}\n </div>\n );\n}\n\nexport const SingleSelectInput = memo(\n SingleSelectInputInner,\n) as typeof SingleSelectInputInner;\n"],"mappings":"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","ignoreList":[]}
@@ -18,6 +18,8 @@ import { Button } from "@base-ui/react/button";
18
18
  import classnames from "classnames";
19
19
  import React, { memo, useCallback, useMemo, useState } from "react";
20
20
  import { Combobox } from "../../../base-components/combobox/Combobox.js";
21
+ import { isEmptyValue } from "../../utils/filterValues.js";
22
+ import { NoValueLabel } from "./NoValueLabel.js";
21
23
  import sharedStyles from "./shared.module.css";
22
24
  import styles from "./TextTagsInput.module.css";
23
25
  const TAG_SEPARATOR_PATTERN = /[,\n]/;
@@ -28,13 +30,15 @@ const TagItem = /*#__PURE__*/memo(function ({
28
30
  const handleRemove = useCallback(() => {
29
31
  onRemove(tag);
30
32
  }, [tag, onRemove]);
33
+ const isEmpty = isEmptyValue(tag);
34
+ const displayLabel = isEmpty ? "No value" : tag;
31
35
  return /*#__PURE__*/React.createElement("span", {
32
36
  className: sharedStyles.tag
33
- }, tag, /*#__PURE__*/React.createElement(Button, {
37
+ }, isEmpty ? /*#__PURE__*/React.createElement(NoValueLabel, null) : tag, /*#__PURE__*/React.createElement(Button, {
34
38
  type: "button",
35
39
  className: sharedStyles.tagRemove,
36
40
  onClick: handleRemove,
37
- "aria-label": `Remove ${tag}`
41
+ "aria-label": `Remove ${displayLabel}`
38
42
  }, "\xD7"));
39
43
  });
40
44
  function TextTagsInputInner({