@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.
- package/AGENTS.md +4 -0
- package/CHANGELOG.md +11 -0
- package/build/browser/action-form/ActionForm.js +19 -11
- package/build/browser/action-form/ActionForm.js.map +1 -1
- package/build/browser/action-form/ActionFormApi.js.map +1 -1
- package/build/browser/action-form/BaseForm.js +19 -13
- package/build/browser/action-form/BaseForm.js.map +1 -1
- package/build/browser/action-form/BaseForm.module.css +7 -7
- package/build/browser/action-form/FormField.js +5 -2
- package/build/browser/action-form/FormField.js.map +1 -1
- package/build/browser/action-form/FormField.module.css +6 -1
- package/build/browser/action-form/FormField.module.css.js +1 -0
- package/build/browser/action-form/FormFieldApi.js +7 -1
- package/build/browser/action-form/FormFieldApi.js.map +1 -1
- package/build/browser/action-form/FormHeader.module.css +2 -2
- package/build/browser/action-form/fields/DateCalendar.js +41 -3
- package/build/browser/action-form/fields/DateCalendar.js.map +1 -1
- package/build/browser/action-form/fields/DateCalendar.module.css +59 -10
- package/build/browser/action-form/fields/DateCalendar.module.css.js +5 -1
- package/build/browser/action-form/fields/DateRangeCalendar.js +8 -5
- package/build/browser/action-form/fields/DateRangeCalendar.js.map +1 -1
- package/build/browser/action-form/fields/DateRangeInputField.js +76 -61
- package/build/browser/action-form/fields/DateRangeInputField.js.map +1 -1
- package/build/browser/action-form/fields/DateRangeInputField.module.css +0 -15
- package/build/browser/action-form/fields/DateRangeInputField.module.css.js +1 -2
- package/build/browser/action-form/fields/DatetimePickerField.js +74 -40
- package/build/browser/action-form/fields/DatetimePickerField.js.map +1 -1
- package/build/browser/action-form/fields/DatetimePickerField.module.css +2 -9
- package/build/browser/action-form/fields/FieldBridge.js +1 -1
- package/build/browser/action-form/fields/FieldBridge.js.map +1 -1
- package/build/browser/action-form/fields/FilePickerField.js +47 -39
- package/build/browser/action-form/fields/FilePickerField.js.map +1 -1
- package/build/browser/action-form/fields/FilePickerField.module.css +43 -31
- package/build/browser/action-form/fields/FilePickerField.module.css.js +2 -2
- package/build/browser/action-form/fields/FormFieldRenderer.js +9 -0
- package/build/browser/action-form/fields/FormFieldRenderer.js.map +1 -1
- package/build/browser/action-form/fields/RadioButtonsField.module.css +3 -3
- package/build/browser/action-form/fields/SwitchField.js +34 -0
- package/build/browser/action-form/fields/SwitchField.js.map +1 -0
- package/build/browser/action-form/fields/TimePicker.js +165 -26
- package/build/browser/action-form/fields/TimePicker.js.map +1 -1
- package/build/browser/action-form/fields/TimePicker.module.css +27 -2
- package/build/browser/action-form/fields/TimePicker.module.css.js +3 -1
- package/build/browser/action-form/fields/calendarShared.js +5 -0
- package/build/browser/action-form/fields/calendarShared.js.map +1 -1
- package/build/browser/action-form/fields/useDateEditState.js +3 -4
- package/build/browser/action-form/fields/useDateEditState.js.map +1 -1
- package/build/browser/base-components/action-button/ActionButton.js +2 -1
- package/build/browser/base-components/action-button/ActionButton.js.map +1 -1
- package/build/browser/base-components/action-button/ActionButton.module.css +19 -0
- package/build/browser/base-components/action-button/ActionButton.module.css.js +2 -1
- package/build/browser/base-components/combobox/Combobox.module.css +31 -3
- package/build/browser/base-components/select/Select.module.css +18 -0
- package/build/browser/base-components/switch/Switch.module.css +18 -6
- package/build/browser/filter-list/base/inputs/ListogramInput.js +34 -6
- package/build/browser/filter-list/base/inputs/ListogramInput.js.map +1 -1
- package/build/browser/filter-list/base/inputs/ListogramInput.module.css +11 -5
- package/build/browser/filter-list/base/inputs/ListogramInput.module.css.js +1 -1
- package/build/browser/filter-list/base/inputs/MultiSelectInput.js +20 -12
- package/build/browser/filter-list/base/inputs/MultiSelectInput.js.map +1 -1
- package/build/browser/filter-list/base/inputs/NoValueLabel.js +36 -0
- package/build/browser/filter-list/base/inputs/NoValueLabel.js.map +1 -0
- package/build/browser/filter-list/base/inputs/NoValueLabel.module.css +20 -0
- package/build/browser/filter-list/base/inputs/NoValueLabel.module.css.js +6 -0
- package/build/browser/filter-list/base/inputs/NullValueWrapper.js +4 -3
- package/build/browser/filter-list/base/inputs/NullValueWrapper.js.map +1 -1
- package/build/browser/filter-list/base/inputs/NullValueWrapper.module.css +10 -7
- package/build/browser/filter-list/base/inputs/NullValueWrapper.module.css.js +1 -1
- package/build/browser/filter-list/base/inputs/SingleSelectInput.js +13 -8
- package/build/browser/filter-list/base/inputs/SingleSelectInput.js.map +1 -1
- package/build/browser/filter-list/base/inputs/TextTagsInput.js +6 -2
- package/build/browser/filter-list/base/inputs/TextTagsInput.js.map +1 -1
- package/build/browser/filter-list/hooks/useFilterListState.js +7 -6
- package/build/browser/filter-list/hooks/useFilterListState.js.map +1 -1
- package/build/browser/filter-list/hooks/useStableMapEntries.js +35 -0
- package/build/browser/filter-list/hooks/useStableMapEntries.js.map +1 -0
- package/build/browser/filter-list/utils/filterValues.js +13 -0
- package/build/browser/filter-list/utils/filterValues.js.map +1 -1
- package/build/browser/object-table/DefaultCellRenderer.js +12 -2
- package/build/browser/object-table/DefaultCellRenderer.js.map +1 -1
- package/build/browser/object-table/EditableCell.js +14 -4
- package/build/browser/object-table/EditableCell.js.map +1 -1
- package/build/browser/object-table/EditableCell.module.css +4 -0
- package/build/browser/object-table/EditableCell.module.css.js +1 -0
- package/build/browser/object-table/ObjectTable.js +3 -1
- package/build/browser/object-table/ObjectTable.js.map +1 -1
- package/build/browser/object-table/ObjectTableApi.js.map +1 -1
- package/build/browser/object-table/Table.js +8 -4
- package/build/browser/object-table/Table.js.map +1 -1
- package/build/browser/object-table/TableBody.js +4 -2
- package/build/browser/object-table/TableBody.js.map +1 -1
- package/build/browser/object-table/TableRow.js +12 -4
- package/build/browser/object-table/TableRow.js.map +1 -1
- package/build/browser/object-table/hooks/useColumnDefs.js.map +1 -1
- package/build/browser/object-table/utils/editableUtils.js +39 -0
- package/build/browser/object-table/utils/editableUtils.js.map +1 -0
- package/build/browser/object-table/utils/shouldShowEditableCell.js +1 -1
- package/build/browser/object-table/utils/shouldShowEditableCell.js.map +1 -1
- package/build/browser/object-table/utils/types.js.map +1 -1
- package/build/browser/styles.css +331 -130
- package/build/browser/tokens/component-tokens/button.css +15 -0
- package/build/browser/tokens/component-tokens/combobox.css +9 -0
- package/build/browser/tokens/component-tokens/datetime-picker.css +2 -2
- package/build/browser/tokens/component-tokens/file-picker.css +0 -10
- package/build/browser/tokens/component-tokens/filter-list.css +9 -6
- package/build/browser/tokens/component-tokens/form-section.css +1 -1
- package/build/browser/tokens/component-tokens/form.css +9 -5
- package/build/browser/tokens/component-tokens/table.css +3 -5
- package/build/browser/tokens.css +1 -0
- package/build/browser/util/UserAgent.js +1 -1
- package/build/cjs/{DateCalendar-2W4QHEEI.css → DateCalendar-G7RC2FCG.css} +105 -8
- package/build/cjs/DateCalendar-G7RC2FCG.css.map +1 -0
- package/build/cjs/DateCalendar-RX7HP2XP.cjs +26 -0
- package/build/cjs/{DateCalendar-QGSYBWJB.cjs.map → DateCalendar-RX7HP2XP.cjs.map} +1 -1
- package/build/cjs/{DateRangeCalendar-M63S2LLG.css → DateRangeCalendar-JBVYJDBJ.css} +105 -8
- package/build/cjs/DateRangeCalendar-JBVYJDBJ.css.map +1 -0
- package/build/cjs/DateRangeCalendar-OHT4IUWQ.cjs +54 -0
- package/build/cjs/DateRangeCalendar-OHT4IUWQ.cjs.map +1 -0
- package/build/cjs/{chunk-T7I6O43T.cjs → chunk-6SPXSFPI.cjs} +237 -85
- package/build/cjs/chunk-6SPXSFPI.cjs.map +1 -0
- package/build/cjs/{chunk-SZXVBDSA.cjs → chunk-6UDBHYSO.cjs} +3 -3
- package/build/cjs/{chunk-SZXVBDSA.cjs.map → chunk-6UDBHYSO.cjs.map} +1 -1
- package/build/cjs/{chunk-YBDS5WQP.cjs → chunk-7H6WXQ35.cjs} +4 -4
- package/build/cjs/{chunk-YBDS5WQP.cjs.map → chunk-7H6WXQ35.cjs.map} +1 -1
- package/build/cjs/{chunk-VVJFMOZI.cjs → chunk-I3OSD6CF.cjs} +19 -45
- package/build/cjs/chunk-I3OSD6CF.cjs.map +1 -0
- package/build/cjs/chunk-MD4KDE44.cjs +41 -0
- package/build/cjs/chunk-MD4KDE44.cjs.map +1 -0
- package/build/cjs/{chunk-YPXTSEE7.cjs → chunk-MLFMSZJQ.cjs} +85 -38
- package/build/cjs/chunk-MLFMSZJQ.cjs.map +1 -0
- package/build/cjs/chunk-MQYOHGPY.cjs +52 -0
- package/build/cjs/chunk-MQYOHGPY.cjs.map +1 -0
- package/build/cjs/{chunk-BJDCC446.cjs → chunk-PTTCWNZZ.cjs} +417 -364
- package/build/cjs/chunk-PTTCWNZZ.cjs.map +1 -0
- package/build/cjs/{chunk-B2GRQRWU.cjs → chunk-TOJSJN3L.cjs} +44 -8
- package/build/cjs/chunk-TOJSJN3L.cjs.map +1 -0
- package/build/cjs/{chunk-JLESWL47.cjs → chunk-V7XWTJV7.cjs} +4 -2
- package/build/cjs/chunk-V7XWTJV7.cjs.map +1 -0
- package/build/cjs/{chunk-L5LPFCXT.cjs → chunk-W2IASYE4.cjs} +163 -125
- package/build/cjs/chunk-W2IASYE4.cjs.map +1 -0
- package/build/cjs/chunk-X337DNCW.cjs +45 -0
- package/build/cjs/chunk-X337DNCW.cjs.map +1 -0
- package/build/cjs/{chunk-SB2VTP67.cjs → chunk-Z7VHLTKD.cjs} +2 -64
- package/build/cjs/chunk-Z7VHLTKD.cjs.map +1 -0
- package/build/cjs/public/experimental/action-form.cjs +11 -9
- package/build/cjs/public/experimental/action-form.css +223 -68
- package/build/cjs/public/experimental/action-form.css.map +1 -1
- package/build/cjs/public/experimental/action-form.d.cts +83 -74
- package/build/cjs/public/experimental/filter-list.cjs +9 -8
- package/build/cjs/public/experimental/filter-list.css +38 -19
- package/build/cjs/public/experimental/filter-list.css.map +1 -1
- package/build/cjs/public/experimental/object-table.cjs +14 -12
- package/build/cjs/public/experimental/object-table.css +152 -59
- package/build/cjs/public/experimental/object-table.css.map +1 -1
- package/build/cjs/public/experimental/object-table.d.cts +39 -20
- package/build/cjs/public/experimental/pdf-viewer.cjs +24 -24
- package/build/cjs/public/experimental.cjs +46 -44
- package/build/cjs/public/experimental.css +242 -139
- package/build/cjs/public/experimental.css.map +1 -1
- package/build/cjs/public/primitives.cjs +8 -7
- package/build/cjs/public/primitives.css +15 -0
- package/build/cjs/public/primitives.css.map +1 -1
- package/build/cjs/public/primitives.d.cts +1 -0
- package/build/esm/action-form/ActionForm.js +19 -11
- package/build/esm/action-form/ActionForm.js.map +1 -1
- package/build/esm/action-form/ActionFormApi.js.map +1 -1
- package/build/esm/action-form/BaseForm.js +19 -13
- package/build/esm/action-form/BaseForm.js.map +1 -1
- package/build/esm/action-form/BaseForm.module.css +7 -7
- package/build/esm/action-form/FormField.js +5 -2
- package/build/esm/action-form/FormField.js.map +1 -1
- package/build/esm/action-form/FormField.module.css +6 -1
- package/build/esm/action-form/FormFieldApi.js +7 -1
- package/build/esm/action-form/FormFieldApi.js.map +1 -1
- package/build/esm/action-form/FormHeader.module.css +2 -2
- package/build/esm/action-form/fields/DateCalendar.js +41 -3
- package/build/esm/action-form/fields/DateCalendar.js.map +1 -1
- package/build/esm/action-form/fields/DateCalendar.module.css +59 -10
- package/build/esm/action-form/fields/DateRangeCalendar.js +8 -5
- package/build/esm/action-form/fields/DateRangeCalendar.js.map +1 -1
- package/build/esm/action-form/fields/DateRangeInputField.js +76 -61
- package/build/esm/action-form/fields/DateRangeInputField.js.map +1 -1
- package/build/esm/action-form/fields/DateRangeInputField.module.css +0 -15
- package/build/esm/action-form/fields/DatetimePickerField.js +74 -40
- package/build/esm/action-form/fields/DatetimePickerField.js.map +1 -1
- package/build/esm/action-form/fields/DatetimePickerField.module.css +2 -9
- package/build/esm/action-form/fields/FieldBridge.js +1 -1
- package/build/esm/action-form/fields/FieldBridge.js.map +1 -1
- package/build/esm/action-form/fields/FilePickerField.js +47 -39
- package/build/esm/action-form/fields/FilePickerField.js.map +1 -1
- package/build/esm/action-form/fields/FilePickerField.module.css +43 -31
- package/build/esm/action-form/fields/FormFieldRenderer.js +9 -0
- package/build/esm/action-form/fields/FormFieldRenderer.js.map +1 -1
- package/build/esm/action-form/fields/RadioButtonsField.module.css +3 -3
- package/build/esm/action-form/fields/SwitchField.js +34 -0
- package/build/esm/action-form/fields/SwitchField.js.map +1 -0
- package/build/esm/action-form/fields/TimePicker.js +165 -26
- package/build/esm/action-form/fields/TimePicker.js.map +1 -1
- package/build/esm/action-form/fields/TimePicker.module.css +27 -2
- package/build/esm/action-form/fields/calendarShared.js +5 -0
- package/build/esm/action-form/fields/calendarShared.js.map +1 -1
- package/build/esm/action-form/fields/useDateEditState.js +3 -4
- package/build/esm/action-form/fields/useDateEditState.js.map +1 -1
- package/build/esm/base-components/action-button/ActionButton.js +2 -1
- package/build/esm/base-components/action-button/ActionButton.js.map +1 -1
- package/build/esm/base-components/action-button/ActionButton.module.css +19 -0
- package/build/esm/base-components/combobox/Combobox.module.css +31 -3
- package/build/esm/base-components/select/Select.module.css +18 -0
- package/build/esm/base-components/switch/Switch.module.css +18 -6
- package/build/esm/filter-list/base/inputs/ListogramInput.js +34 -6
- package/build/esm/filter-list/base/inputs/ListogramInput.js.map +1 -1
- package/build/esm/filter-list/base/inputs/ListogramInput.module.css +11 -5
- package/build/esm/filter-list/base/inputs/MultiSelectInput.js +20 -12
- package/build/esm/filter-list/base/inputs/MultiSelectInput.js.map +1 -1
- package/build/esm/filter-list/base/inputs/NoValueLabel.js +36 -0
- package/build/esm/filter-list/base/inputs/NoValueLabel.js.map +1 -0
- package/build/esm/filter-list/base/inputs/NoValueLabel.module.css +20 -0
- package/build/esm/filter-list/base/inputs/NullValueWrapper.js +4 -3
- package/build/esm/filter-list/base/inputs/NullValueWrapper.js.map +1 -1
- package/build/esm/filter-list/base/inputs/NullValueWrapper.module.css +10 -7
- package/build/esm/filter-list/base/inputs/SingleSelectInput.js +13 -8
- package/build/esm/filter-list/base/inputs/SingleSelectInput.js.map +1 -1
- package/build/esm/filter-list/base/inputs/TextTagsInput.js +6 -2
- package/build/esm/filter-list/base/inputs/TextTagsInput.js.map +1 -1
- package/build/esm/filter-list/hooks/useFilterListState.js +7 -6
- package/build/esm/filter-list/hooks/useFilterListState.js.map +1 -1
- package/build/esm/filter-list/hooks/useStableMapEntries.js +35 -0
- package/build/esm/filter-list/hooks/useStableMapEntries.js.map +1 -0
- package/build/esm/filter-list/utils/filterValues.js +13 -0
- package/build/esm/filter-list/utils/filterValues.js.map +1 -1
- package/build/esm/object-table/DefaultCellRenderer.js +12 -2
- package/build/esm/object-table/DefaultCellRenderer.js.map +1 -1
- package/build/esm/object-table/EditableCell.js +14 -4
- package/build/esm/object-table/EditableCell.js.map +1 -1
- package/build/esm/object-table/EditableCell.module.css +4 -0
- package/build/esm/object-table/ObjectTable.js +3 -1
- package/build/esm/object-table/ObjectTable.js.map +1 -1
- package/build/esm/object-table/ObjectTableApi.js.map +1 -1
- package/build/esm/object-table/Table.js +8 -4
- package/build/esm/object-table/Table.js.map +1 -1
- package/build/esm/object-table/TableBody.js +4 -2
- package/build/esm/object-table/TableBody.js.map +1 -1
- package/build/esm/object-table/TableRow.js +12 -4
- package/build/esm/object-table/TableRow.js.map +1 -1
- package/build/esm/object-table/hooks/useColumnDefs.js.map +1 -1
- package/build/esm/object-table/utils/editableUtils.js +39 -0
- package/build/esm/object-table/utils/editableUtils.js.map +1 -0
- package/build/esm/object-table/utils/shouldShowEditableCell.js +1 -1
- package/build/esm/object-table/utils/shouldShowEditableCell.js.map +1 -1
- package/build/esm/object-table/utils/types.js.map +1 -1
- package/build/esm/tokens/component-tokens/button.css +15 -0
- package/build/esm/tokens/component-tokens/combobox.css +9 -0
- package/build/esm/tokens/component-tokens/datetime-picker.css +2 -2
- package/build/esm/tokens/component-tokens/file-picker.css +0 -10
- package/build/esm/tokens/component-tokens/filter-list.css +9 -6
- package/build/esm/tokens/component-tokens/form-section.css +1 -1
- package/build/esm/tokens/component-tokens/form.css +9 -5
- package/build/esm/tokens/component-tokens/table.css +3 -5
- package/build/esm/tokens.css +1 -0
- package/build/esm/util/UserAgent.js +1 -1
- package/build/types/action-form/ActionFormApi.d.ts +8 -8
- package/build/types/action-form/ActionFormApi.d.ts.map +1 -1
- package/build/types/action-form/BaseForm.d.ts.map +1 -1
- package/build/types/action-form/FormFieldApi.d.ts +29 -22
- package/build/types/action-form/FormFieldApi.d.ts.map +1 -1
- package/build/types/action-form/fields/DateCalendar.d.ts +6 -1
- package/build/types/action-form/fields/DateCalendar.d.ts.map +1 -1
- package/build/types/action-form/fields/DateRangeCalendar.d.ts.map +1 -1
- package/build/types/action-form/fields/DateRangeInputField.d.ts.map +1 -1
- package/build/types/action-form/fields/DatetimePickerField.d.ts.map +1 -1
- package/build/types/action-form/fields/FieldBridge.d.ts.map +1 -1
- package/build/types/action-form/fields/FilePickerField.d.ts.map +1 -1
- package/build/types/action-form/fields/FormFieldRenderer.d.ts.map +1 -1
- package/build/types/action-form/fields/SwitchField.d.ts +7 -0
- package/build/types/action-form/fields/SwitchField.d.ts.map +1 -0
- package/build/types/action-form/fields/TimePicker.d.ts +4 -5
- package/build/types/action-form/fields/TimePicker.d.ts.map +1 -1
- package/build/types/action-form/fields/useDateEditState.d.ts +2 -2
- package/build/types/base-components/action-button/ActionButton.d.ts +1 -0
- package/build/types/base-components/action-button/ActionButton.d.ts.map +1 -1
- package/build/types/filter-list/base/inputs/ListogramInput.d.ts.map +1 -1
- package/build/types/filter-list/base/inputs/MultiSelectInput.d.ts.map +1 -1
- package/build/types/filter-list/base/inputs/NoValueLabel.d.ts +15 -0
- package/build/types/filter-list/base/inputs/NoValueLabel.d.ts.map +1 -0
- package/build/types/filter-list/base/inputs/NullValueWrapper.d.ts.map +1 -1
- package/build/types/filter-list/base/inputs/SingleSelectInput.d.ts.map +1 -1
- package/build/types/filter-list/base/inputs/TextTagsInput.d.ts.map +1 -1
- package/build/types/filter-list/hooks/useFilterListState.d.ts.map +1 -1
- package/build/types/filter-list/hooks/useStableMapEntries.d.ts +9 -0
- package/build/types/filter-list/hooks/useStableMapEntries.d.ts.map +1 -0
- package/build/types/filter-list/utils/filterValues.d.ts +7 -0
- package/build/types/filter-list/utils/filterValues.d.ts.map +1 -1
- package/build/types/object-table/DefaultCellRenderer.d.ts.map +1 -1
- package/build/types/object-table/EditableCell.d.ts +1 -1
- package/build/types/object-table/EditableCell.d.ts.map +1 -1
- package/build/types/object-table/ObjectTableApi.d.ts +26 -7
- package/build/types/object-table/ObjectTableApi.d.ts.map +1 -1
- package/build/types/object-table/Table.d.ts +9 -2
- package/build/types/object-table/Table.d.ts.map +1 -1
- package/build/types/object-table/TableBody.d.ts +2 -1
- package/build/types/object-table/TableBody.d.ts.map +1 -1
- package/build/types/object-table/TableRow.d.ts +2 -1
- package/build/types/object-table/TableRow.d.ts.map +1 -1
- package/build/types/object-table/utils/editableUtils.d.ts +16 -0
- package/build/types/object-table/utils/editableUtils.d.ts.map +1 -0
- package/build/types/object-table/utils/shouldShowEditableCell.d.ts +2 -1
- package/build/types/object-table/utils/shouldShowEditableCell.d.ts.map +1 -1
- package/build/types/object-table/utils/types.d.ts +4 -11
- package/build/types/object-table/utils/types.d.ts.map +1 -1
- package/docs/ActionForm.md +176 -0
- package/docs/CSSVariables.md +31 -30
- package/docs/ObjectTable.md +141 -16
- package/package.json +6 -5
- package/build/cjs/DateCalendar-2W4QHEEI.css.map +0 -1
- package/build/cjs/DateCalendar-QGSYBWJB.cjs +0 -24
- package/build/cjs/DateRangeCalendar-JHO2BF3Z.cjs +0 -48
- package/build/cjs/DateRangeCalendar-JHO2BF3Z.cjs.map +0 -1
- package/build/cjs/DateRangeCalendar-M63S2LLG.css.map +0 -1
- package/build/cjs/chunk-B2GRQRWU.cjs.map +0 -1
- package/build/cjs/chunk-BJDCC446.cjs.map +0 -1
- package/build/cjs/chunk-JLESWL47.cjs.map +0 -1
- package/build/cjs/chunk-L5LPFCXT.cjs.map +0 -1
- package/build/cjs/chunk-SB2VTP67.cjs.map +0 -1
- package/build/cjs/chunk-T7I6O43T.cjs.map +0 -1
- package/build/cjs/chunk-UCTQICPR.cjs +0 -10
- package/build/cjs/chunk-UCTQICPR.cjs.map +0 -1
- package/build/cjs/chunk-VVJFMOZI.cjs.map +0 -1
- 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
|
-
|
|
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:
|
|
136
|
+
className: styles.label,
|
|
111
137
|
"data-excluding": isExcluding && selectedSet.has(value) || undefined
|
|
112
|
-
},
|
|
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 =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
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":"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,EAAEC,OAAO,QAAQ,OAAO;AACzD,SAASC,QAAQ,QAAQ,+CAA+C;AAExE,SAASC,YAAY,QAAQ,6BAA6B;AAC1D,OAAOC,MAAM,MAAM,+BAA+B;AAClD,SAASC,YAAY,QAAQ,mBAAmB;AAChD,OAAOC,YAAY,MAAM,qBAAqB;AAgB9C,SAASC,qBAAqBA,CAAC;EAC7BC,MAAM;EACNC,SAAS;EACTC,KAAK;EACLC,cAAc;EACdC,QAAQ;EACRC,SAAS;EACTC,KAAK;EACLC,WAAW,GAAG,kBAAkB;EAChCC,UAAU,GAAG,IAAI;EACjBC,SAAS,GAAG,eAAe;EAC3BC;AACqB,CAAC,EAAsB;EAC5C,MAAMC,iBAAiB,GAAGnB,WAAW,CAClCoB,SAA0B,IAAK;IAC9BR,QAAQ,CAACQ,SAAS,IAAI,EAAE,CAAC;EAC3B,CAAC,EACD,CAACR,QAAQ,CACX,CAAC;EAED,MAAMS,KAAK,GAAGpB,OAAO,CACnB,MAAMO,MAAM,CAACc,GAAG,CAAC,CAAC;IAAEC;EAAM,CAAC,KAAKA,KAAK,CAAC,EACtC,CAACf,MAAM,CACT,CAAC;EAED,MAAMgB,YAAY,GAAGvB,OAAO,CAC1B,MAAM,IAAIwB,GAAG,CAACjB,MAAM,CAACc,GAAG,CAAC,CAAC;IAAEC,KAAK;IAAEG;EAAM,CAAC,KAAK,CAACH,KAAK,EAAEG,KAAK,CAAC,CAAC,CAAC,EAC/D,CAAClB,MAAM,CACT,CAAC;EAED,MAAMmB,cAAc,GAAG1B,OAAO,CAC5B,MACEiB,WAAW,GACP,CAACU,SAAiB,EAAEC,KAAa,KACjCX,WAAW,CAACU,SAAS,CAAC,CAACE,WAAW,CAAC,CAAC,CAACC,QAAQ,CAACF,KAAK,CAACC,WAAW,CAAC,CAAC,CAAC,GAClEE,SAAS,EACf,CAACd,WAAW,CACd,CAAC;EAED,MAAMe,UAAU,GAAGjC,WAAW,CAC3BuB,KAAa,IAAK;IACjB,MAAMW,OAAO,GAAG/B,YAAY,CAACoB,KAAK,CAAC;IACnC,oBACEzB,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAACkC,IAAI;MAACC,GAAG,EAAEd,KAAM;MAACA,KAAK,EAAEA;IAAM,gBACtCzB,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAACoC,aAAa,MAAE,CAAC,eAC1BxC,KAAA,CAAAqC,aAAA;MAAMtB,SAAS,EAAET,MAAM,CAACmC;IAAU,GAC/BL,OAAO,gBACJpC,KAAA,CAAAqC,aAAA,CAAC9B,YAAY,MAAE,CAAC,GACfa,WAAW,GAAGA,WAAW,CAACK,KAAK,CAAC,GAAGA,KACpC,CAAC,EACNP,UAAU,iBACTlB,KAAA,CAAAqC,aAAA;MAAMtB,SAAS,EAAET,MAAM,CAACoC;IAAU,GAAC,GAChC,EAAC,CAAChB,YAAY,CAACiB,GAAG,CAAClB,KAAK,CAAC,IAAI,CAAC,EAAEmB,cAAc,CAAC,CAAC,EAAC,GAC9C,CAEK,CAAC;EAEpB,CAAC,EACD,CAAClB,YAAY,EAAER,UAAU,EAAEE,WAAW,CACxC,CAAC;EAED,MAAMyB,WAAW,GAAG3C,WAAW,CAC5B4C,aAAuB,iBACtB9C,KAAA,CAAAqC,aAAA,CAAArC,KAAA,CAAA+C,QAAA,QACGD,aAAa,CAACtB,GAAG,CAAEC,KAAK,IAAK;IAC5B,MAAMW,OAAO,GAAG/B,YAAY,CAACoB,KAAK,CAAC;IACnC,oBACEzB,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC4C,IAAI;MACZT,GAAG,EAAEd,KAAM;MACX,cAAYW,OAAO,GAAG,UAAU,GAAGX;IAAM,GAExCW,OAAO,gBACJpC,KAAA,CAAAqC,aAAA,CAAC9B,YAAY,MAAE,CAAC,GACfa,WAAW,GAAGA,WAAW,CAACK,KAAK,CAAC,GAAGA,KAAM,eAC9CzB,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC6C,UAAU,MAAE,CACT,CAAC;EAEpB,CAAC,CAAC,eACFjD,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC8C,KAAK;IACbjC,WAAW,EAAE6B,aAAa,CAACK,MAAM,GAAG,CAAC,GAAG,EAAE,GAAGlC,WAAY;IACzD,cAAYE;EAAU,CACvB,CACD,CACH,EACD,CAACF,WAAW,EAAEE,SAAS,EAAEC,WAAW,CACtC,CAAC;EAED,oBACEpB,KAAA,CAAAqC,aAAA;IACEtB,SAAS,EAAEhB,UAAU,CAACO,MAAM,CAAC8C,WAAW,EAAErC,SAAS,CAAE;IACrDC,KAAK,EAAEA,KAAM;IACb,gBAAcL;EAAU,GAEvBC,KAAK,iBACJZ,KAAA,CAAAqC,aAAA;IAAKtB,SAAS,EAAEP,YAAY,CAAC6C;EAAa,GAAC,yBAClB,EAACzC,KAAK,CAAC0C,OAC3B,CACN,EAEA,CAAC1C,KAAK,IAAIF,MAAM,CAACyC,MAAM,KAAK,CAAC,iBAC5BnD,KAAA,CAAAqC,aAAA;IAAKtB,SAAS,EAAEP,YAAY,CAAC+C;EAAa,GACvC5C,SAAS,GAAG,oBAAoB,GAAG,sBACjC,CACN,EAEA,CAACD,MAAM,CAACyC,MAAM,GAAG,CAAC,IAAIxC,SAAS,kBAC9BX,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAACoD,IAAI;IACZC,QAAQ,EAAE,IAAK;IACfhC,KAAK,EAAEZ,cAAe;IACtB6C,aAAa,EAAErC,iBAAkB;IACjCE,KAAK,EAAEA,KAAM;IACboC,MAAM,EAAE9B;EAAe,GAEtBlB,SAAS,iBACRX,KAAA,CAAAqC,aAAA;IAAKtB,SAAS,EAAEP,YAAY,CAACoD;EAAe,GAAC,aAExC,CACN,eAED5D,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAACyD,KAAK,qBACb7D,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC0D,KAAK,QAAEjB,WAA4B,CAC/B,CAAC,eAEjB7C,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC2D,MAAM,qBACd/D,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC4D,UAAU,qBAClBhE,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC6D,KAAK,qBACbjE,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC8D,KAAK,QAAC,qBAAmC,CAAC,eACpDlE,KAAA,CAAAqC,aAAA,CAACjC,QAAQ,CAAC+D,IAAI,QAAEhC,UAA0B,CAC5B,CACG,CACN,CACJ,CAEd,CAAC;AAEV;AAEA,OAAO,MAAMiC,gBAAgB,gBAAGnE,IAAI,CAClCQ,qBACF,CAAiC","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(
|
|
49
|
-
className: styles.
|
|
50
|
-
}
|
|
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","
|
|
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 =>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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 ${
|
|
41
|
+
"aria-label": `Remove ${displayLabel}`
|
|
38
42
|
}, "\xD7"));
|
|
39
43
|
});
|
|
40
44
|
function TextTagsInputInner({
|