@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
package/AGENTS.md
CHANGED
|
@@ -40,6 +40,7 @@ Components are imported from their individual entry points under `@osdk/react-co
|
|
|
40
40
|
|
|
41
41
|
- `@osdk/react-components/experimental/object-table` — ObjectTable, BaseTable, ColumnConfigDialog
|
|
42
42
|
- `@osdk/react-components/experimental/filter-list` — FilterList, BaseFilterList
|
|
43
|
+
- `@osdk/react-components/experimental/action-form` — ActionForm, BaseForm, and form field definitions
|
|
43
44
|
- `@osdk/react-components/experimental/pdf-viewer` — PdfViewer, BasePdfViewer, and building blocks/hooks
|
|
44
45
|
- `@osdk/react-components/experimental/tiff-renderer` — TiffRenderer
|
|
45
46
|
- `@osdk/react-components/experimental/markdown-renderer` — MarkdownRenderer
|
|
@@ -50,6 +51,8 @@ Components are imported from their individual entry points under `@osdk/react-co
|
|
|
50
51
|
| **BaseTable** | OSDK-agnostic base table — use when building custom data fetching on top of the table UI. |
|
|
51
52
|
| **FilterList** | Aggregation-based filter UI for object sets with draggable reordering. |
|
|
52
53
|
| **BaseFilterList** | OSDK-agnostic base filter list — use for custom filter implementations. |
|
|
54
|
+
| **ActionForm** | Form for applying OSDK actions with generated or custom field definitions. |
|
|
55
|
+
| **BaseForm** | OSDK-agnostic base action form — use when supplying explicit field content and submit handling. |
|
|
53
56
|
| **ColumnConfigDialog** | Dialog for managing column visibility and drag-and-drop reordering. |
|
|
54
57
|
| **PdfViewer** | PDF viewer for OSDK Media objects with toolbar, search, annotations, sidebar (thumbnails/outline), highlight mode, and form fields. |
|
|
55
58
|
| **BasePdfViewer** | OSDK-agnostic base PDF viewer — accepts a URL or ArrayBuffer directly. Use when building custom data fetching on top of the viewer UI. |
|
|
@@ -62,6 +65,7 @@ Before using any component, read the relevant doc from this package:
|
|
|
62
65
|
|
|
63
66
|
- **Setup & installation**: Read [README.md](./README.md) for provider, CSS layers, and peer dependencies
|
|
64
67
|
- **ObjectTable**: Read [docs/ObjectTable.md](./docs/ObjectTable.md) for props, column definitions, examples, theming, and troubleshooting
|
|
68
|
+
- **ActionForm**: Read [docs/ActionForm.md](./docs/ActionForm.md) for generated fields, title behavior, custom field definitions, switch fields, and date/time behavior
|
|
65
69
|
- **PdfViewer**: Read [docs/PdfViewer.md](./docs/PdfViewer.md) for props, annotations, building blocks, hooks, examples, and theming
|
|
66
70
|
- **TiffRenderer**: Read [docs/TiffViewer.md](./docs/TiffViewer.md) for props and usage
|
|
67
71
|
- **MarkdownRenderer**: Read [docs/MarkdownRenderer.md](./docs/MarkdownRenderer.md) for props, examples, and theming
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @osdk/react-components
|
|
2
2
|
|
|
3
|
+
## 0.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 53e5f4f: Cap the Combobox popup at 320px (configurable via `--osdk-combobox-popup-max-height`) with overflow scrolling. Long option lists no longer push other UI off-screen — they scroll inside the popup. A short browser window still gets a smaller cap because the rule resolves to `min(320px, var(--available-height))`.
|
|
8
|
+
- aca2466: Standardize "No value" rendering in FilterList — introduce a shared `NoValueLabel` component (italic, muted) used by listogram buckets, single-select and multi-select dropdown options, multi-select chips, text-tag chips, and the `NullValueWrapper` include-null row. Adds an `isEmptyValue` helper. The `NullValueWrapper` include-null row's default visual flips from upright/default-color to italic/muted so it matches the dropdown and listogram surfaces. Legacy `--osdk-filter-listogram-empty-label-color`, `--osdk-filter-listogram-empty-label-font-style`, `--osdk-filter-null-label-color`, `--osdk-filter-null-label-font-family`, `--osdk-filter-null-label-font-size`, and `--osdk-filter-null-label-line-height` tokens are honored as opt-in overrides on the listogram and null-wrapper containers; consumers who explicitly set them continue to override the new italic-muted defaults.
|
|
9
|
+
- fe39be0: Stabilize per-filter where-clause references inside `useFilterListState` via deep-equality caching, so `FilterInput.memo` holds when the cross-filter context for a given filter is unchanged across selections. Eliminates redundant aggregation requests on every value selection. Internal-only — no public API changes.
|
|
10
|
+
- 76ab0a3: ObjectTable: Fix bug when cell is marked edited on clicking into and out of an empty cell
|
|
11
|
+
- 72e928b: ObjectTable: support per-row edit configuration via `editable: (rowData) => boolean`, add `getRowAttributes` prop for conditional row styling via data attributes, replace `editFieldConfig.fieldComponentProps` with `editFieldConfig.getFieldComponentProps(rowData)` so editor configuration can vary per row, and add a `showEditFooter` prop to opt out of the built-in edit footer.
|
|
12
|
+
- 9be8339: Polish ActionForm date/time controls, boolean switch fields, form submission, popup positioning, component tokens, and FauxFoundry action typings.
|
|
13
|
+
|
|
3
14
|
## 0.12.0
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
|
@@ -26,6 +26,7 @@ const EMPTY_FORM_CONTENT = [];
|
|
|
26
26
|
export const ActionForm = typedReactMemo(function ({
|
|
27
27
|
actionDefinition,
|
|
28
28
|
formTitle,
|
|
29
|
+
showFormTitle = false,
|
|
29
30
|
formFieldDefinitions,
|
|
30
31
|
formState: controlledFormState,
|
|
31
32
|
onFormStateChange,
|
|
@@ -33,8 +34,7 @@ export const ActionForm = typedReactMemo(function ({
|
|
|
33
34
|
onSubmit,
|
|
34
35
|
onValidationResponse: _onValidationResponse,
|
|
35
36
|
onSuccess,
|
|
36
|
-
onError
|
|
37
|
-
portalContainer
|
|
37
|
+
onError
|
|
38
38
|
}) {
|
|
39
39
|
const {
|
|
40
40
|
applyAction: osdkApplyAction,
|
|
@@ -61,12 +61,21 @@ export const ActionForm = typedReactMemo(function ({
|
|
|
61
61
|
// RendererFieldDefinition is a discriminated union keyed by fieldComponent.
|
|
62
62
|
// TypeScript can't verify that the spread preserves the fieldComponent ↔
|
|
63
63
|
// fieldComponentProps pairing, but FormFieldDefinition guarantees it.
|
|
64
|
-
return formFieldDefinitions.map(def =>
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
return formFieldDefinitions.map(def => {
|
|
65
|
+
const {
|
|
66
|
+
defaultValue,
|
|
67
|
+
...fieldDefinition
|
|
68
|
+
} = def;
|
|
69
|
+
return {
|
|
70
|
+
...fieldDefinition,
|
|
71
|
+
fieldKey: String(def.fieldKey),
|
|
72
|
+
fieldType: parameters?.[String(def.fieldKey)]?.type,
|
|
73
|
+
fieldComponentProps: defaultValue === undefined ? def.fieldComponentProps : {
|
|
74
|
+
...def.fieldComponentProps,
|
|
75
|
+
defaultValue
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
});
|
|
70
79
|
}, [formFieldDefinitions, parameters]);
|
|
71
80
|
const rendererFieldDefinitions = useMemo(() => customFieldDefinitions ?? (metadata != null ? getDefaultFieldDefinitions(metadata) : EMPTY_FIELD_DEFINITIONS), [customFieldDefinitions, metadata]);
|
|
72
81
|
const formContent = useMemo(() => rendererFieldDefinitions.length === 0 ? EMPTY_FORM_CONTENT : rendererFieldDefinitions.map(def => ({
|
|
@@ -102,7 +111,7 @@ export const ActionForm = typedReactMemo(function ({
|
|
|
102
111
|
[fieldKey]: value
|
|
103
112
|
}));
|
|
104
113
|
}, [onFormStateChange]);
|
|
105
|
-
const resolvedTitle = formTitle ?? metadata?.displayName ?? actionDefinition.apiName;
|
|
114
|
+
const resolvedTitle = showFormTitle ? formTitle ?? metadata?.displayName ?? actionDefinition.apiName : undefined;
|
|
106
115
|
const commonProps = {
|
|
107
116
|
formTitle: resolvedTitle,
|
|
108
117
|
formContent,
|
|
@@ -110,8 +119,7 @@ export const ActionForm = typedReactMemo(function ({
|
|
|
110
119
|
isSubmitDisabled,
|
|
111
120
|
isPending,
|
|
112
121
|
isLoading: metadataLoading,
|
|
113
|
-
onFieldValueChange: handleFieldValueChange
|
|
114
|
-
portalContainer
|
|
122
|
+
onFieldValueChange: handleFieldValueChange
|
|
115
123
|
};
|
|
116
124
|
if (!(controlledFormState != null)) {
|
|
117
125
|
return /*#__PURE__*/React.createElement(BaseForm, commonProps);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionForm.js","names":["useOsdkAction","useOsdkMetadata","React","useCallback","useEffect","useMemo","typedReactMemo","BaseForm","coerceFieldValue","getDefaultFieldDefinitions","EMPTY_FIELD_DEFINITIONS","EMPTY_FORM_CONTENT","ActionForm","actionDefinition","formTitle","formFieldDefinitions","formState","controlledFormState","onFormStateChange","isSubmitDisabled","onSubmit","onValidationResponse","_onValidationResponse","onSuccess","onError","portalContainer","applyAction","osdkApplyAction","isPending","metadata","loading","metadataLoading","error","metadataError","type","parameters","customFieldDefinitions","map","def","fieldKey","String","fieldType","defaultValue","rendererFieldDefinitions","formContent","length","definition","coerceFormState","rawState","coerced","key","value","Object","entries","handleSubmit","rawFormState","result","e","handleFieldValueChange","prev","resolvedTitle","displayName","apiName","commonProps","isLoading","onFieldValueChange","createElement","_extends"],"sources":["ActionForm.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 type { ActionDefinition } from \"@osdk/api\";\nimport { useOsdkAction, useOsdkMetadata } from \"@osdk/react\";\nimport React, { useCallback, useEffect, useMemo } from \"react\";\nimport { typedReactMemo } from \"../shared/typedMemo.js\";\nimport type {\n ActionFormProps,\n FormContentItem,\n FormState,\n} from \"./ActionFormApi.js\";\nimport { BaseForm } from \"./BaseForm.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { coerceFieldValue } from \"./utils/coerceFieldValue.js\";\nimport { getDefaultFieldDefinitions } from \"./utils/getDefaultFieldDefinitions.js\";\n\nconst EMPTY_FIELD_DEFINITIONS: ReadonlyArray<RendererFieldDefinition> = [];\nconst EMPTY_FORM_CONTENT: ReadonlyArray<FormContentItem> = [];\n\nexport const ActionForm: <Q extends ActionDefinition<unknown>>(\n props: ActionFormProps<Q>,\n) => React.ReactElement = typedReactMemo(function ActionFormFn<\n Q extends ActionDefinition<unknown>,\n>({\n actionDefinition,\n formTitle,\n formFieldDefinitions,\n formState: controlledFormState,\n onFormStateChange,\n isSubmitDisabled,\n onSubmit,\n onValidationResponse: _onValidationResponse,\n onSuccess,\n onError,\n portalContainer,\n}: ActionFormProps<Q>): React.ReactElement {\n const { applyAction: osdkApplyAction, isPending } = useOsdkAction(\n actionDefinition,\n );\n const {\n metadata,\n loading: metadataLoading,\n error: metadataError,\n } = useOsdkMetadata(actionDefinition);\n\n useEffect(\n function saveMetadataError() {\n if (metadataError != null) {\n onError?.({ type: \"unknown\", error: metadataError });\n }\n },\n [metadataError, onError],\n );\n\n const parameters = metadata?.parameters;\n\n const customFieldDefinitions: ReadonlyArray<RendererFieldDefinition> | null =\n useMemo(() => {\n if (formFieldDefinitions == null) {\n return null;\n }\n // RendererFieldDefinition is a discriminated union keyed by fieldComponent.\n // TypeScript can't verify that the spread preserves the fieldComponent ↔\n // fieldComponentProps pairing, but FormFieldDefinition guarantees it.\n return formFieldDefinitions.map(\n (def) =>\n ({\n ...def,\n fieldKey: String(def.fieldKey),\n fieldType: parameters?.[String(def.fieldKey)]?.type,\n defaultValue: def.defaultValue,\n }) as RendererFieldDefinition,\n );\n }, [formFieldDefinitions, parameters]);\n\n const rendererFieldDefinitions = useMemo(\n () =>\n customFieldDefinitions\n ?? (metadata != null\n ? getDefaultFieldDefinitions(metadata)\n : EMPTY_FIELD_DEFINITIONS),\n [customFieldDefinitions, metadata],\n );\n\n const formContent = useMemo(\n (): ReadonlyArray<FormContentItem> =>\n rendererFieldDefinitions.length === 0\n ? EMPTY_FORM_CONTENT\n : rendererFieldDefinitions.map(\n (def): FormContentItem => ({ type: \"field\", definition: def }),\n ),\n [rendererFieldDefinitions],\n );\n\n const coerceFormState = useCallback(\n (rawState: Record<string, unknown>): Record<string, unknown> => {\n const coerced: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawState)) {\n coerced[key] = coerceFieldValue(parameters?.[key]?.type, value);\n }\n return coerced;\n },\n [parameters],\n );\n\n const handleSubmit = useCallback(\n async (rawFormState: Record<string, unknown>) => {\n const formState = coerceFormState(rawFormState) as FormState<Q>;\n try {\n if (onSubmit != null) {\n await onSubmit(formState, osdkApplyAction);\n } else {\n const result = await osdkApplyAction(formState);\n onSuccess?.(result);\n }\n } catch (e) {\n onError?.({ type: \"submission\", error: e });\n }\n },\n [coerceFormState, onSubmit, osdkApplyAction, onSuccess, onError],\n );\n\n const handleFieldValueChange = useCallback(\n (fieldKey: string, value: unknown) => {\n onFormStateChange?.(\n (prev) =>\n ({\n ...prev,\n [fieldKey]: value,\n }) as FormState<Q>,\n );\n },\n [onFormStateChange],\n );\n\n const resolvedTitle = formTitle ?? metadata?.displayName\n ?? actionDefinition.apiName;\n\n const isControlled = controlledFormState != null;\n\n const commonProps = {\n formTitle: resolvedTitle,\n formContent,\n onSubmit: handleSubmit,\n isSubmitDisabled,\n isPending,\n isLoading: metadataLoading,\n onFieldValueChange: handleFieldValueChange,\n portalContainer,\n };\n\n if (!isControlled) {\n return <BaseForm {...commonProps} />;\n }\n\n return <BaseForm {...commonProps} formState={controlledFormState} />;\n});\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"ActionForm.js","names":["useOsdkAction","useOsdkMetadata","React","useCallback","useEffect","useMemo","typedReactMemo","BaseForm","coerceFieldValue","getDefaultFieldDefinitions","EMPTY_FIELD_DEFINITIONS","EMPTY_FORM_CONTENT","ActionForm","actionDefinition","formTitle","showFormTitle","formFieldDefinitions","formState","controlledFormState","onFormStateChange","isSubmitDisabled","onSubmit","onValidationResponse","_onValidationResponse","onSuccess","onError","applyAction","osdkApplyAction","isPending","metadata","loading","metadataLoading","error","metadataError","type","parameters","customFieldDefinitions","map","def","defaultValue","fieldDefinition","fieldKey","String","fieldType","fieldComponentProps","undefined","rendererFieldDefinitions","formContent","length","definition","coerceFormState","rawState","coerced","key","value","Object","entries","handleSubmit","rawFormState","result","e","handleFieldValueChange","prev","resolvedTitle","displayName","apiName","commonProps","isLoading","onFieldValueChange","createElement","_extends"],"sources":["ActionForm.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 type { ActionDefinition } from \"@osdk/api\";\nimport { useOsdkAction, useOsdkMetadata } from \"@osdk/react\";\nimport React, { useCallback, useEffect, useMemo } from \"react\";\nimport { typedReactMemo } from \"../shared/typedMemo.js\";\nimport type {\n ActionFormProps,\n FormContentItem,\n FormState,\n} from \"./ActionFormApi.js\";\nimport { BaseForm } from \"./BaseForm.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { coerceFieldValue } from \"./utils/coerceFieldValue.js\";\nimport { getDefaultFieldDefinitions } from \"./utils/getDefaultFieldDefinitions.js\";\n\nconst EMPTY_FIELD_DEFINITIONS: ReadonlyArray<RendererFieldDefinition> = [];\nconst EMPTY_FORM_CONTENT: ReadonlyArray<FormContentItem> = [];\n\nexport const ActionForm: <Q extends ActionDefinition<unknown>>(\n props: ActionFormProps<Q>,\n) => React.ReactElement = typedReactMemo(function ActionFormFn<\n Q extends ActionDefinition<unknown>,\n>({\n actionDefinition,\n formTitle,\n showFormTitle = false,\n formFieldDefinitions,\n formState: controlledFormState,\n onFormStateChange,\n isSubmitDisabled,\n onSubmit,\n onValidationResponse: _onValidationResponse,\n onSuccess,\n onError,\n}: ActionFormProps<Q>): React.ReactElement {\n const { applyAction: osdkApplyAction, isPending } = useOsdkAction(\n actionDefinition,\n );\n const {\n metadata,\n loading: metadataLoading,\n error: metadataError,\n } = useOsdkMetadata(actionDefinition);\n\n useEffect(\n function saveMetadataError() {\n if (metadataError != null) {\n onError?.({ type: \"unknown\", error: metadataError });\n }\n },\n [metadataError, onError],\n );\n\n const parameters = metadata?.parameters;\n\n const customFieldDefinitions: ReadonlyArray<RendererFieldDefinition> | null =\n useMemo(() => {\n if (formFieldDefinitions == null) {\n return null;\n }\n // RendererFieldDefinition is a discriminated union keyed by fieldComponent.\n // TypeScript can't verify that the spread preserves the fieldComponent ↔\n // fieldComponentProps pairing, but FormFieldDefinition guarantees it.\n return formFieldDefinitions.map((def) => {\n const { defaultValue, ...fieldDefinition } = def;\n return {\n ...fieldDefinition,\n fieldKey: String(def.fieldKey),\n fieldType: parameters?.[String(def.fieldKey)]?.type,\n fieldComponentProps: defaultValue === undefined\n ? def.fieldComponentProps\n : { ...def.fieldComponentProps, defaultValue },\n } as RendererFieldDefinition;\n });\n }, [formFieldDefinitions, parameters]);\n\n const rendererFieldDefinitions = useMemo(\n () =>\n customFieldDefinitions\n ?? (metadata != null\n ? getDefaultFieldDefinitions(metadata)\n : EMPTY_FIELD_DEFINITIONS),\n [customFieldDefinitions, metadata],\n );\n\n const formContent = useMemo(\n (): ReadonlyArray<FormContentItem> =>\n rendererFieldDefinitions.length === 0\n ? EMPTY_FORM_CONTENT\n : rendererFieldDefinitions.map(\n (def): FormContentItem => ({ type: \"field\", definition: def }),\n ),\n [rendererFieldDefinitions],\n );\n\n const coerceFormState = useCallback(\n (rawState: Record<string, unknown>): Record<string, unknown> => {\n const coerced: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(rawState)) {\n coerced[key] = coerceFieldValue(parameters?.[key]?.type, value);\n }\n return coerced;\n },\n [parameters],\n );\n\n const handleSubmit = useCallback(\n async (rawFormState: Record<string, unknown>) => {\n const formState = coerceFormState(rawFormState) as FormState<Q>;\n try {\n if (onSubmit != null) {\n await onSubmit(formState, osdkApplyAction);\n } else {\n const result = await osdkApplyAction(formState);\n onSuccess?.(result);\n }\n } catch (e) {\n onError?.({ type: \"submission\", error: e });\n }\n },\n [coerceFormState, onSubmit, osdkApplyAction, onSuccess, onError],\n );\n\n const handleFieldValueChange = useCallback(\n (fieldKey: string, value: unknown) => {\n onFormStateChange?.(\n (prev) =>\n ({\n ...prev,\n [fieldKey]: value,\n }) as FormState<Q>,\n );\n },\n [onFormStateChange],\n );\n\n const resolvedTitle = showFormTitle\n ? (formTitle ?? metadata?.displayName ?? actionDefinition.apiName)\n : undefined;\n\n const isControlled = controlledFormState != null;\n\n const commonProps = {\n formTitle: resolvedTitle,\n formContent,\n onSubmit: handleSubmit,\n isSubmitDisabled,\n isPending,\n isLoading: metadataLoading,\n onFieldValueChange: handleFieldValueChange,\n };\n\n if (!isControlled) {\n return <BaseForm {...commonProps} />;\n }\n\n return <BaseForm {...commonProps} formState={controlledFormState} />;\n});\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionFormApi.js","names":[],"sources":["ActionFormApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n} from \"@osdk/api\";\nimport type { ActionValidationError } from \"@osdk/client\";\nimport type {\n ActionParameters,\n FieldKey,\n FieldValueType,\n FormFieldDefinition,\n
|
|
1
|
+
{"version":3,"file":"ActionFormApi.js","names":[],"sources":["ActionFormApi.ts"],"sourcesContent":["/*\n * Copyright 2025 Palantir Technologies, Inc. All rights reserved.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type {\n ActionDefinition,\n ActionEditResponse,\n ActionValidationResponse,\n} from \"@osdk/api\";\nimport type { ActionValidationError } from \"@osdk/client\";\nimport type {\n ActionParameters,\n FieldKey,\n FieldValueType,\n FormFieldDefinition,\n RendererFieldDefinition,\n} from \"./FormFieldApi.js\";\n\n/**\n * Props for the ActionForm component.\n *\n * A discriminated union ensures that controlled mode (formState provided)\n * always requires onFormStateChange, and uncontrolled mode makes `onFormStateChange` optional\n */\nexport type ActionFormProps<Q extends ActionDefinition<unknown>> =\n | (ActionFormConfigProps<Q> & {\n formState: FormState<Q>;\n onFormStateChange: (\n updater: (prevState: FormState<Q>) => FormState<Q>,\n ) => void;\n })\n | (ActionFormConfigProps<Q> & {\n formState?: undefined;\n onFormStateChange?: (\n updater: (prevState: FormState<Q>) => FormState<Q>,\n ) => void;\n });\n\ninterface ActionFormConfigProps<Q extends ActionDefinition<unknown>>\n extends Pick<BaseFormProps, \"formTitle\" | \"isSubmitDisabled\">\n{\n actionDefinition: Q;\n\n /**\n * Whether to show the form title.\n *\n * @default false\n */\n showFormTitle?: boolean;\n\n /**\n * If not supplied, field definitions are constructed from `ActionParameters`.\n */\n formFieldDefinitions?: ReadonlyArray<FormFieldDefinition<Q>>;\n\n /**\n * If supplied, this will override the default submit action\n * By default, the action's applyAction will be called\n *\n * @param formState all field values when onSubmit is called\n * @param applyAction the function to execute the action\n * @returns a promise of the submission response\n */\n onSubmit?: (\n formState: FormState<Q>,\n applyAction: (\n args: ActionParameters<Q>,\n ) => Promise<ActionEditResponse | undefined>,\n ) => Promise<unknown> | void;\n\n /**\n * Called when the validation response is returned from a validateOnly submission\n *\n * @param results the validation response\n */\n onValidationResponse?: (results: ActionValidationResponse) => void;\n\n /**\n * Called when the action is successfully executed from a non-validateOnly submission\n *\n * @param results the submission response\n */\n onSuccess?: (results: ActionEditResponse | undefined) => void;\n\n /**\n * Called when there is an error in form submission\n *\n * @param error the error that occurred\n */\n onError?: (error: FormError) => void;\n}\n\n/**\n * Form values mapping parameter names to their values\n */\nexport type FormState<Q extends ActionDefinition<unknown>> = {\n [K in FieldKey<Q>]?: FieldValueType<Q, K>;\n};\n\n/**\n * Form error discriminated union\n */\nexport type FormError =\n | { type: \"validation\"; error: ActionValidationError }\n | { type: \"submission\"; error: unknown }\n | { type: \"unknown\"; error: unknown };\n\n/**\n * A single item in the form content array — either a standalone field\n * or a section that groups multiple fields.\n */\nexport type FormContentItem =\n | { type: \"field\"; definition: RendererFieldDefinition }\n | { type: \"section\"; key: string; definition: FormSectionDefinition };\n\n/**\n * Configuration for a form section — a visual group of fields with\n * optional title bar, collapse behavior, and multi-column layout.\n */\nexport interface FormSectionDefinition {\n title: string;\n description?: string;\n fields: ReadonlyArray<RendererFieldDefinition>;\n /** Whether the section starts collapsed. Default `false`. */\n collapsedByDefault?: boolean;\n /** Whether to show the title bar. Default `true`. */\n showTitleBar?: boolean;\n /** Number of columns for fields. Default `1`. */\n columnCount?: 1 | 2;\n /** Visual style. `\"box\"` = bordered card, `\"minimal\"` = heading only. Default `\"box\"`. */\n style?: \"box\" | \"minimal\";\n}\n\n/**\n * Props for the `BaseForm` component, which renders a form without\n * OSDK data fetching.\n *\n * Uses a discriminated union so that controlled mode (`formState` provided)\n * always requires `onFieldValueChange`, and uncontrolled mode omits both.\n * `onSubmit` receives the current form state so callers can access values\n * even in uncontrolled mode.\n */\nexport type BaseFormProps =\n & BaseFormCommonProps\n & (\n | {\n formState: Record<string, unknown>;\n onFieldValueChange: (fieldKey: string, value: unknown) => void;\n }\n | {\n formState?: undefined;\n onFieldValueChange?: (fieldKey: string, value: unknown) => void;\n }\n );\n\ninterface BaseFormCommonProps {\n formTitle?: string;\n formContent: ReadonlyArray<FormContentItem>;\n onSubmit: (formState: Record<string, unknown>) => Promise<void> | void;\n isSubmitDisabled?: boolean;\n isPending?: boolean;\n isLoading?: boolean;\n className?: string;\n /** Label for the submit button. Default `\"Submit\"`. */\n submitButtonText?: string;\n /** Visual variant of the submit button. Default `\"primary\"`. */\n submitButtonVariant?: \"primary\" | \"secondary\";\n}\n"],"mappings":"","ignoreList":[]}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { Error as ErrorIcon } from "@blueprintjs/icons";
|
|
18
18
|
import classNames from "classnames";
|
|
19
|
-
import React, { memo, useCallback, useMemo, useState } from "react";
|
|
19
|
+
import React, { memo, useCallback, useMemo, useRef, useState } from "react";
|
|
20
20
|
import { useForm } from "react-hook-form";
|
|
21
21
|
import { ActionButton } from "../base-components/action-button/ActionButton.js";
|
|
22
22
|
import { SkeletonBar } from "../base-components/skeleton/SkeletonBar.js";
|
|
@@ -37,9 +37,9 @@ export const BaseForm = /*#__PURE__*/memo(function ({
|
|
|
37
37
|
isLoading = false,
|
|
38
38
|
className,
|
|
39
39
|
submitButtonText = "Submit",
|
|
40
|
-
submitButtonVariant = "primary"
|
|
41
|
-
portalContainer
|
|
40
|
+
submitButtonVariant = "primary"
|
|
42
41
|
}) {
|
|
42
|
+
const portalContainerRef = useRef(null);
|
|
43
43
|
const allFieldDefinitions = useMemo(() => flattenFieldDefinitions(formContent), [formContent]);
|
|
44
44
|
const defaultValues = useMemo(() => buildDefaultValues(allFieldDefinitions), [allFieldDefinitions]);
|
|
45
45
|
const {
|
|
@@ -70,8 +70,7 @@ export const BaseForm = /*#__PURE__*/memo(function ({
|
|
|
70
70
|
const submissionErrorMessage = submissionError != null ? submissionError instanceof Error ? submissionError.message
|
|
71
71
|
// TODO: provide better error message
|
|
72
72
|
: "Submission failed" : undefined;
|
|
73
|
-
const
|
|
74
|
-
e.preventDefault();
|
|
73
|
+
const submitForm = useCallback(async () => {
|
|
75
74
|
setHasAttemptedSubmit(true);
|
|
76
75
|
const isValid = await trigger();
|
|
77
76
|
if (!isValid) {
|
|
@@ -99,8 +98,12 @@ export const BaseForm = /*#__PURE__*/memo(function ({
|
|
|
99
98
|
const areErrorsPresent = errorEntries.length > 0;
|
|
100
99
|
const buttonErrorMessage = areErrorsPresent ? "Some fields are invalid" : submissionErrorMessage;
|
|
101
100
|
return /*#__PURE__*/React.createElement("form", {
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
ref: portalContainerRef,
|
|
102
|
+
className: classNames(styles.osdkForm, className)
|
|
103
|
+
// Workshop widgets can run in iframes without `allow-forms`, where
|
|
104
|
+
// native form submission is blocked. Keep the form landmark, but do not
|
|
105
|
+
// wire any form-level submit handlers; the submit button invokes our
|
|
106
|
+
// JavaScript submit path directly.
|
|
104
107
|
}, formTitle != null && /*#__PURE__*/React.createElement(FormHeader, {
|
|
105
108
|
title: formTitle
|
|
106
109
|
}), isLoading && allFieldDefinitions.length === 0 && /*#__PURE__*/React.createElement("div", {
|
|
@@ -116,7 +119,7 @@ export const BaseForm = /*#__PURE__*/memo(function ({
|
|
|
116
119
|
fieldDef: item.definition,
|
|
117
120
|
control: control,
|
|
118
121
|
onExternalChange: handleFieldChange,
|
|
119
|
-
portalContainer:
|
|
122
|
+
portalContainer: portalContainerRef
|
|
120
123
|
});
|
|
121
124
|
}
|
|
122
125
|
const sectionErrorCount = item.definition.fields.reduce((count, field) => count + (errors[field.fieldKey] != null ? 1 : 0), 0);
|
|
@@ -129,7 +132,7 @@ export const BaseForm = /*#__PURE__*/memo(function ({
|
|
|
129
132
|
fieldDef: fieldDef,
|
|
130
133
|
control: control,
|
|
131
134
|
onExternalChange: handleFieldChange,
|
|
132
|
-
portalContainer:
|
|
135
|
+
portalContainer: portalContainerRef
|
|
133
136
|
})));
|
|
134
137
|
})), /*#__PURE__*/React.createElement("div", {
|
|
135
138
|
className: styles.osdkFormFooter
|
|
@@ -142,7 +145,8 @@ export const BaseForm = /*#__PURE__*/memo(function ({
|
|
|
142
145
|
isSubmitDisabled: isSubmitDisabled || hasAttemptedSubmit && areErrorsPresent,
|
|
143
146
|
errorMessage: buttonErrorMessage,
|
|
144
147
|
buttonText: submitButtonText,
|
|
145
|
-
buttonVariant: submitButtonVariant
|
|
148
|
+
buttonVariant: submitButtonVariant,
|
|
149
|
+
onClick: submitForm
|
|
146
150
|
}))));
|
|
147
151
|
});
|
|
148
152
|
|
|
@@ -193,13 +197,15 @@ const SubmitButton = /*#__PURE__*/memo(function ({
|
|
|
193
197
|
isSubmitDisabled,
|
|
194
198
|
errorMessage,
|
|
195
199
|
buttonText,
|
|
196
|
-
buttonVariant
|
|
200
|
+
buttonVariant,
|
|
201
|
+
onClick
|
|
197
202
|
}) {
|
|
198
203
|
const buttonLabel = isPending ? "Submitting\u2026" : buttonText;
|
|
199
204
|
const button = /*#__PURE__*/React.createElement(ActionButton, {
|
|
200
|
-
type: "
|
|
205
|
+
type: "button",
|
|
201
206
|
variant: buttonVariant,
|
|
202
|
-
disabled: isSubmitDisabled || isPending
|
|
207
|
+
disabled: isSubmitDisabled || isPending,
|
|
208
|
+
onClick: onClick
|
|
203
209
|
}, buttonLabel);
|
|
204
210
|
if (errorMessage == null) {
|
|
205
211
|
return button;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseForm.js","names":["Error","ErrorIcon","classNames","React","memo","useCallback","useMemo","useState","useForm","ActionButton","SkeletonBar","Tooltip","useAsyncAction","styles","FieldBridge","FormHeader","FormSection","BaseForm","formTitle","formContent","formState","controlledFormState","onFieldValueChange","onSubmit","isSubmitDisabled","isPending","isLoading","className","submitButtonText","submitButtonVariant","portalContainer","allFieldDefinitions","flattenFieldDefinitions","defaultValues","buildDefaultValues","control","trigger","getValues","errors","mode","values","hasAttemptedSubmit","setHasAttemptedSubmit","isSubmitting","error","submissionError","execute","executeSubmit","clearError","submissionErrorMessage","message","undefined","handleFormSubmit","e","preventDefault","isValid","handleFieldChange","fieldKey","value","labelByFieldKey","Map","map","d","label","errorEntries","Object","entries","key","entry","get","areErrorsPresent","length","buttonErrorMessage","createElement","osdkForm","title","role","osdkFormFields","FORM_SKELETON","item","type","definition","fieldDef","onExternalChange","sectionErrorCount","fields","reduce","count","field","errorCount","osdkFormFooter","ErrorIndicator","osdkFormSubmitButton","SubmitButton","errorMessage","buttonText","buttonVariant","result","push","SKELETON_FIELD_COUNT","Array","from","_","i","osdkFormSkeletonField","osdkFormSkeletonLabel","osdkFormSkeletonInput","fieldDefinitions","def","props","fieldComponentProps","defaultValue","buttonLabel","button","variant","disabled","Root","defaultOpen","Trigger","render","osdkTooltipTriggerWrapper","Portal","Positioner","Popup","Arrow","osdkFormErrorIndicator","size","osdkFormErrorList"],"sources":["BaseForm.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 { Error as ErrorIcon } from \"@blueprintjs/icons\";\nimport classNames from \"classnames\";\nimport React, { memo, useCallback, useMemo, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { SkeletonBar } from \"../base-components/skeleton/SkeletonBar.js\";\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { useAsyncAction } from \"../shared/hooks/useAsyncAction.js\";\nimport type { BaseFormProps, FormContentItem } from \"./ActionFormApi.js\";\nimport styles from \"./BaseForm.module.css\";\nimport { FieldBridge } from \"./fields/FieldBridge.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { FormHeader } from \"./FormHeader.js\";\nimport { FormSection } from \"./FormSection.js\";\n\nexport const BaseForm: React.FC<BaseFormProps> = memo(function BaseFormFn({\n formTitle,\n formContent,\n formState: controlledFormState,\n onFieldValueChange,\n onSubmit,\n isSubmitDisabled = false,\n isPending = false,\n isLoading = false,\n className,\n submitButtonText = \"Submit\",\n submitButtonVariant = \"primary\",\n portalContainer,\n}: BaseFormProps): React.ReactElement {\n const isControlled = controlledFormState != null;\n\n const allFieldDefinitions = useMemo(\n () => flattenFieldDefinitions(formContent),\n [formContent],\n );\n\n const defaultValues = useMemo(\n () => buildDefaultValues(allFieldDefinitions),\n [allFieldDefinitions],\n );\n\n const {\n control,\n trigger,\n getValues,\n formState: { errors },\n } = useForm<Record<string, unknown>>({\n // Validate on blur first, then revalidate on change after the first\n // error. This gives the user a chance to finish typing before seeing\n // errors, while staying responsive once an error is surfaced.\n mode: \"onTouched\",\n ...(isControlled ? { values: controlledFormState } : { defaultValues }),\n });\n\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n\n const {\n isPending: isSubmitting,\n error: submissionError,\n execute: executeSubmit,\n clearError,\n } = useAsyncAction(onSubmit);\n const submissionErrorMessage = submissionError != null\n ? submissionError instanceof Error\n ? submissionError.message\n // TODO: provide better error message\n : \"Submission failed\"\n : undefined;\n\n const handleFormSubmit = useCallback(\n async (e: React.FormEvent) => {\n e.preventDefault();\n setHasAttemptedSubmit(true);\n\n const isValid = await trigger();\n if (!isValid) {\n return;\n }\n\n // In controlled mode, always submit the controlled state, not RHF's\n // internal state. Between a user keystroke and the parent re-rendering,\n // RHF's store may hold the user-typed value rather than the parent's\n // value. Using controlledFormState directly preserves the existing\n // guarantee that controlled mode submits the parent's state.\n await executeSubmit(controlledFormState ?? getValues());\n },\n [trigger, executeSubmit, controlledFormState, getValues],\n );\n\n const handleFieldChange = useCallback(\n (fieldKey: string, value: unknown) => {\n clearError();\n onFieldValueChange?.(fieldKey, value);\n },\n [clearError, onFieldValueChange],\n );\n\n const isFormPending = isPending || isSubmitting;\n\n const labelByFieldKey = useMemo(\n () => new Map(allFieldDefinitions.map((d) => [d.fieldKey, d.label])),\n [allFieldDefinitions],\n );\n\n // RHF reuses the same errors object reference across renders so we cannot memoize errorEntries\n const errorEntries = Object.entries(errors).map(([key, entry]) => ({\n label: labelByFieldKey.get(key) ?? key,\n message: entry?.message ?? \"Invalid\",\n }));\n const areErrorsPresent = errorEntries.length > 0;\n const buttonErrorMessage = areErrorsPresent\n ? \"Some fields are invalid\"\n : submissionErrorMessage;\n\n return (\n <form\n className={classNames(styles.osdkForm, className)}\n onSubmit={handleFormSubmit}\n >\n {formTitle != null && <FormHeader title={formTitle} />}\n {isLoading && allFieldDefinitions.length === 0 && (\n <div\n role=\"status\"\n aria-label=\"Loading form fields\"\n className={styles.osdkFormFields}\n >\n {FORM_SKELETON}\n </div>\n )}\n <div className={styles.osdkFormFields}>\n {formContent.map((item) => {\n if (item.type === \"field\") {\n return (\n <FieldBridge\n key={item.definition.fieldKey}\n fieldDef={item.definition}\n control={control}\n onExternalChange={handleFieldChange}\n portalContainer={portalContainer}\n />\n );\n }\n const sectionErrorCount = item.definition.fields.reduce(\n (count, field) => count + (errors[field.fieldKey] != null ? 1 : 0),\n 0,\n );\n return (\n <FormSection\n key={item.key}\n definition={item.definition}\n errorCount={sectionErrorCount}\n >\n {item.definition.fields.map((fieldDef) => (\n <FieldBridge\n key={fieldDef.fieldKey}\n fieldDef={fieldDef}\n control={control}\n onExternalChange={handleFieldChange}\n portalContainer={portalContainer}\n />\n ))}\n </FormSection>\n );\n })}\n </div>\n <div className={styles.osdkFormFooter}>\n <ErrorIndicator errorEntries={errorEntries} />\n <div className={styles.osdkFormSubmitButton}>\n <SubmitButton\n isPending={isFormPending}\n isSubmitDisabled={isSubmitDisabled\n || (hasAttemptedSubmit && areErrorsPresent)}\n errorMessage={buttonErrorMessage}\n buttonText={submitButtonText}\n buttonVariant={submitButtonVariant}\n />\n </div>\n </div>\n </form>\n );\n});\n\n/**\n * Extracts all RendererFieldDefinitions from formContent, flattening\n * section fields into a single array. RHF sees a flat field namespace\n * regardless of visual grouping, so this is used to build default values\n * and the field-key-to-label map for error display.\n */\nfunction flattenFieldDefinitions(\n formContent: ReadonlyArray<FormContentItem>,\n): ReadonlyArray<RendererFieldDefinition> {\n const result: RendererFieldDefinition[] = [];\n for (const item of formContent) {\n if (item.type === \"field\") {\n result.push(item.definition);\n } else {\n for (const fieldDef of item.definition.fields) {\n result.push(fieldDef);\n }\n }\n }\n return result;\n}\n\nconst SKELETON_FIELD_COUNT = 3;\n\n// Mimics the label + input layout of real form fields.\nconst FORM_SKELETON = Array.from(\n { length: SKELETON_FIELD_COUNT },\n (_, i) => (\n <div key={i} className={styles.osdkFormSkeletonField}>\n <SkeletonBar className={styles.osdkFormSkeletonLabel} />\n <SkeletonBar className={styles.osdkFormSkeletonInput} />\n </div>\n ),\n);\n\nfunction buildDefaultValues(\n fieldDefinitions: ReadonlyArray<RendererFieldDefinition>,\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const def of fieldDefinitions) {\n const props: Record<string, unknown> = def.fieldComponentProps;\n if (\"defaultValue\" in props) {\n values[def.fieldKey] = props.defaultValue;\n }\n }\n return values;\n}\n\ninterface ErrorEntry {\n label: string;\n message: string;\n}\n\ninterface SubmitButtonProps {\n isPending: boolean;\n isSubmitDisabled: boolean;\n errorMessage: string | undefined;\n buttonText: string;\n buttonVariant: \"primary\" | \"secondary\";\n}\n\nconst SubmitButton = memo(function SubmitButtonFn({\n isPending,\n isSubmitDisabled,\n errorMessage,\n buttonText,\n buttonVariant,\n}: SubmitButtonProps): React.ReactElement {\n const buttonLabel = isPending ? \"Submitting\\u2026\" : buttonText;\n const button = (\n <ActionButton\n type=\"submit\"\n variant={buttonVariant}\n disabled={isSubmitDisabled || isPending}\n >\n {buttonLabel}\n </ActionButton>\n );\n\n if (errorMessage == null) {\n return button;\n }\n\n return (\n <Tooltip.Root defaultOpen={true}>\n <Tooltip.Trigger\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {button}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n {errorMessage}\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n});\n\ninterface ErrorIndicatorProps {\n errorEntries: ReadonlyArray<ErrorEntry>;\n}\n\n// memo omitted: errorEntries is always a new array (RHF reuses the same errors ref)\nfunction ErrorIndicator({\n errorEntries,\n}: ErrorIndicatorProps): React.ReactElement | null {\n if (errorEntries.length === 0) {\n return null;\n }\n\n const count = errorEntries.length;\n\n return (\n <Tooltip.Root>\n <Tooltip.Trigger>\n <span className={styles.osdkFormErrorIndicator}>\n <ErrorIcon size={14} />\n {count === 1 ? \"1 issue\" : `${count} issues`}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n <ul className={styles.osdkFormErrorList}>\n {errorEntries.map((entry) => (\n <li key={entry.label}>\n <strong>{entry.label}:</strong> {entry.message}\n </li>\n ))}\n </ul>\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"BaseForm.js","names":["Error","ErrorIcon","classNames","React","memo","useCallback","useMemo","useRef","useState","useForm","ActionButton","SkeletonBar","Tooltip","useAsyncAction","styles","FieldBridge","FormHeader","FormSection","BaseForm","formTitle","formContent","formState","controlledFormState","onFieldValueChange","onSubmit","isSubmitDisabled","isPending","isLoading","className","submitButtonText","submitButtonVariant","portalContainerRef","allFieldDefinitions","flattenFieldDefinitions","defaultValues","buildDefaultValues","control","trigger","getValues","errors","mode","values","hasAttemptedSubmit","setHasAttemptedSubmit","isSubmitting","error","submissionError","execute","executeSubmit","clearError","submissionErrorMessage","message","undefined","submitForm","isValid","handleFieldChange","fieldKey","value","labelByFieldKey","Map","map","d","label","errorEntries","Object","entries","key","entry","get","areErrorsPresent","length","buttonErrorMessage","createElement","ref","osdkForm","title","role","osdkFormFields","FORM_SKELETON","item","type","definition","fieldDef","onExternalChange","portalContainer","sectionErrorCount","fields","reduce","count","field","errorCount","osdkFormFooter","ErrorIndicator","osdkFormSubmitButton","SubmitButton","errorMessage","buttonText","buttonVariant","onClick","result","push","SKELETON_FIELD_COUNT","Array","from","_","i","osdkFormSkeletonField","osdkFormSkeletonLabel","osdkFormSkeletonInput","fieldDefinitions","def","props","fieldComponentProps","defaultValue","buttonLabel","button","variant","disabled","Root","defaultOpen","Trigger","render","osdkTooltipTriggerWrapper","Portal","Positioner","Popup","Arrow","osdkFormErrorIndicator","size","osdkFormErrorList"],"sources":["BaseForm.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 { Error as ErrorIcon } from \"@blueprintjs/icons\";\nimport classNames from \"classnames\";\nimport React, { memo, useCallback, useMemo, useRef, useState } from \"react\";\nimport { useForm } from \"react-hook-form\";\nimport { ActionButton } from \"../base-components/action-button/ActionButton.js\";\nimport { SkeletonBar } from \"../base-components/skeleton/SkeletonBar.js\";\nimport { Tooltip } from \"../base-components/tooltip/Tooltip.js\";\nimport { useAsyncAction } from \"../shared/hooks/useAsyncAction.js\";\nimport type { BaseFormProps, FormContentItem } from \"./ActionFormApi.js\";\nimport styles from \"./BaseForm.module.css\";\nimport { FieldBridge } from \"./fields/FieldBridge.js\";\nimport type { RendererFieldDefinition } from \"./FormFieldApi.js\";\nimport { FormHeader } from \"./FormHeader.js\";\nimport { FormSection } from \"./FormSection.js\";\n\nexport const BaseForm: React.FC<BaseFormProps> = memo(function BaseFormFn({\n formTitle,\n formContent,\n formState: controlledFormState,\n onFieldValueChange,\n onSubmit,\n isSubmitDisabled = false,\n isPending = false,\n isLoading = false,\n className,\n submitButtonText = \"Submit\",\n submitButtonVariant = \"primary\",\n}: BaseFormProps): React.ReactElement {\n const portalContainerRef = useRef<HTMLFormElement>(null);\n const isControlled = controlledFormState != null;\n\n const allFieldDefinitions = useMemo(\n () => flattenFieldDefinitions(formContent),\n [formContent],\n );\n\n const defaultValues = useMemo(\n () => buildDefaultValues(allFieldDefinitions),\n [allFieldDefinitions],\n );\n\n const {\n control,\n trigger,\n getValues,\n formState: { errors },\n } = useForm<Record<string, unknown>>({\n // Validate on blur first, then revalidate on change after the first\n // error. This gives the user a chance to finish typing before seeing\n // errors, while staying responsive once an error is surfaced.\n mode: \"onTouched\",\n ...(isControlled ? { values: controlledFormState } : { defaultValues }),\n });\n\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = useState(false);\n\n const {\n isPending: isSubmitting,\n error: submissionError,\n execute: executeSubmit,\n clearError,\n } = useAsyncAction(onSubmit);\n const submissionErrorMessage = submissionError != null\n ? submissionError instanceof Error\n ? submissionError.message\n // TODO: provide better error message\n : \"Submission failed\"\n : undefined;\n\n const submitForm = useCallback(async () => {\n setHasAttemptedSubmit(true);\n\n const isValid = await trigger();\n if (!isValid) {\n return;\n }\n\n // In controlled mode, always submit the controlled state, not RHF's\n // internal state. Between a user keystroke and the parent re-rendering,\n // RHF's store may hold the user-typed value rather than the parent's\n // value. Using controlledFormState directly preserves the existing\n // guarantee that controlled mode submits the parent's state.\n await executeSubmit(controlledFormState ?? getValues());\n }, [trigger, executeSubmit, controlledFormState, getValues]);\n\n const handleFieldChange = useCallback(\n (fieldKey: string, value: unknown) => {\n clearError();\n onFieldValueChange?.(fieldKey, value);\n },\n [clearError, onFieldValueChange],\n );\n\n const labelByFieldKey = useMemo(\n () => new Map(allFieldDefinitions.map((d) => [d.fieldKey, d.label])),\n [allFieldDefinitions],\n );\n\n // RHF reuses the same errors object reference across renders so we cannot memoize errorEntries\n const errorEntries = Object.entries(errors).map(([key, entry]) => ({\n label: labelByFieldKey.get(key) ?? key,\n message: entry?.message ?? \"Invalid\",\n }));\n const areErrorsPresent = errorEntries.length > 0;\n const buttonErrorMessage = areErrorsPresent\n ? \"Some fields are invalid\"\n : submissionErrorMessage;\n const isFormPending = isPending || isSubmitting;\n const isSubmitButtonDisabled = isSubmitDisabled\n || (hasAttemptedSubmit && areErrorsPresent);\n\n return (\n <form\n ref={portalContainerRef}\n className={classNames(styles.osdkForm, className)}\n // Workshop widgets can run in iframes without `allow-forms`, where\n // native form submission is blocked. Keep the form landmark, but do not\n // wire any form-level submit handlers; the submit button invokes our\n // JavaScript submit path directly.\n >\n {formTitle != null && <FormHeader title={formTitle} />}\n {isLoading && allFieldDefinitions.length === 0 && (\n <div\n role=\"status\"\n aria-label=\"Loading form fields\"\n className={styles.osdkFormFields}\n >\n {FORM_SKELETON}\n </div>\n )}\n <div className={styles.osdkFormFields}>\n {formContent.map((item) => {\n if (item.type === \"field\") {\n return (\n <FieldBridge\n key={item.definition.fieldKey}\n fieldDef={item.definition}\n control={control}\n onExternalChange={handleFieldChange}\n portalContainer={portalContainerRef}\n />\n );\n }\n const sectionErrorCount = item.definition.fields.reduce(\n (count, field) => count + (errors[field.fieldKey] != null ? 1 : 0),\n 0,\n );\n return (\n <FormSection\n key={item.key}\n definition={item.definition}\n errorCount={sectionErrorCount}\n >\n {item.definition.fields.map((fieldDef) => (\n <FieldBridge\n key={fieldDef.fieldKey}\n fieldDef={fieldDef}\n control={control}\n onExternalChange={handleFieldChange}\n portalContainer={portalContainerRef}\n />\n ))}\n </FormSection>\n );\n })}\n </div>\n <div className={styles.osdkFormFooter}>\n <ErrorIndicator errorEntries={errorEntries} />\n <div className={styles.osdkFormSubmitButton}>\n <SubmitButton\n isPending={isFormPending}\n isSubmitDisabled={isSubmitButtonDisabled}\n errorMessage={buttonErrorMessage}\n buttonText={submitButtonText}\n buttonVariant={submitButtonVariant}\n onClick={submitForm}\n />\n </div>\n </div>\n </form>\n );\n});\n\n/**\n * Extracts all RendererFieldDefinitions from formContent, flattening\n * section fields into a single array. RHF sees a flat field namespace\n * regardless of visual grouping, so this is used to build default values\n * and the field-key-to-label map for error display.\n */\nfunction flattenFieldDefinitions(\n formContent: ReadonlyArray<FormContentItem>,\n): ReadonlyArray<RendererFieldDefinition> {\n const result: RendererFieldDefinition[] = [];\n for (const item of formContent) {\n if (item.type === \"field\") {\n result.push(item.definition);\n } else {\n for (const fieldDef of item.definition.fields) {\n result.push(fieldDef);\n }\n }\n }\n return result;\n}\n\nconst SKELETON_FIELD_COUNT = 3;\n\n// Mimics the label + input layout of real form fields.\nconst FORM_SKELETON = Array.from(\n { length: SKELETON_FIELD_COUNT },\n (_, i) => (\n <div key={i} className={styles.osdkFormSkeletonField}>\n <SkeletonBar className={styles.osdkFormSkeletonLabel} />\n <SkeletonBar className={styles.osdkFormSkeletonInput} />\n </div>\n ),\n);\n\nfunction buildDefaultValues(\n fieldDefinitions: ReadonlyArray<RendererFieldDefinition>,\n): Record<string, unknown> {\n const values: Record<string, unknown> = {};\n for (const def of fieldDefinitions) {\n const props: Record<string, unknown> = def.fieldComponentProps;\n if (\"defaultValue\" in props) {\n values[def.fieldKey] = props.defaultValue;\n }\n }\n return values;\n}\n\ninterface ErrorEntry {\n label: string;\n message: string;\n}\n\ninterface SubmitButtonProps {\n isPending: boolean;\n isSubmitDisabled: boolean;\n errorMessage: string | undefined;\n buttonText: string;\n buttonVariant: \"primary\" | \"secondary\";\n onClick: () => void;\n}\n\nconst SubmitButton = memo(function SubmitButtonFn({\n isPending,\n isSubmitDisabled,\n errorMessage,\n buttonText,\n buttonVariant,\n onClick,\n}: SubmitButtonProps): React.ReactElement {\n const buttonLabel = isPending ? \"Submitting\\u2026\" : buttonText;\n const button = (\n <ActionButton\n type=\"button\"\n variant={buttonVariant}\n disabled={isSubmitDisabled || isPending}\n onClick={onClick}\n >\n {buttonLabel}\n </ActionButton>\n );\n\n if (errorMessage == null) {\n return button;\n }\n\n return (\n <Tooltip.Root defaultOpen={true}>\n <Tooltip.Trigger\n render={<span className={styles.osdkTooltipTriggerWrapper} />}\n >\n {button}\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n {errorMessage}\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n});\n\ninterface ErrorIndicatorProps {\n errorEntries: ReadonlyArray<ErrorEntry>;\n}\n\n// memo omitted: errorEntries is always a new array (RHF reuses the same errors ref)\nfunction ErrorIndicator({\n errorEntries,\n}: ErrorIndicatorProps): React.ReactElement | null {\n if (errorEntries.length === 0) {\n return null;\n }\n\n const count = errorEntries.length;\n\n return (\n <Tooltip.Root>\n <Tooltip.Trigger>\n <span className={styles.osdkFormErrorIndicator}>\n <ErrorIcon size={14} />\n {count === 1 ? \"1 issue\" : `${count} issues`}\n </span>\n </Tooltip.Trigger>\n <Tooltip.Portal>\n <Tooltip.Positioner>\n <Tooltip.Popup>\n <Tooltip.Arrow />\n <ul className={styles.osdkFormErrorList}>\n {errorEntries.map((entry) => (\n <li key={entry.label}>\n <strong>{entry.label}:</strong> {entry.message}\n </li>\n ))}\n </ul>\n </Tooltip.Popup>\n </Tooltip.Positioner>\n </Tooltip.Portal>\n </Tooltip.Root>\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -23,8 +23,9 @@
|
|
|
23
23
|
.osdkFormFields {
|
|
24
24
|
display: flex;
|
|
25
25
|
flex-direction: column;
|
|
26
|
-
gap: var(--osdk-form-
|
|
27
|
-
padding: var(--osdk-form-content-padding);
|
|
26
|
+
gap: var(--osdk-form-fields-gap);
|
|
27
|
+
padding-block: var(--osdk-form-content-padding-block);
|
|
28
|
+
padding-inline: var(--osdk-form-content-padding-inline);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
.osdkFormFooter {
|
|
@@ -32,10 +33,9 @@
|
|
|
32
33
|
flex-direction: row;
|
|
33
34
|
justify-content: space-between;
|
|
34
35
|
align-items: center;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
padding-inline: var(--osdk-form-content-padding);
|
|
36
|
+
padding-block: var(--osdk-form-content-padding-inline);
|
|
37
|
+
padding-inline: var(--osdk-form-content-padding-inline);
|
|
38
|
+
border-block-start: var(--osdk-surface-border-width) solid var(--osdk-form-footer-border-color);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
.osdkFormSubmitButton {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
.osdkFormSkeletonField {
|
|
62
62
|
display: flex;
|
|
63
63
|
flex-direction: column;
|
|
64
|
-
gap: var(--osdk-form-
|
|
64
|
+
gap: var(--osdk-form-field-gap);
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
.osdkFormSkeletonLabel {
|
|
@@ -45,10 +45,13 @@ export const FormField = /*#__PURE__*/memo(function ({
|
|
|
45
45
|
label: label
|
|
46
46
|
}, helperText)) : labelElement, hasHelperText && helperTextPlacement === "bottom" && /*#__PURE__*/React.createElement("div", {
|
|
47
47
|
className: styles.osdkFormFieldHelperText
|
|
48
|
-
}, helperText), children,
|
|
48
|
+
}, helperText), children, /*#__PURE__*/React.createElement("div", {
|
|
49
|
+
className: styles.osdkFormFieldErrorSlot,
|
|
50
|
+
"data-osdk-form-field-error-slot": ""
|
|
51
|
+
}, error != null && /*#__PURE__*/React.createElement("div", {
|
|
49
52
|
className: styles.osdkFormFieldError,
|
|
50
53
|
role: "alert"
|
|
51
|
-
}, error));
|
|
54
|
+
}, error)));
|
|
52
55
|
});
|
|
53
56
|
// Uses Popover (not Tooltip) because helper text may contain interactive
|
|
54
57
|
// content like links that need focus management and keyboard navigation.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormField.js","names":["Popover","InfoSign","React","memo","styles","FormField","fieldKey","label","isRequired","helperText","helperTextPlacement","error","onBlur","children","hasHelperText","labelElement","createElement","className","osdkFormFieldLabel","htmlFor","osdkFormFieldRequired","osdkFormField","osdkFormFieldLabelRow","InfoTip","osdkFormFieldHelperText","osdkFormFieldError","role","Root","Trigger","render","osdkFormFieldInfoIcon","nativeButton","openOnHover","size","Portal","Positioner","sideOffset","Popup","osdkFormFieldInfoPopup"],"sources":["FormField.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 { Popover } from \"@base-ui/react/popover\";\nimport { InfoSign } from \"@blueprintjs/icons\";\nimport React, { memo } from \"react\";\nimport styles from \"./FormField.module.css\";\n\ninterface FormFieldProps {\n fieldKey: string;\n label?: string;\n isRequired?: boolean;\n helperText?: React.ReactNode;\n helperTextPlacement?: \"bottom\" | \"tooltip\";\n error?: string;\n onBlur?: (e: React.FocusEvent<HTMLDivElement>) => void;\n children: React.ReactNode;\n}\n\nexport const FormField: React.FC<FormFieldProps> = memo(function FormFieldFn({\n fieldKey,\n label,\n isRequired,\n helperText,\n helperTextPlacement = \"tooltip\",\n error,\n onBlur,\n children,\n}: FormFieldProps): React.ReactElement {\n const hasHelperText = helperText != null && helperText !== \"\";\n const showTooltip = hasHelperText && helperTextPlacement === \"tooltip\";\n const showBottomText = hasHelperText && helperTextPlacement === \"bottom\";\n\n const labelElement = label != null\n ? (\n <label className={styles.osdkFormFieldLabel} htmlFor={fieldKey}>\n {label}\n {isRequired === true && (\n <span className={styles.osdkFormFieldRequired} aria-label=\"required\">\n {\" \"}\n *\n </span>\n )}\n </label>\n )\n : null;\n\n return (\n <div className={styles.osdkFormField} onBlur={onBlur}>\n {showTooltip\n ? (\n <div className={styles.osdkFormFieldLabelRow}>\n {labelElement}\n <InfoTip label={label}>{helperText}</InfoTip>\n </div>\n )\n : labelElement}\n {showBottomText && (\n <div className={styles.osdkFormFieldHelperText}>{helperText}</div>\n )}\n {children}\n {error != null && (\n
|
|
1
|
+
{"version":3,"file":"FormField.js","names":["Popover","InfoSign","React","memo","styles","FormField","fieldKey","label","isRequired","helperText","helperTextPlacement","error","onBlur","children","hasHelperText","labelElement","createElement","className","osdkFormFieldLabel","htmlFor","osdkFormFieldRequired","osdkFormField","osdkFormFieldLabelRow","InfoTip","osdkFormFieldHelperText","osdkFormFieldErrorSlot","osdkFormFieldError","role","Root","Trigger","render","osdkFormFieldInfoIcon","nativeButton","openOnHover","size","Portal","Positioner","sideOffset","Popup","osdkFormFieldInfoPopup"],"sources":["FormField.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 { Popover } from \"@base-ui/react/popover\";\nimport { InfoSign } from \"@blueprintjs/icons\";\nimport React, { memo } from \"react\";\nimport styles from \"./FormField.module.css\";\n\ninterface FormFieldProps {\n fieldKey: string;\n label?: string;\n isRequired?: boolean;\n helperText?: React.ReactNode;\n helperTextPlacement?: \"bottom\" | \"tooltip\";\n error?: string;\n onBlur?: (e: React.FocusEvent<HTMLDivElement>) => void;\n children: React.ReactNode;\n}\n\nexport const FormField: React.FC<FormFieldProps> = memo(function FormFieldFn({\n fieldKey,\n label,\n isRequired,\n helperText,\n helperTextPlacement = \"tooltip\",\n error,\n onBlur,\n children,\n}: FormFieldProps): React.ReactElement {\n const hasHelperText = helperText != null && helperText !== \"\";\n const showTooltip = hasHelperText && helperTextPlacement === \"tooltip\";\n const showBottomText = hasHelperText && helperTextPlacement === \"bottom\";\n\n const labelElement = label != null\n ? (\n <label className={styles.osdkFormFieldLabel} htmlFor={fieldKey}>\n {label}\n {isRequired === true && (\n <span className={styles.osdkFormFieldRequired} aria-label=\"required\">\n {\" \"}\n *\n </span>\n )}\n </label>\n )\n : null;\n\n return (\n <div className={styles.osdkFormField} onBlur={onBlur}>\n {showTooltip\n ? (\n <div className={styles.osdkFormFieldLabelRow}>\n {labelElement}\n <InfoTip label={label}>{helperText}</InfoTip>\n </div>\n )\n : labelElement}\n {showBottomText && (\n <div className={styles.osdkFormFieldHelperText}>{helperText}</div>\n )}\n {children}\n <div\n className={styles.osdkFormFieldErrorSlot}\n data-osdk-form-field-error-slot=\"\"\n >\n {error != null && (\n <div className={styles.osdkFormFieldError} role=\"alert\">\n {error}\n </div>\n )}\n </div>\n </div>\n );\n});\n\ninterface InfoTipProps {\n label?: string;\n children: React.ReactNode;\n}\n\n// Uses Popover (not Tooltip) because helper text may contain interactive\n// content like links that need focus management and keyboard navigation.\n// See https://base-ui.com/react/components/tooltip#infotips\nfunction InfoTip({ label, children }: InfoTipProps): React.ReactElement {\n return (\n <Popover.Root>\n <Popover.Trigger\n render={<span className={styles.osdkFormFieldInfoIcon} />}\n nativeButton={false}\n openOnHover={true}\n aria-label={label != null ? `Info about ${label}` : \"More information\"}\n >\n <InfoSign size={12} />\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Positioner sideOffset={4}>\n <Popover.Popup className={styles.osdkFormFieldInfoPopup}>\n {children}\n </Popover.Popup>\n </Popover.Positioner>\n </Popover.Portal>\n </Popover.Root>\n );\n}\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,OAAO,QAAQ,wBAAwB;AAChD,SAASC,QAAQ,QAAQ,oBAAoB;AAC7C,OAAOC,KAAK,IAAIC,IAAI,QAAQ,OAAO;AACnC,OAAOC,MAAM,MAAM,wBAAwB;AAa3C,OAAO,MAAMC,SAAmC,gBAAGF,IAAI,CAAC,UAAqB;EAC3EG,QAAQ;EACRC,KAAK;EACLC,UAAU;EACVC,UAAU;EACVC,mBAAmB,GAAG,SAAS;EAC/BC,KAAK;EACLC,MAAM;EACNC;AACc,CAAC,EAAsB;EACrC,MAAMC,aAAa,GAAGL,UAAU,IAAI,IAAI,IAAIA,UAAU,KAAK,EAAE;EAI7D,MAAMM,YAAY,GAAGR,KAAK,IAAI,IAAI,gBAE9BL,KAAA,CAAAc,aAAA;IAAOC,SAAS,EAAEb,MAAM,CAACc,kBAAmB;IAACC,OAAO,EAAEb;EAAS,GAC5DC,KAAK,EACLC,UAAU,KAAK,IAAI,iBAClBN,KAAA,CAAAc,aAAA;IAAMC,SAAS,EAAEb,MAAM,CAACgB,qBAAsB;IAAC,cAAW;EAAU,GACjE,GAAG,EAAC,GAED,CAEH,CAAC,GAER,IAAI;EAER,oBACElB,KAAA,CAAAc,aAAA;IAAKC,SAAS,EAAEb,MAAM,CAACiB,aAAc;IAACT,MAAM,EAAEA;EAAO,GAlBnCE,aAAa,IAAIJ,mBAAmB,KAAK,SAAS,gBAqB9DR,KAAA,CAAAc,aAAA;IAAKC,SAAS,EAAEb,MAAM,CAACkB;EAAsB,GAC1CP,YAAY,eACbb,KAAA,CAAAc,aAAA,CAACO,OAAO;IAAChB,KAAK,EAAEA;EAAM,GAAEE,UAAoB,CACzC,CAAC,GAENM,YAAY,EAzBGD,aAAa,IAAIJ,mBAAmB,KAAK,QAAQ,iBA2BlER,KAAA,CAAAc,aAAA;IAAKC,SAAS,EAAEb,MAAM,CAACoB;EAAwB,GAAEf,UAAgB,CAClE,EACAI,QAAQ,eACTX,KAAA,CAAAc,aAAA;IACEC,SAAS,EAAEb,MAAM,CAACqB,sBAAuB;IACzC,mCAAgC;EAAE,GAEjCd,KAAK,IAAI,IAAI,iBACZT,KAAA,CAAAc,aAAA;IAAKC,SAAS,EAAEb,MAAM,CAACsB,kBAAmB;IAACC,IAAI,EAAC;EAAO,GACpDhB,KACE,CAEJ,CACF,CAAC;AAEV,CAAC,CAAC;AAOF;AACA;AACA;AACA,SAASY,OAAOA,CAAC;EAAEhB,KAAK;EAAEM;AAAuB,CAAC,EAAsB;EACtE,oBACEX,KAAA,CAAAc,aAAA,CAAChB,OAAO,CAAC4B,IAAI,qBACX1B,KAAA,CAAAc,aAAA,CAAChB,OAAO,CAAC6B,OAAO;IACdC,MAAM,eAAE5B,KAAA,CAAAc,aAAA;MAAMC,SAAS,EAAEb,MAAM,CAAC2B;IAAsB,CAAE,CAAE;IAC1DC,YAAY,EAAE,KAAM;IACpBC,WAAW,EAAE,IAAK;IAClB,cAAY1B,KAAK,IAAI,IAAI,GAAG,cAAcA,KAAK,EAAE,GAAG;EAAmB,gBAEvEL,KAAA,CAAAc,aAAA,CAACf,QAAQ;IAACiC,IAAI,EAAE;EAAG,CAAE,CACN,CAAC,eAClBhC,KAAA,CAAAc,aAAA,CAAChB,OAAO,CAACmC,MAAM,qBACbjC,KAAA,CAAAc,aAAA,CAAChB,OAAO,CAACoC,UAAU;IAACC,UAAU,EAAE;EAAE,gBAChCnC,KAAA,CAAAc,aAAA,CAAChB,OAAO,CAACsC,KAAK;IAACrB,SAAS,EAAEb,MAAM,CAACmC;EAAuB,GACrD1B,QACY,CACG,CACN,CACJ,CAAC;AAEnB","ignoreList":[]}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
.osdkFormField {
|
|
18
18
|
display: flex;
|
|
19
19
|
flex-direction: column;
|
|
20
|
-
gap: var(--osdk-form-
|
|
20
|
+
gap: var(--osdk-form-field-gap);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
.osdkFormFieldLabel {
|
|
@@ -32,9 +32,14 @@
|
|
|
32
32
|
|
|
33
33
|
.osdkFormFieldError {
|
|
34
34
|
font-size: var(--osdk-form-error-font-size);
|
|
35
|
+
line-height: var(--osdk-form-error-line-height);
|
|
35
36
|
color: var(--osdk-form-error-color);
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
.osdkFormFieldErrorSlot {
|
|
40
|
+
min-block-size: var(--osdk-form-error-reserved-block-size);
|
|
41
|
+
}
|
|
42
|
+
|
|
38
43
|
.osdkFormFieldLabelRow {
|
|
39
44
|
display: flex;
|
|
40
45
|
align-items: center;
|
|
@@ -4,6 +4,7 @@ const styles = {
|
|
|
4
4
|
"osdkFormFieldLabel": "FormField-module__osdkFormFieldLabel___S9J-yCFD",
|
|
5
5
|
"osdkFormFieldRequired": "FormField-module__osdkFormFieldRequired___O0-L5TM8",
|
|
6
6
|
"osdkFormFieldError": "FormField-module__osdkFormFieldError___VYf8-K5I",
|
|
7
|
+
"osdkFormFieldErrorSlot": "FormField-module__osdkFormFieldErrorSlot___6kJW7FnJ",
|
|
7
8
|
"osdkFormFieldLabelRow": "FormField-module__osdkFormFieldLabelRow___RXG0mixo",
|
|
8
9
|
"osdkFormFieldInfoIcon": "FormField-module__osdkFormFieldInfoIcon___p4UK4WxM",
|
|
9
10
|
"osdkFormFieldInfoPopup": "FormField-module__osdkFormFieldInfoPopup___vSWWPRsu",
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* A form field definition specifies configuration for a single field
|
|
18
|
+
* A form field definition specifies configuration for a single field.
|
|
19
|
+
* Implemented as a distributed mapped type so `fieldComponent` narrows
|
|
20
|
+
* `fieldComponentProps` to the matching component prop type.
|
|
19
21
|
*/
|
|
20
22
|
|
|
21
23
|
/**
|
|
@@ -64,6 +66,10 @@ export const EMPTY_RANGE = [null, null];
|
|
|
64
66
|
* Radio buttons field props
|
|
65
67
|
*/
|
|
66
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Switch field props for boolean values.
|
|
71
|
+
*/
|
|
72
|
+
|
|
67
73
|
/**
|
|
68
74
|
* Option interface for radio button options
|
|
69
75
|
*/
|