@persona/design-system 0.8.0 → 0.8.1
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/CHANGELOG.md +241 -0
- package/dist/Accordion.d.mts +1 -1
- package/dist/AccordionItem.d.mts +1 -1
- package/dist/{Action-B-AiHknZ.d.mts → Action-BwYS9qaG.d.mts} +3 -3
- package/dist/Action.d.mts +1 -1
- package/dist/AdvancedFilterRuleRow.d.mts +4 -2
- package/dist/AdvancedFilterRulesPopover.d.mts +5 -3
- package/dist/ArrayValueControl.d.mts +1 -1
- package/dist/Attribute.d.mts +3 -3
- package/dist/{Badge-COqUjFQu.mjs → Badge-D-5tbZDw.mjs} +2 -2
- package/dist/{Badge-COqUjFQu.mjs.map → Badge-D-5tbZDw.mjs.map} +1 -1
- package/dist/BooleanValueControl.d.mts +1 -1
- package/dist/{Breadcrumb-DRFY46ZW.d.mts → Breadcrumb-BADja8tn.d.mts} +1 -1
- package/dist/Breadcrumb.d.mts +1 -1
- package/dist/{Breadcrumbs-DXS7rU7_.mjs → Breadcrumbs-CNpM0aXm.mjs} +5 -5
- package/dist/{Breadcrumbs-DXS7rU7_.mjs.map → Breadcrumbs-CNpM0aXm.mjs.map} +1 -1
- package/dist/{Breadcrumbs-DUSbT1I7.d.mts → Breadcrumbs-CxP7ktfM.d.mts} +2 -2
- package/dist/Breadcrumbs.d.mts +1 -1
- package/dist/{Button-xZ6DC5XC.d.mts → Button-CnswHEJ2.d.mts} +4 -4
- package/dist/Button.d.mts +1 -1
- package/dist/{Calendar-dPmo2dkj.d.mts → Calendar-Cke5IlMI.d.mts} +1 -1
- package/dist/Calendar.d.mts +1 -1
- package/dist/CalendarBase.d.mts +1 -1
- package/dist/{Card-CUeM8Lh8.d.mts → Card-Bp6L08H4.d.mts} +3 -3
- package/dist/Card.d.mts +1 -1
- package/dist/{CardV2-D9p7D7jX.mjs → CardV2-DEW6mw_o.mjs} +7 -7
- package/dist/{CardV2-D9p7D7jX.mjs.map → CardV2-DEW6mw_o.mjs.map} +1 -1
- package/dist/{Checkbox-DoJpxPEz.d.mts → Checkbox-DUXws1Os.d.mts} +1 -1
- package/dist/{Checkbox-DQynkc_I.mjs → Checkbox-GibG2pg5.mjs} +3 -3
- package/dist/{Checkbox-DQynkc_I.mjs.map → Checkbox-GibG2pg5.mjs.map} +1 -1
- package/dist/Checkbox.d.mts +1 -1
- package/dist/CheckboxGroupField-DzdOYIjo.d.mts +25 -0
- package/dist/CheckboxGroupField.d.mts +2 -25
- package/dist/ChoicesValueControl.d.mts +1 -1
- package/dist/{Combobox-C_kCY3P3.mjs → Combobox-CCDoNF9Y.mjs} +9 -9
- package/dist/{Combobox-C_kCY3P3.mjs.map → Combobox-CCDoNF9Y.mjs.map} +1 -1
- package/dist/{Combobox-D7hyf-jA.d.mts → Combobox-CnxmKUQf.d.mts} +3 -3
- package/dist/Combobox.d.mts +2 -2
- package/dist/{ComboboxBase-BMCY6O7Y.d.mts → ComboboxBase-CtNrsPO9.d.mts} +6 -6
- package/dist/ComboboxBase.d.mts +1 -1
- package/dist/{ComboboxMultiSelect-L0KYMkmm.d.mts → ComboboxMultiSelect-CMH6iVu4.d.mts} +2 -2
- package/dist/ComboboxMultiSelect.d.mts +1 -1
- package/dist/{ComboboxSingleSelect-v5oNrJ7M.d.mts → ComboboxSingleSelect-BLPbLmMY.d.mts} +4 -4
- package/dist/ComboboxSingleSelect.d.mts +1 -1
- package/dist/{CompactBar-DjFaUAsN.d.mts → CompactBar-BwKIIlWz.d.mts} +3 -3
- package/dist/CompactBar.d.mts +1 -1
- package/dist/{ConfigFormGroup-DLOZOuLf.mjs → ConfigFormGroup-BQXN2Pgj.mjs} +2 -2
- package/dist/{ConfigFormGroup-DLOZOuLf.mjs.map → ConfigFormGroup-BQXN2Pgj.mjs.map} +1 -1
- package/dist/{ControlBar-Cegjxa6-.d.mts → ControlBar-BJUY6GOX.d.mts} +2 -2
- package/dist/ControlBar.d.mts +1 -1
- package/dist/DataTable.d.mts +3 -3
- package/dist/{DateField-Dk5ykLdr.d.mts → DateField-BojOHfrv.d.mts} +2 -2
- package/dist/DateField.d.mts +1 -1
- package/dist/{DatePicker-Dtvv0V45.d.mts → DatePicker-BHVx_i_F.d.mts} +2 -2
- package/dist/{DatePicker-C7z1yodK.mjs → DatePicker-LPIJrc0n.mjs} +6 -6
- package/dist/{DatePicker-C7z1yodK.mjs.map → DatePicker-LPIJrc0n.mjs.map} +1 -1
- package/dist/DatePicker.d.mts +1 -1
- package/dist/{DateRangePicker-HPYsa4wC.d.mts → DateRangePicker-CelDK_44.d.mts} +3 -3
- package/dist/DateRangePicker.d.mts +1 -1
- package/dist/DateRangeValueControl.d.mts +2 -2
- package/dist/DateValueControl.d.mts +1 -1
- package/dist/{DropdownButton-CQrFHOIW.mjs → DropdownButton-i5Dmxiq1.mjs} +3 -3
- package/dist/{DropdownButton-CQrFHOIW.mjs.map → DropdownButton-i5Dmxiq1.mjs.map} +1 -1
- package/dist/DropdownButton.d.mts +2 -2
- package/dist/{DropdownMenu-D1qvgGTZ.d.mts → DropdownMenu-YtLxcNWt.d.mts} +2 -2
- package/dist/{DropdownMenu-rm9Nnxn7.mjs → DropdownMenu-j8NWbAvM.mjs} +2 -2
- package/dist/{DropdownMenu-rm9Nnxn7.mjs.map → DropdownMenu-j8NWbAvM.mjs.map} +1 -1
- package/dist/DropdownMenu.d.mts +1 -1
- package/dist/{ErrorProps-B8-Mqf1W.d.mts → ErrorProps-6dRdJ4QQ.d.mts} +1 -1
- package/dist/ErrorProps.d.mts +1 -1
- package/dist/{FieldRegistry-0LmSQ-jc.d.mts → FieldRegistry-DqO8HiYb.d.mts} +2 -2
- package/dist/FieldRegistry.d.mts +1 -1
- package/dist/{FilterBar-BMM4Swbt.d.mts → FilterBar-CpAA2Ozk.d.mts} +4 -4
- package/dist/FilterBar.d.mts +1 -1
- package/dist/FilterPickerMenu.d.mts +2 -2
- package/dist/FilterPill.d.mts +1 -1
- package/dist/FilterPopover.d.mts +8 -2
- package/dist/FloatValueControl.d.mts +1 -1
- package/dist/{FormControl-Dg8doZq2.d.mts → FormControl-B-s6G9mp.d.mts} +2 -2
- package/dist/{FormControl-DXrxoJLl.mjs → FormControl-bDxFF0hl.mjs} +3 -3
- package/dist/{FormControl-DXrxoJLl.mjs.map → FormControl-bDxFF0hl.mjs.map} +1 -1
- package/dist/FormControl.d.mts +1 -1
- package/dist/FormControlLabel.d.mts +1 -1
- package/dist/{FormField-BeLigf9j.d.mts → FormField-D3k-f3-f.d.mts} +2 -2
- package/dist/{FormField-Crp3F-hv.mjs → FormField-DbcqNcx2.mjs} +16 -16
- package/dist/{FormField-Crp3F-hv.mjs.map → FormField-DbcqNcx2.mjs.map} +1 -1
- package/dist/FormField.d.mts +1 -1
- package/dist/{Grid-eMLuyRzV.mjs → Grid-CeH9E5Ai.mjs} +1 -1
- package/dist/{Grid-eMLuyRzV.mjs.map → Grid-CeH9E5Ai.mjs.map} +1 -1
- package/dist/{Header-DxJ6TfPw.d.mts → Header-2K49LYkR.d.mts} +1 -1
- package/dist/Header.d.mts +1 -1
- package/dist/{HelperTooltip-DcyrpEZI.d.mts → HelperTooltip-CTHUM2nC.d.mts} +2 -2
- package/dist/HelperTooltip.d.mts +1 -1
- package/dist/HighlightedText.d.mts +61 -0
- package/dist/{HoverCopyableField-12bBuG-d.mjs → HoverCopyableField-BARZLhfO.mjs} +3 -3
- package/dist/{HoverCopyableField-12bBuG-d.mjs.map → HoverCopyableField-BARZLhfO.mjs.map} +1 -1
- package/dist/{IconButton-CCLMYWVN.mjs → IconButton-BHFCjvzs.mjs} +1 -1
- package/dist/{IconButton-CCLMYWVN.mjs.map → IconButton-BHFCjvzs.mjs.map} +1 -1
- package/dist/{IconButton-BUMMN-gH.d.mts → IconButton-D5hx405r.d.mts} +2 -2
- package/dist/IconButton.d.mts +1 -1
- package/dist/ImageTile.d.mts +1 -1
- package/dist/InlineCombobox.d.mts +1 -1
- package/dist/InlineInput.d.mts +1 -1
- package/dist/{Input-Cl4o41k4.mjs → Input-BQN97Hzm.mjs} +3 -3
- package/dist/{Input-Cl4o41k4.mjs.map → Input-BQN97Hzm.mjs.map} +1 -1
- package/dist/{Input-2N2e5JCf.d.mts → Input-BQbcIiVj.d.mts} +3 -3
- package/dist/Input.d.mts +1 -1
- package/dist/{InputProps-TWzig3QO.d.mts → InputProps-DT1ZReZS.d.mts} +2 -2
- package/dist/InputProps.d.mts +1 -1
- package/dist/IntegerValueControl.d.mts +1 -1
- package/dist/{Link-I9Bklen-.mjs → Link-Bzm4AL5J.mjs} +1 -1
- package/dist/{Link-I9Bklen-.mjs.map → Link-Bzm4AL5J.mjs.map} +1 -1
- package/dist/Link.d.mts +1 -1
- package/dist/{ListBox-BcoXOt73.d.mts → ListBox-CdqRwBvA.d.mts} +7 -7
- package/dist/{ListBox-sqeLBiKS.mjs → ListBox-DOqN9DNl.mjs} +9 -9
- package/dist/{ListBox-sqeLBiKS.mjs.map → ListBox-DOqN9DNl.mjs.map} +1 -1
- package/dist/ListBox.d.mts +1 -1
- package/dist/ListBoxField-Bl2WLplO.d.mts +51 -0
- package/dist/ListBoxField.d.mts +2 -51
- package/dist/{LoadingShimmer-dRSkdlqD.mjs → LoadingShimmer-Ds7rvIUN.mjs} +1 -1
- package/dist/{LoadingShimmer-dRSkdlqD.mjs.map → LoadingShimmer-Ds7rvIUN.mjs.map} +1 -1
- package/dist/LoadingShimmer.d.mts +1 -1
- package/dist/{LogicRow-DXywXdYt.d.mts → LogicRow-CwMAn1sh.d.mts} +3 -3
- package/dist/LogicRow.d.mts +1 -1
- package/dist/MaskedInput.d.mts +1 -1
- package/dist/{Menu-BekLwm8w.d.mts → Menu-CUN9bmc1.d.mts} +3 -3
- package/dist/{Menu-CwlI7BMN.mjs → Menu-DjW2b3Wk.mjs} +1 -1
- package/dist/{Menu-CwlI7BMN.mjs.map → Menu-DjW2b3Wk.mjs.map} +1 -1
- package/dist/Menu.d.mts +1 -1
- package/dist/{MiddleTruncatedText-CO58jrNF.mjs → MiddleTruncatedText-DoTyfMem.mjs} +2 -2
- package/dist/{MiddleTruncatedText-CO58jrNF.mjs.map → MiddleTruncatedText-DoTyfMem.mjs.map} +1 -1
- package/dist/{Modal-ymxlGYKt.d.mts → Modal-CGXJGrKg.d.mts} +2 -2
- package/dist/{Modal-CMiFcXC9.mjs → Modal-DHLPK65-.mjs} +4 -4
- package/dist/{Modal-CMiFcXC9.mjs.map → Modal-DHLPK65-.mjs.map} +1 -1
- package/dist/Modal.d.mts +1 -1
- package/dist/{PageHeader-D_0p7UK_.mjs → PageHeader-eI4RM_uL.mjs} +2 -2
- package/dist/{PageHeader-D_0p7UK_.mjs.map → PageHeader-eI4RM_uL.mjs.map} +1 -1
- package/dist/PageHeader.d.mts +1 -1
- package/dist/{PageSelector-Bxulu6vU.d.mts → PageSelector-kAfYxEky.d.mts} +3 -3
- package/dist/PageSelector.d.mts +1 -1
- package/dist/{Pagination-Co9CfyFQ.mjs → Pagination-6BDOn9bX.mjs} +6 -6
- package/dist/Pagination-6BDOn9bX.mjs.map +1 -0
- package/dist/{Pagination-Dg-4O7F7.d.mts → Pagination-Bhr7xyd2.d.mts} +2 -2
- package/dist/Pagination.d.mts +1 -1
- package/dist/{Pii-JGV9gP95.mjs → Pii-DhL1gblz.mjs} +2 -2
- package/dist/{Pii-JGV9gP95.mjs.map → Pii-DhL1gblz.mjs.map} +1 -1
- package/dist/{PillShell-BA7KK1zS.d.mts → PillShell-CVJL1k5I.d.mts} +2 -2
- package/dist/PillShell.d.mts +1 -1
- package/dist/{Popover-ZAj03lws.mjs → Popover-CbYaWrAy.mjs} +1 -1
- package/dist/{Popover-ZAj03lws.mjs.map → Popover-CbYaWrAy.mjs.map} +1 -1
- package/dist/{ProgressIndicator-CQg08vuA.mjs → ProgressIndicator-BpF3XLn3.mjs} +1 -1
- package/dist/{ProgressIndicator-CQg08vuA.mjs.map → ProgressIndicator-BpF3XLn3.mjs.map} +1 -1
- package/dist/{ProgressIndicator-D85HQGSx.d.mts → ProgressIndicator-CYyM6OSx.d.mts} +1 -1
- package/dist/ProgressIndicator.d.mts +1 -1
- package/dist/{PseudoClassProps-BHs8TX_3.d.mts → PseudoClassProps-BOVN6Etr.d.mts} +1 -1
- package/dist/PseudoClassProps.d.mts +1 -1
- package/dist/{Radio-CYV290JI.mjs → Radio-DPaX-9LH.mjs} +2 -2
- package/dist/{Radio-CYV290JI.mjs.map → Radio-DPaX-9LH.mjs.map} +1 -1
- package/dist/{RadioGroup-Cq3KV1TN.d.mts → RadioGroup-C0l0pdEt.d.mts} +1 -1
- package/dist/{RadioGroup-lWMMtu9V.mjs → RadioGroup-D7f4m2Uc.mjs} +2 -2
- package/dist/{RadioGroup-lWMMtu9V.mjs.map → RadioGroup-D7f4m2Uc.mjs.map} +1 -1
- package/dist/RadioGroup.d.mts +1 -1
- package/dist/{RangeCalendar-Mh7h74Tp.d.mts → RangeCalendar-BJn9V3iN.d.mts} +2 -2
- package/dist/RangeCalendar.d.mts +1 -1
- package/dist/RangeCalendarPresets.d.mts +1 -1
- package/dist/{RouterContext-B3IU1jb0.d.mts → RouterContext-BLrzYlJ_.d.mts} +2 -2
- package/dist/RouterContext.d.mts +1 -1
- package/dist/{RouterLink-CwAqTLC2.d.mts → RouterLink-BHXjhqps.d.mts} +2 -2
- package/dist/RouterLink.d.mts +1 -1
- package/dist/RuleEditorFields.d.mts +4 -2
- package/dist/RulesPill.d.mts +1 -1
- package/dist/{SearchInput-BGyUUcoz.d.mts → SearchInput-Buh8LdIL.d.mts} +2 -2
- package/dist/SearchInput.d.mts +1 -1
- package/dist/SectionHeading.d.mts +1 -1
- package/dist/{SegmentedControl-DgDabSgr.d.mts → SegmentedControl-B9qLyIIW.d.mts} +1 -1
- package/dist/{SegmentedControl-BEbIcV3g.mjs → SegmentedControl-zEvBtVj0.mjs} +2 -2
- package/dist/{SegmentedControl-BEbIcV3g.mjs.map → SegmentedControl-zEvBtVj0.mjs.map} +1 -1
- package/dist/SegmentedControl.d.mts +1 -1
- package/dist/{Select-yC2t_gZb.mjs → Select-BoZuM_e9.mjs} +6 -6
- package/dist/{Select-yC2t_gZb.mjs.map → Select-BoZuM_e9.mjs.map} +1 -1
- package/dist/{Select-wqTtGyga.d.mts → Select-Cv_9PLOt.d.mts} +3 -3
- package/dist/Select.d.mts +1 -1
- package/dist/SmartTextInput.d.mts +107 -0
- package/dist/SmartTextInputCodeDialog.d.mts +18 -0
- package/dist/SmartTextInputField.d.mts +25 -0
- package/dist/SmartTextInputFunctionDialog.d.mts +37 -0
- package/dist/SmartTextInputListbox.d.mts +26 -0
- package/dist/SmartTextInputPopover.d.mts +45 -0
- package/dist/{Spinner-BlAg8_OX.mjs → Spinner-CarSRiBF.mjs} +1 -1
- package/dist/{Spinner-BlAg8_OX.mjs.map → Spinner-CarSRiBF.mjs.map} +1 -1
- package/dist/{Stack-Bkn0TUDe.mjs → Stack-CEPzs4Pb.mjs} +1 -1
- package/dist/{Stack-Bkn0TUDe.mjs.map → Stack-CEPzs4Pb.mjs.map} +1 -1
- package/dist/{Stack-CYqjBXe8.d.mts → Stack-XzBzPvSV.d.mts} +1 -1
- package/dist/Stack.d.mts +1 -1
- package/dist/{StatusIndicator-DT2zNbkp.mjs → StatusIndicator-bEnMWV_S.mjs} +1 -1
- package/dist/{StatusIndicator-DT2zNbkp.mjs.map → StatusIndicator-bEnMWV_S.mjs.map} +1 -1
- package/dist/{Sticker-BLbgJxcH.mjs → Sticker-B-fU8lgu.mjs} +3 -3
- package/dist/{Sticker-BLbgJxcH.mjs.map → Sticker-B-fU8lgu.mjs.map} +1 -1
- package/dist/{Sticker-BmyKaxwx.d.mts → Sticker-DGfNuxUK.d.mts} +4 -4
- package/dist/Sticker.d.mts +1 -1
- package/dist/StringValueControl.d.mts +1 -1
- package/dist/Tab.d.mts +1 -1
- package/dist/{TabBar-Bj84q1Mr.mjs → TabBar-BSl5v5aa.mjs} +3 -3
- package/dist/{TabBar-Bj84q1Mr.mjs.map → TabBar-BSl5v5aa.mjs.map} +1 -1
- package/dist/{Table-DhdHUQ8V.d.mts → Table-B2V5tlfA.d.mts} +1 -1
- package/dist/{Table-WqNfjasd.mjs → Table-msXj0glu.mjs} +2 -2
- package/dist/{Table-WqNfjasd.mjs.map → Table-msXj0glu.mjs.map} +1 -1
- package/dist/Table.d.mts +1 -1
- package/dist/{TableBody-qoSvQDds.d.mts → TableBody-SlQe4Jyp.d.mts} +1 -1
- package/dist/TableBody.d.mts +1 -1
- package/dist/{TableBox-obl64W5Y.mjs → TableBox-CF1_Fk0j.mjs} +9 -9
- package/dist/{TableBox-obl64W5Y.mjs.map → TableBox-CF1_Fk0j.mjs.map} +1 -1
- package/dist/TableBox.d.mts +2 -2
- package/dist/{TableBoxCell-DzYMx4Ju.d.mts → TableBoxCell-BRhGeUnO.d.mts} +6 -6
- package/dist/TableBoxCell.d.mts +1 -1
- package/dist/TableBoxField-Cq9M1upV.d.mts +103 -0
- package/dist/TableBoxField.d.mts +2 -103
- package/dist/{TableBoxRow-B4rFCvWK.d.mts → TableBoxRow-DZzRYoID.d.mts} +3 -3
- package/dist/TableBoxRow.d.mts +1 -1
- package/dist/{TableBoxRowActions-qMKcVuTL.d.mts → TableBoxRowActions-4-j3flJq.d.mts} +2 -2
- package/dist/TableBoxRowActions.d.mts +1 -1
- package/dist/{TableCell-CGPQRc5g.d.mts → TableCell-D5Sqb6iO.d.mts} +2 -2
- package/dist/TableCell.d.mts +1 -1
- package/dist/{TableControls-WP78qtET.d.mts → TableControls-B-LakH-8.d.mts} +3 -3
- package/dist/{TableControls-RS_ozBsI.mjs → TableControls-CqW_nyBY.mjs} +98 -31
- package/dist/TableControls-CqW_nyBY.mjs.map +1 -0
- package/dist/TableControls.d.mts +1 -1
- package/dist/{TableControlsContext-DZIZSyfX.d.mts → TableControlsContext-Dh1YVmBM.d.mts} +2 -2
- package/dist/TableControlsContext.d.mts +1 -1
- package/dist/{TableHead-36j-_oyn.d.mts → TableHead-BCrVa0BY.d.mts} +1 -1
- package/dist/TableHead.d.mts +1 -1
- package/dist/{TableHeaderCell-C7gp9j1X.d.mts → TableHeaderCell-CcEkDozs.d.mts} +1 -1
- package/dist/TableHeaderCell.d.mts +1 -1
- package/dist/{TableLayout-CQqIV0vj.d.mts → TableLayout-Bhj1QBBz.d.mts} +1 -1
- package/dist/TableLayout.d.mts +1 -1
- package/dist/{TableRow-BJZM8I8i.d.mts → TableRow-Cy1y7b9S.d.mts} +2 -2
- package/dist/TableRow.d.mts +1 -1
- package/dist/TableTH.d.mts +1 -1
- package/dist/{TableViewConfigurationDropdown-Dwy_9FBz.d.mts → TableViewConfigurationDropdown-BzygLtGm.d.mts} +2 -2
- package/dist/TableViewConfigurationDropdown.d.mts +1 -1
- package/dist/{TechnicalSticker-CL0zkOAj.mjs → TechnicalSticker-B6T7cHHc.mjs} +2 -2
- package/dist/{TechnicalSticker-CL0zkOAj.mjs.map → TechnicalSticker-B6T7cHHc.mjs.map} +1 -1
- package/dist/{Text-DbtTa83E.d.mts → Text-BVGJ-Nlw.d.mts} +3 -3
- package/dist/Text.d.mts +1 -1
- package/dist/{TextArea-CbxF6u7z.d.mts → TextArea-Bzj593VO.d.mts} +2 -2
- package/dist/{TextArea-CfZr5Sk4.mjs → TextArea-C1CmFRiz.mjs} +2 -2
- package/dist/{TextArea-CfZr5Sk4.mjs.map → TextArea-C1CmFRiz.mjs.map} +1 -1
- package/dist/TextArea.d.mts +1 -1
- package/dist/{TextUnderlineTooltip-BgLQuK38.d.mts → TextUnderlineTooltip-CgFmtqF_.d.mts} +2 -2
- package/dist/TextUnderlineTooltip.d.mts +1 -1
- package/dist/Tile.d.mts +1 -1
- package/dist/Toast.d.mts +1 -1
- package/dist/{Toggle-D4ZaUcVt.mjs → Toggle-CntyMUPJ.mjs} +2 -2
- package/dist/{Toggle-D4ZaUcVt.mjs.map → Toggle-CntyMUPJ.mjs.map} +1 -1
- package/dist/{Toggle-BYMLrPXk.d.mts → Toggle-bSu1xAaq.d.mts} +1 -1
- package/dist/Toggle.d.mts +1 -1
- package/dist/{Tooltip-4pshzB_i.d.mts → Tooltip-Duw4Fz1t.d.mts} +2 -2
- package/dist/Tooltip.d.mts +1 -1
- package/dist/{TruncatedText-O7hE3w0O.d.mts → TruncatedText-CbTpX_R1.d.mts} +1 -1
- package/dist/VersionHistory.d.mts +1 -1
- package/dist/{VersionHistoryItem-CIcEgl0K.d.mts → VersionHistoryItem-D05QYej7.d.mts} +1 -1
- package/dist/VersionHistoryItem.d.mts +1 -1
- package/dist/WizardModal.d.mts +3 -3
- package/dist/{accordionTitleTypography-CNB1w3kn.d.mts → accordionTitleTypography-Leehcmb3.d.mts} +2 -2
- package/dist/accordionTitleTypography.d.mts +1 -1
- package/dist/chainTypes-D8SGRGba.d.mts +17 -0
- package/dist/{codec-BXVBsB8Y.d.mts → codec-Vsztf4fe.d.mts} +2 -2
- package/dist/codec.d.mts +1 -1
- package/dist/{color-3UO63ocQ.d.mts → color-CrlF3pba.d.mts} +2 -2
- package/dist/components/Accordion/index.d.mts +1 -1
- package/dist/components/Accordion/index.mjs +1 -1
- package/dist/components/Attribute/index.mjs +2 -2
- package/dist/components/Badge/index.mjs +1 -1
- package/dist/components/Banner/index.mjs +1 -1
- package/dist/components/BottomPanel/index.mjs +3 -3
- package/dist/components/Breadcrumbs/index.d.mts +1 -1
- package/dist/components/Breadcrumbs/index.mjs +1 -1
- package/dist/components/Button/index.d.mts +2 -2
- package/dist/components/Button/index.mjs +1 -1
- package/dist/components/ButtonGroup/index.mjs +2 -2
- package/dist/components/Card/index.d.mts +2 -2
- package/dist/components/CardV2/index.d.mts +1 -1
- package/dist/components/CardV2/index.mjs +1 -1
- package/dist/components/Checkbox/index.d.mts +1 -1
- package/dist/components/Checkbox/index.mjs +1 -1
- package/dist/components/CodeHighlight/index.mjs +1 -1
- package/dist/components/Combobox/index.d.mts +2 -2
- package/dist/components/Combobox/index.mjs +1 -1
- package/dist/components/ConfigFormGroup/index.mjs +2 -2
- package/dist/components/DataTable/TableControls/index.d.mts +19 -19
- package/dist/components/DataTable/TableControls/index.mjs +1 -1
- package/dist/components/DataTable/index.mjs +11 -11
- package/dist/components/DataTable/types.d.mts +2 -2
- package/dist/components/DatePicker/index.d.mts +5 -5
- package/dist/components/DatePicker/index.mjs +1 -1
- package/dist/components/DropdownButton/index.mjs +1 -1
- package/dist/components/DropdownMenu/index.d.mts +1 -1
- package/dist/components/DropdownMenu/index.mjs +1 -1
- package/dist/components/FloatingPanel/index.mjs +2 -2
- package/dist/components/FormControl/index.d.mts +2 -2
- package/dist/components/FormControl/index.mjs +2 -2
- package/dist/components/FormField/index.d.mts +6 -6
- package/dist/components/FormField/index.mjs +1 -1
- package/dist/components/Grid/index.mjs +1 -1
- package/dist/components/HoverCopyableField/index.mjs +1 -1
- package/dist/components/ImageTile/index.mjs +5 -5
- package/dist/components/Input/index.d.mts +1 -1
- package/dist/components/Input/index.mjs +1 -1
- package/dist/components/Link/index.mjs +1 -1
- package/dist/components/ListBox/index.d.mts +3 -3
- package/dist/components/ListBox/index.mjs +1 -1
- package/dist/components/LoadingShimmer/index.mjs +1 -1
- package/dist/components/MaskedInput/index.mjs +1 -1
- package/dist/components/Menu/index.d.mts +1 -1
- package/dist/components/Menu/index.mjs +1 -1
- package/dist/components/Modal/index.d.mts +1 -1
- package/dist/components/Modal/index.mjs +1 -1
- package/dist/components/PageHeader/index.mjs +1 -1
- package/dist/components/Pagination/index.d.mts +3 -3
- package/dist/components/Pagination/index.mjs +1 -1
- package/dist/components/Pii/index.mjs +1 -1
- package/dist/components/Popover/index.mjs +1 -1
- package/dist/components/ProgressIndicator/index.d.mts +1 -1
- package/dist/components/ProgressIndicator/index.mjs +1 -1
- package/dist/components/Radio/index.mjs +1 -1
- package/dist/components/RadioGroup/index.d.mts +1 -1
- package/dist/components/RadioGroup/index.mjs +1 -1
- package/dist/components/RightPanel/index.mjs +3 -3
- package/dist/components/SegmentedControl/index.d.mts +1 -1
- package/dist/components/SegmentedControl/index.mjs +1 -1
- package/dist/components/Select/index.d.mts +1 -1
- package/dist/components/Select/index.mjs +1 -1
- package/dist/components/SmartTextInput/index.d.mts +5 -0
- package/dist/components/SmartTextInput/index.mjs +2035 -0
- package/dist/components/SmartTextInput/index.mjs.map +1 -0
- package/dist/components/SmartTextInput/parser/method-chain/parser.mjs +1 -1
- package/dist/components/SmartTextInput/parser/method-chain/types.d.mts +1 -1
- package/dist/components/SmartTextInput/parser/smart-text/parser.mjs +1 -1
- package/dist/components/SmartTextInput/parser/smart-text/types.d.mts +3 -72
- package/dist/components/Spinner/index.mjs +1 -1
- package/dist/components/Stack/index.d.mts +1 -1
- package/dist/components/Stack/index.mjs +1 -1
- package/dist/components/StatusIndicator/index.mjs +1 -1
- package/dist/components/Sticker/index.d.mts +1 -1
- package/dist/components/Sticker/index.mjs +1 -1
- package/dist/components/TabBar/index.mjs +1 -1
- package/dist/components/Table/index.d.mts +8 -8
- package/dist/components/Table/index.mjs +1 -1
- package/dist/components/TableBox/index.d.mts +2 -2
- package/dist/components/TableBox/index.mjs +1 -1
- package/dist/components/TechnicalSticker/index.mjs +1 -1
- package/dist/components/Text/index.d.mts +1 -1
- package/dist/components/TextArea/index.d.mts +1 -1
- package/dist/components/TextArea/index.mjs +1 -1
- package/dist/components/Tile/index.mjs +2 -2
- package/dist/components/Toast/index.mjs +1 -1
- package/dist/components/Toggle/index.d.mts +1 -1
- package/dist/components/Toggle/index.mjs +1 -1
- package/dist/components/Tooltip/index.d.mts +3 -3
- package/dist/components/VersionHistory/index.d.mts +1 -1
- package/dist/components/VersionHistory/index.mjs +7 -7
- package/dist/compound-expression.d.mts +1 -1
- package/dist/{constants-BOxzLX-O.d.mts → constants-CQUCM6__.d.mts} +1 -1
- package/dist/constants.d.mts +1 -1
- package/dist/{createPath-OeTC9kvS.d.mts → createPath-Bq7wYGt_.d.mts} +2 -2
- package/dist/createPath.d.mts +1 -1
- package/dist/{date-filter-BnzR6NxT.mjs → date-filter-D6IfCkwp.mjs} +1 -1
- package/dist/{date-filter-BnzR6NxT.mjs.map → date-filter-D6IfCkwp.mjs.map} +1 -1
- package/dist/{date-range-rule-value-BRp5Bi7R.d.mts → date-range-rule-value-DVhMQP4-.d.mts} +2 -2
- package/dist/date-range-rule-value.d.mts +1 -1
- package/dist/{date-rule-intent-CDBtV0ET.d.mts → date-rule-intent-BwQ6OTVD.d.mts} +3 -3
- package/dist/date-rule-intent.d.mts +1 -1
- package/dist/display.d.mts +1 -1
- package/dist/fieldPickerOptions.d.mts +2 -2
- package/dist/{filter-size-context-CqvQ190x.d.mts → filter-size-context-BjTzcZwZ.d.mts} +2 -2
- package/dist/filter-size-context.d.mts +1 -1
- package/dist/helpers.d.mts +1 -1
- package/dist/{index-BXSe73Xn.d.mts → index-BFIFjR7Q.d.mts} +2 -2
- package/dist/{index-wKK9f9La.d.mts → index-BhDvrF4l.d.mts} +4 -4
- package/dist/{index-CyAok7As.d.mts → index-C-xpEL8b.d.mts} +2 -2
- package/dist/index-xmouCHX9.d.mts +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index2.d.mts +1 -1
- package/dist/index3.d.mts +3 -3
- package/dist/index4.d.mts +1 -1
- package/dist/index5.d.mts +14 -14
- package/dist/{input-C6cyiqm2.d.mts → input-DpHBIUpP.d.mts} +3 -3
- package/dist/inputFields-BVDurw3L.d.mts +71 -0
- package/dist/inputFields.d.mts +2 -71
- package/dist/{intersperse-Df9zw7Bk.mjs → intersperse-bvY2gibK.mjs} +1 -1
- package/dist/{intersperse-Df9zw7Bk.mjs.map → intersperse-bvY2gibK.mjs.map} +1 -1
- package/dist/{jsonSchema-CfGi1bzI.d.mts → jsonSchema-Bl-qzgrr.d.mts} +1 -1
- package/dist/lib/MiddleTruncatedText.mjs +1 -1
- package/dist/lib/PDSProvider.d.mts +2 -2
- package/dist/lib/TruncatedText.d.mts +1 -1
- package/dist/lib/TruncatedText.mjs +1 -1
- package/dist/lib/TruncatedText.mjs.map +1 -1
- package/dist/lib/TruncatedTextWithTooltip.d.mts +1 -1
- package/dist/lib/TruncatedTextWithTooltip.mjs +1 -1
- package/dist/lib/TruncatedTextWithTooltip.mjs.map +1 -1
- package/dist/lib/chainTypes.d.mts +2 -17
- package/dist/lib/color.d.mts +1 -1
- package/dist/lib/customFunctionSchema.d.mts +1 -1
- package/dist/lib/date-filter/index.d.mts +2 -2
- package/dist/lib/date-filter/index.mjs +1 -1
- package/dist/lib/jsonSchema.d.mts +1 -1
- package/dist/lib/jsonSchemaType.d.mts +1 -1
- package/dist/lib/message.d.mts +1 -1
- package/dist/lib/methodChain.d.mts +2 -2
- package/dist/lib/methodChain.mjs +1 -2
- package/dist/lib/methodChainNormalize.d.mts +2 -2
- package/dist/lib/methodChainTypes.d.mts +1 -1
- package/dist/lib/objectSchemaTypes.d.mts +1 -1
- package/dist/lib/platformObject.d.mts +1 -1
- package/dist/lib/pseudoClass.d.mts +1 -1
- package/dist/lib/router/adapters/reactRouter.d.mts +1 -1
- package/dist/lib/router/adapters/tanstack.d.mts +1 -1
- package/dist/lib/router/index.d.mts +5 -5
- package/dist/lib/schemaOptions.d.mts +2 -173
- package/dist/lib/schemaOptions.mjs +1 -1
- package/dist/lib/semanticColor.d.mts +1 -1
- package/dist/lib/useChain.d.mts +2 -0
- package/dist/lib/useChain.mjs +2 -0
- package/dist/listbox-options-BjOkovND.d.mts +38 -0
- package/dist/listbox-options.d.mts +2 -0
- package/dist/{message-CblP0EjG.d.mts → message-w_1-kTDE.d.mts} +1 -1
- package/dist/{methodChain-Pk1C3i_E.d.mts → methodChain-B5vZEOff.d.mts} +4 -4
- package/dist/{methodChain-DAQxLgxt.mjs → methodChain-L_h8Z8Bx.mjs} +2 -2
- package/dist/{methodChain-DAQxLgxt.mjs.map → methodChain-L_h8Z8Bx.mjs.map} +1 -1
- package/dist/{methodChainTypes-CqWzfx0M.d.mts → methodChainTypes-BVkTI8MX.d.mts} +2 -2
- package/dist/mixins/focus.d.mts +1 -1
- package/dist/mixins/hoverable.d.mts +2 -2
- package/dist/mixins/input.d.mts +1 -1
- package/dist/mixins/menuItem.d.mts +2 -2
- package/dist/mixins/scrollbar.d.mts +1 -1
- package/dist/mixins/text.d.mts +1 -1
- package/dist/{operators-CoXL5Hv6.d.mts → operators-BG82-g3M.d.mts} +9 -3
- package/dist/operators.d.mts +2 -2
- package/dist/{palette-CxXUs1Fu.d.mts → palette-C8tyI81D.d.mts} +3 -3
- package/dist/palette.d.mts +1 -1
- package/dist/{parser-Kxos6siN.mjs → parser-BeTiVjRs.mjs} +3 -2
- package/dist/{parser-Kxos6siN.mjs.map → parser-BeTiVjRs.mjs.map} +1 -1
- package/dist/patterns/LayoutLoadingShimmer/index.mjs +5 -5
- package/dist/patterns/PageLayout/index.mjs +2 -2
- package/dist/{components → patterns}/WizardModal/index.mjs +5 -5
- package/dist/patterns/WizardModal/index.mjs.map +1 -0
- package/dist/reactRouterFallback.d.mts +1 -1
- package/dist/relative-date-label.d.mts +1 -1
- package/dist/safe-parse.d.mts +23 -0
- package/dist/schemaOptions-DGca6x7E.d.mts +173 -0
- package/dist/{semantic-CFMBsuiJ.d.mts → semantic-D1661f_6.d.mts} +1 -1
- package/dist/{semanticColor-DuJCmDrH.d.mts → semanticColor-Bg0H3RUL.d.mts} +3 -3
- package/dist/{text-D8HPjiEX.d.mts → text-Iw9DKpbZ.d.mts} +1 -1
- package/dist/{theme-BcaR-Au5.d.mts → theme-BB1B6Wkz.d.mts} +3 -3
- package/dist/theme.d.mts +1 -1
- package/dist/tone.d.mts +3 -3
- package/dist/tree.d.mts +9 -0
- package/dist/{types-CoVZwrMW.d.mts → types-B0ilOIfE.d.mts} +2 -2
- package/dist/types-BYRTxB0a.d.mts +72 -0
- package/dist/{types-BCiq4hGv.d.mts → types-CI2bPi02.d.mts} +1 -1
- package/dist/types-Cs6CdZCO.d.mts +83 -0
- package/dist/{types-CkpixGWr.d.mts → types-D1DijcJv.d.mts} +1 -1
- package/dist/{types-Cl-w8tYc.d.mts → types-DZTbvdpO.d.mts} +1 -1
- package/dist/{types-DgyGecdM.d.mts → types-DdTu747j.d.mts} +1 -1
- package/dist/{types-C4WUSW3e.d.mts → types-Dy3lZv9z.d.mts} +2 -2
- package/dist/{types-BGMmkUpy.d.mts → types-M-rsm1Km.d.mts} +1 -1
- package/dist/types.d.mts +1 -1
- package/dist/types2.d.mts +1 -1
- package/dist/types3.d.mts +1 -1
- package/dist/types4.d.mts +1 -1
- package/dist/types5.d.mts +1 -1
- package/dist/types6.d.mts +1 -1
- package/dist/types7.d.mts +2 -0
- package/dist/{url-state-8j_ef8Uf.d.mts → url-state-DWA7UFxS.d.mts} +2 -2
- package/dist/url-state.d.mts +1 -1
- package/dist/useChain-CEsXE2Bx.d.mts +77 -0
- package/dist/useChain-CKqYGdx4.mjs +4589 -0
- package/dist/useChain-CKqYGdx4.mjs.map +1 -0
- package/dist/useChainAtCursor.d.mts +87 -0
- package/dist/useCodeChainFunctionPanel.d.mts +26 -0
- package/dist/useComboboxFooterAction.d.mts +1 -1
- package/dist/{useFilterStateV2-CW6eght1.d.mts → useFilterStateV2-DoJ9lyJx.d.mts} +3 -3
- package/dist/useFilterStateV2.d.mts +1 -1
- package/dist/{useFormField-XezSxho_.mjs → useFormField-BAmkdxtA.mjs} +2 -2
- package/dist/{useFormField-XezSxho_.mjs.map → useFormField-BAmkdxtA.mjs.map} +1 -1
- package/dist/{useFormField-CLRZkUZt.d.mts → useFormField-BtnAYcHV.d.mts} +2 -2
- package/dist/useFormField.d.mts +1 -1
- package/dist/{useFormGroup-C7Cax8zO.mjs → useFormGroup-BZayb9fZ.mjs} +1 -1
- package/dist/{useFormGroup-C7Cax8zO.mjs.map → useFormGroup-BZayb9fZ.mjs.map} +1 -1
- package/dist/{useLocationPathname-DH5Tdq5X.d.mts → useLocationPathname-pLyLOrAi.d.mts} +1 -1
- package/dist/useLocationPathname.d.mts +1 -1
- package/dist/{useTableBoxDragAndDrop-Da4TiYBT.d.mts → useTableBoxDragAndDrop-wjc_LCpC.d.mts} +1 -1
- package/dist/useTableBoxDragAndDrop.d.mts +1 -1
- package/dist/useTruncation.d.mts +1 -1
- package/dist/{utilities-DcsbI71T.d.mts → utilities-DL18UdPs.d.mts} +1 -1
- package/dist/utilities.d.mts +1 -1
- package/dist/utils/storybook.mjs +1 -1
- package/dist/utils/testing.d.mts +1 -1
- package/dist/utils.d.mts +1 -1
- package/dist/utils4.d.mts +111 -0
- package/dist/{validation-BgwNghi2.d.mts → validation-PeVTwtd-.d.mts} +3 -3
- package/dist/validation.d.mts +1 -1
- package/dist/validation2.d.mts +64 -0
- package/dist/{value-control-resolver-B0HDRxRN.d.mts → value-control-resolver-Cx_wXQFv.d.mts} +2 -2
- package/dist/value-control-resolver.d.mts +1 -1
- package/dist/variables/effect.d.mts +1 -1
- package/dist/variables/semantic.d.mts +1 -1
- package/llms.txt +1 -1
- package/package.json +10 -3
- package/skills/ui-authoring/COMPONENTS.md +0 -1
- package/skills/ui-authoring/PATTERNS.md +1 -0
- package/dist/Pagination-Co9CfyFQ.mjs.map +0 -1
- package/dist/TableControls-RS_ozBsI.mjs.map +0 -1
- package/dist/components/WizardModal/index.mjs.map +0 -1
- /package/dist/{index-B24gUwOx.d.mts → index-7in8TPrM.d.mts} +0 -0
- /package/dist/{index-BFnNtGdX.d.mts → index-BCq_fh4A2.d.mts} +0 -0
- /package/dist/{index-BNRXMhlr.d.mts → index-BINnViIh.d.mts} +0 -0
- /package/dist/{index-BPiqSRRl.d.mts → index-BMBcfD_R.d.mts} +0 -0
- /package/dist/{index-BYd3Btr1.d.mts → index-BOn0AAue.d.mts} +0 -0
- /package/dist/{index-B_BBnMou.d.mts → index-BcsXXrHq.d.mts} +0 -0
- /package/dist/{index-Bt4QNofW.d.mts → index-BjgW3E7y.d.mts} +0 -0
- /package/dist/{index-C6HcjJiY.d.mts → index-BwXb5CoQ.d.mts} +0 -0
- /package/dist/{index-CEqOS-7M.d.mts → index-C3usUse7.d.mts} +0 -0
- /package/dist/{index-CIABef8t.d.mts → index-C9achTF6.d.mts} +0 -0
- /package/dist/{index-CTHojwxd.d.mts → index-CCKHlTA4.d.mts} +0 -0
- /package/dist/{index-CjDodOH2.d.mts → index-CFuHCx9T.d.mts} +0 -0
- /package/dist/{index-Cm-1i165.d.mts → index-CP2eJYlK.d.mts} +0 -0
- /package/dist/{index-CoUVmp_Q.d.mts → index-CWB6exYm.d.mts} +0 -0
- /package/dist/{index-DB7t8whN.d.mts → index-CryTAIZM.d.mts} +0 -0
- /package/dist/{index-DBGd4WeR.d.mts → index-CuYZJcK3.d.mts} +0 -0
- /package/dist/{index-DGsJdI5l.d.mts → index-CuheJfs-.d.mts} +0 -0
- /package/dist/{index-DWfPppPU.d.mts → index-D-9tW2r5.d.mts} +0 -0
- /package/dist/{index-DeVKzGce.d.mts → index-D9XihFV1.d.mts} +0 -0
- /package/dist/{index-DedbSZMv.d.mts → index-Dflz2i1X.d.mts} +0 -0
- /package/dist/{index-Jh0C5PIG.d.mts → index-DjOaHFU3.d.mts} +0 -0
- /package/dist/{index-NKYLt_R9.d.mts → index-DkrC-i1D.d.mts} +0 -0
- /package/dist/{index-Qwqzz3XM.d.mts → index-DrK1_jKY.d.mts} +0 -0
- /package/dist/{index-VWno75SQ.d.mts → index-Iujpc9_6.d.mts} +0 -0
- /package/dist/{index-fxXoW-qc.d.mts → index-e6k85DKM.d.mts} +0 -0
- /package/dist/{index-gVcIuWLd.d.mts → index-gpCH5158.d.mts} +0 -0
- /package/dist/{index-zeAhjge4.d.mts → index-irNqT1qQ2.d.mts} +0 -0
- /package/dist/{components → patterns}/WizardModal/index.d.mts +0 -0
|
@@ -0,0 +1,2035 @@
|
|
|
1
|
+
import { a as styled, r as css } from "../../styledComponentsInterop-NxwFjeA4.mjs";
|
|
2
|
+
import { i as Paragraph } from "../../Text-BdluS7Fy.mjs";
|
|
3
|
+
import { rotate } from "../../variables/keyframes.mjs";
|
|
4
|
+
import { JsonSchemaStringifiableTypes, getNonNullableRefSchema, getNonNullableType, isFunctionSchema, isJsonSchemaArray, isSchemaTypeAllowed } from "../../lib/jsonSchema.mjs";
|
|
5
|
+
import { isCreatableReceiverSchema, isNoArgCodeChainFunction } from "../../lib/customFunctionSchema.mjs";
|
|
6
|
+
import { isASTCustomFunctionNode, isAnyASTFunctionNode, isRealASTFunctionParamType } from "./parser/method-chain/types.mjs";
|
|
7
|
+
import { _ as methodChainToString, l as isEmpty, n as MethodChainNodeTypes, w as assertNever } from "../../methodChain-L_h8Z8Bx.mjs";
|
|
8
|
+
import { normalizeChain, normalizeFunctionParam } from "../../lib/methodChainNormalize.mjs";
|
|
9
|
+
import { getFunctionSchemaForNode, getSchemaForFieldPath } from "../../lib/schemaOptions.mjs";
|
|
10
|
+
import { n as useChain, r as useChainSchema } from "../../useChain-CKqYGdx4.mjs";
|
|
11
|
+
import { Z_INDICES } from "../../lib/zindex.mjs";
|
|
12
|
+
import { focusStyle } from "../../mixins/focus.mjs";
|
|
13
|
+
import "../../variables/effect.mjs";
|
|
14
|
+
import { n as Stack, t as HStack } from "../../Stack-CEPzs4Pb.mjs";
|
|
15
|
+
import { n as Button } from "../../IconButton-BHFCjvzs.mjs";
|
|
16
|
+
import { n as useFormField } from "../../useFormField-BAmkdxtA.mjs";
|
|
17
|
+
import Input_default from "../Input/index.mjs";
|
|
18
|
+
import { n as ErrorText } from "../../FormControl-bDxFF0hl.mjs";
|
|
19
|
+
import { m as FormField, n as TableBoxField, p as splitOutFormFieldProps } from "../../FormField-DbcqNcx2.mjs";
|
|
20
|
+
import PillType from "./PillType.mjs";
|
|
21
|
+
import { ErrorMessageByKind, NodeType, isASTChainNode, isASTContainerNode, isMethodChainNode } from "./parser/smart-text/types.mjs";
|
|
22
|
+
import { parse as peg$parse } from "./parser/smart-text/parser.mjs";
|
|
23
|
+
import { BorderRadius, Color, Spacing, Typography } from "@persona/design-tokens";
|
|
24
|
+
import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
25
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
26
|
+
import { LoaderIcon } from "@persona/icons";
|
|
27
|
+
import { ArrowLeftIcon as ArrowLeftIcon$1 } from "@persona/icons/12px";
|
|
28
|
+
import { FocusScope, mergeProps, useComboBox, useDialog, useFocusManager, useInteractOutside, useListBox, useOption, usePopover } from "react-aria";
|
|
29
|
+
import { Item, useComboBoxState } from "react-stately";
|
|
30
|
+
import { createPortal } from "react-dom";
|
|
31
|
+
//#region components/SmartTextInput/parser/tree.ts
|
|
32
|
+
function getChildren(node) {
|
|
33
|
+
return node.children ?? [];
|
|
34
|
+
}
|
|
35
|
+
function findAll(node, type, acc = []) {
|
|
36
|
+
if (node.type === type) acc.push(node);
|
|
37
|
+
getChildren(node).forEach((c) => findAll(c, type, acc));
|
|
38
|
+
return acc;
|
|
39
|
+
}
|
|
40
|
+
function resolve(node, charIdx) {
|
|
41
|
+
if (charIdx < node.start || charIdx >= Math.max(node.end, node.start + 1)) return null;
|
|
42
|
+
const children = getChildren(node);
|
|
43
|
+
for (let i = 0; i < children.length; i++) {
|
|
44
|
+
const hit = resolve(children[i], charIdx);
|
|
45
|
+
if (hit) return hit;
|
|
46
|
+
}
|
|
47
|
+
return node;
|
|
48
|
+
}
|
|
49
|
+
function findAncestor(root, target, pred) {
|
|
50
|
+
function walk(n, ancestors) {
|
|
51
|
+
if (n === target) {
|
|
52
|
+
for (let i = ancestors.length - 1; i >= 0; i--) if (pred(ancestors[i])) return [true, ancestors[i]];
|
|
53
|
+
return [true, null];
|
|
54
|
+
}
|
|
55
|
+
const children = getChildren(n);
|
|
56
|
+
for (let j = 0; j < children.length; j++) {
|
|
57
|
+
const [found, result] = walk(children[j], ancestors.concat([n]));
|
|
58
|
+
if (found) return [true, result];
|
|
59
|
+
}
|
|
60
|
+
return [false, null];
|
|
61
|
+
}
|
|
62
|
+
const [, result] = walk(root, []);
|
|
63
|
+
return result;
|
|
64
|
+
}
|
|
65
|
+
function enclosingExpr(root, node) {
|
|
66
|
+
return findAncestor(root, node, (a) => a.type === NodeType.Handlebars || a.type === NodeType.Code);
|
|
67
|
+
}
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region components/SmartTextInput/HighlightedText.tsx
|
|
70
|
+
const LoadingIndicator = styled(LoaderIcon)`
|
|
71
|
+
color: ${Color.BorderIconSecondary};
|
|
72
|
+
animation: ${rotate} linear 1s infinite;
|
|
73
|
+
`;
|
|
74
|
+
const LoadingContainer = styled.div`
|
|
75
|
+
z-index: 4;
|
|
76
|
+
position: absolute;
|
|
77
|
+
right: 1px;
|
|
78
|
+
top: 1px;
|
|
79
|
+
bottom: 1px;
|
|
80
|
+
padding: ${Spacing[2]} ${Spacing[3]};
|
|
81
|
+
background: linear-gradient(to right, ${Color.BackgroundPrimary}00, ${Color.BackgroundSecondary}FF);
|
|
82
|
+
`;
|
|
83
|
+
const OverlayContainer = styled.div`
|
|
84
|
+
position: relative;
|
|
85
|
+
background: ${Color.BackgroundPrimary};
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
width: 100%;
|
|
88
|
+
|
|
89
|
+
border-radius: ${BorderRadius.Md};
|
|
90
|
+
|
|
91
|
+
&:focus-within,
|
|
92
|
+
&[data-input-is-focused='true'] {
|
|
93
|
+
${focusStyle}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
${({ $variant }) => $variant === "table-cell" && css`
|
|
97
|
+
background: transparent;
|
|
98
|
+
outline: none !important;
|
|
99
|
+
border-radius: 0;
|
|
100
|
+
`};
|
|
101
|
+
`;
|
|
102
|
+
const Overlay = styled.div`
|
|
103
|
+
${Typography.TextMono}
|
|
104
|
+
|
|
105
|
+
line-height: 1;
|
|
106
|
+
|
|
107
|
+
position: absolute;
|
|
108
|
+
inset: 0;
|
|
109
|
+
/* 8px + 12px with 1px buffer to account for underlying input border. Needs to be margin in X
|
|
110
|
+
seemingly for overflow to work correctly. */
|
|
111
|
+
margin: 0 13px;
|
|
112
|
+
padding: 9px 0;
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
white-space: pre;
|
|
115
|
+
display: flex;
|
|
116
|
+
align-items: center;
|
|
117
|
+
box-sizing: border-box;
|
|
118
|
+
overflow: hidden;
|
|
119
|
+
|
|
120
|
+
${({ $size }) => $size === "sm" && css`
|
|
121
|
+
font-size: 12px;
|
|
122
|
+
margin: 0 9px;
|
|
123
|
+
`};
|
|
124
|
+
${({ $variant }) => $variant === "table-cell" && css`
|
|
125
|
+
margin: 0;
|
|
126
|
+
padding: 0;
|
|
127
|
+
`};
|
|
128
|
+
`;
|
|
129
|
+
const MonoSpan = styled.span`
|
|
130
|
+
color: ${({ $style }) => {
|
|
131
|
+
switch ($style) {
|
|
132
|
+
case "schemaError":
|
|
133
|
+
case "syntaxError": return Color.TextDanger;
|
|
134
|
+
case "token":
|
|
135
|
+
case "hoverableToken": return Color.TextActive;
|
|
136
|
+
}
|
|
137
|
+
}};
|
|
138
|
+
|
|
139
|
+
border-radius: 0;
|
|
140
|
+
text-decoration: ${({ $style }) => $style === "syntaxError" ? `underline wavy ${Color.TextDanger}` : "none"};
|
|
141
|
+
text-decoration-skip-ink: none;
|
|
142
|
+
|
|
143
|
+
${({ $style, $interactive }) => {
|
|
144
|
+
if (!$interactive) return;
|
|
145
|
+
switch ($style) {
|
|
146
|
+
case "schemaError": return css`
|
|
147
|
+
position: relative;
|
|
148
|
+
pointer-events: auto;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
|
|
151
|
+
&::after {
|
|
152
|
+
content: '';
|
|
153
|
+
position: absolute;
|
|
154
|
+
inset: -2px;
|
|
155
|
+
background-color: ${Color.CoreRed600};
|
|
156
|
+
opacity: 0.1;
|
|
157
|
+
pointer-events: none;
|
|
158
|
+
}
|
|
159
|
+
&:hover::after {
|
|
160
|
+
opacity: 0.2;
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
case "hoverable":
|
|
164
|
+
case "hoverableToken": return css`
|
|
165
|
+
position: relative;
|
|
166
|
+
pointer-events: auto;
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
|
|
169
|
+
&:hover::after {
|
|
170
|
+
content: '';
|
|
171
|
+
position: absolute;
|
|
172
|
+
inset: -2px;
|
|
173
|
+
background-color: ${Color.CoreBlue600};
|
|
174
|
+
opacity: 0.1;
|
|
175
|
+
pointer-events: none;
|
|
176
|
+
}
|
|
177
|
+
`;
|
|
178
|
+
}
|
|
179
|
+
}};
|
|
180
|
+
`;
|
|
181
|
+
/**
|
|
182
|
+
* Returns {str, style} segments covering the entire value, based on AST node boundaries.
|
|
183
|
+
* - 'token': delimiter nodes ({{, }}, ${, }), dot nodes
|
|
184
|
+
* - 'hoverableToken': first link of any chain (single-link or multi-segment)
|
|
185
|
+
* - 'hoverable': non-first links of multi-segment chains
|
|
186
|
+
* - 'schemaError': first invalid link in each chain, shown when unfocused
|
|
187
|
+
* - 'syntaxError': error nodes with actual content
|
|
188
|
+
* - 'none': everything else
|
|
189
|
+
*/
|
|
190
|
+
function buildHighlights(tree, value, focused, schemaValidator) {
|
|
191
|
+
const len = value.length;
|
|
192
|
+
const spanMap = /* @__PURE__ */ new Map();
|
|
193
|
+
function setSpan(start, end, style) {
|
|
194
|
+
if (start < end) spanMap.set(start, {
|
|
195
|
+
start,
|
|
196
|
+
end,
|
|
197
|
+
style
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
for (const type of [
|
|
201
|
+
NodeType.HBOpen,
|
|
202
|
+
NodeType.HBClose,
|
|
203
|
+
NodeType.CodeOpen,
|
|
204
|
+
NodeType.CodeClose,
|
|
205
|
+
"dot"
|
|
206
|
+
]) findAll(tree, type).forEach((n) => setSpan(n.start, n.end, "token"));
|
|
207
|
+
findAll(tree, NodeType.Error).forEach((e) => {
|
|
208
|
+
const node = e;
|
|
209
|
+
if (e.start >= e.end && !node.wip) return;
|
|
210
|
+
if (node.wip) {
|
|
211
|
+
if (!focused) setSpan(e.end - 1, e.end, "syntaxError");
|
|
212
|
+
} else setSpan(e.start, e.end, "syntaxError");
|
|
213
|
+
});
|
|
214
|
+
const paramChainStarts = /* @__PURE__ */ new Set();
|
|
215
|
+
findAll(tree, NodeType.Chain).forEach((chain) => {
|
|
216
|
+
if (!isASTChainNode(chain)) return;
|
|
217
|
+
for (const link of chain.children) if (link.type === NodeType.Function || link.type === NodeType.CustomFunction) {
|
|
218
|
+
for (const child of link.children) if (child.type === NodeType.Chain) paramChainStarts.add(child.start);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
findAll(tree, NodeType.Chain).forEach((chain) => {
|
|
222
|
+
if (!isASTChainNode(chain)) return;
|
|
223
|
+
if (paramChainStarts.has(chain.start)) return;
|
|
224
|
+
if (!chain.children.some((l) => l.type === NodeType.Dot)) {
|
|
225
|
+
if (chain.children.some((l) => l.type === NodeType.Error && !l.wip)) return;
|
|
226
|
+
}
|
|
227
|
+
chain.children.forEach((link, idx) => {
|
|
228
|
+
if (link.type === NodeType.Identifier || link.type === NodeType.Function || link.type === NodeType.CustomFunction) {
|
|
229
|
+
const style = idx === 0 ? "hoverableToken" : "hoverable";
|
|
230
|
+
if (link.type === NodeType.Function || link.type === NodeType.CustomFunction) {
|
|
231
|
+
const nameEnd = link.type === NodeType.CustomFunction ? link.start + 1 + link.name.length : link.start + link.name.length;
|
|
232
|
+
setSpan(link.start, nameEnd, style);
|
|
233
|
+
if (link.children.some((child) => child.type === NodeType.ParenClose)) {
|
|
234
|
+
for (const child of link.children) if (child.type !== NodeType.Error && child.type !== NodeType.ParenOpen && child.type !== NodeType.ParenClose) setSpan(child.start, child.end, style);
|
|
235
|
+
}
|
|
236
|
+
} else setSpan(link.start, link.end, style);
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
if (!focused) findAll(tree, NodeType.Handlebars).forEach((node) => {
|
|
241
|
+
const children = node.children ?? [];
|
|
242
|
+
const closeNode = children.find((c) => c.type === NodeType.HBClose);
|
|
243
|
+
const hasChain = children.some((c) => c.type === NodeType.Chain);
|
|
244
|
+
if (closeNode && !hasChain) setSpan(closeNode.start, closeNode.end, "syntaxError");
|
|
245
|
+
});
|
|
246
|
+
if (!focused) {
|
|
247
|
+
const topLevelChains = findAll(tree, NodeType.Chain).filter(isASTChainNode).filter((c) => !paramChainStarts.has(c.start));
|
|
248
|
+
for (const chain of topLevelChains) {
|
|
249
|
+
const enclosingNode = enclosingExpr(tree, chain);
|
|
250
|
+
const chainError = schemaValidator(enclosingNode?.type === NodeType.Handlebars && !enclosingNode.children?.some((c) => c.type === NodeType.Error && c.kind === "unclosedHandlebars") ? {
|
|
251
|
+
type: NodeType.Handlebars,
|
|
252
|
+
start: chain.start,
|
|
253
|
+
end: chain.end,
|
|
254
|
+
children: [chain]
|
|
255
|
+
} : chain);
|
|
256
|
+
if (chainError != null) setSpan(chainError.start, chainError.end, "schemaError");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const sorted = Array.from(spanMap.values()).sort((a, b) => a.start - b.start);
|
|
260
|
+
const result = [];
|
|
261
|
+
let pos = 0;
|
|
262
|
+
for (const span of sorted) {
|
|
263
|
+
if (span.start < pos) continue;
|
|
264
|
+
if (pos < span.start) result.push({
|
|
265
|
+
str: value.slice(pos, span.start),
|
|
266
|
+
style: "none"
|
|
267
|
+
});
|
|
268
|
+
result.push({
|
|
269
|
+
str: value.slice(span.start, span.end),
|
|
270
|
+
style: span.style
|
|
271
|
+
});
|
|
272
|
+
pos = span.end;
|
|
273
|
+
}
|
|
274
|
+
if (pos < len) result.push({
|
|
275
|
+
str: value.slice(pos, len),
|
|
276
|
+
style: "none"
|
|
277
|
+
});
|
|
278
|
+
return result.filter((r) => r.str.length > 0);
|
|
279
|
+
}
|
|
280
|
+
const HighlightedTextOverlay = forwardRef(function HighlightedTextOverlay({ children, onWheel, onMouseMove, highlightedText, overlayRef, inputIsFocused, mode, size, variant, valueType, isLoading }, ref) {
|
|
281
|
+
return /* @__PURE__ */ jsxs(OverlayContainer, {
|
|
282
|
+
ref,
|
|
283
|
+
onWheel,
|
|
284
|
+
onMouseMove,
|
|
285
|
+
$variant: variant,
|
|
286
|
+
"data-input-is-focused": inputIsFocused,
|
|
287
|
+
"data-test": "smart-text-input",
|
|
288
|
+
"data-mode": mode,
|
|
289
|
+
"data-value-type": valueType,
|
|
290
|
+
children: [
|
|
291
|
+
/* @__PURE__ */ jsx(Overlay, {
|
|
292
|
+
ref: overlayRef,
|
|
293
|
+
"data-test": "smart-text-input__highlight",
|
|
294
|
+
"aria-hidden": true,
|
|
295
|
+
style: { zIndex: 3 },
|
|
296
|
+
$size: size,
|
|
297
|
+
$variant: variant,
|
|
298
|
+
children: highlightedText
|
|
299
|
+
}),
|
|
300
|
+
isLoading && /* @__PURE__ */ jsx(LoadingContainer, { children: /* @__PURE__ */ jsx(LoadingIndicator, {
|
|
301
|
+
"aria-label": "Loading schema…",
|
|
302
|
+
role: "status"
|
|
303
|
+
}) }),
|
|
304
|
+
children
|
|
305
|
+
]
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
/**
|
|
309
|
+
* Render the value with syntax highlighting and clickable link spans using the parsed AST.
|
|
310
|
+
*/
|
|
311
|
+
const HighlightedText = ({ value, tree, focused, interactive, schemaValidator, onLinkMouseDown, dontHighlightErrors = false, cursorIdx }) => {
|
|
312
|
+
const runs = buildHighlights(tree, value, focused, schemaValidator);
|
|
313
|
+
const linkMap = /* @__PURE__ */ new Map();
|
|
314
|
+
findAll(tree, NodeType.Chain).forEach((chainNode) => {
|
|
315
|
+
if (!isASTChainNode(chainNode)) return;
|
|
316
|
+
chainNode.children.forEach((link) => {
|
|
317
|
+
if (link.type === NodeType.Identifier || link.type === NodeType.Function || link.type === NodeType.CustomFunction) {
|
|
318
|
+
linkMap.set(link.start, {
|
|
319
|
+
start: link.start,
|
|
320
|
+
end: link.end
|
|
321
|
+
});
|
|
322
|
+
if (link.type === NodeType.Function || link.type === NodeType.CustomFunction) {
|
|
323
|
+
if (link.children.some((child) => child.type === NodeType.ParenClose)) {
|
|
324
|
+
for (const child of link.children) if (child.type !== NodeType.Error && child.type !== NodeType.ParenOpen && child.type !== NodeType.ParenClose) linkMap.set(child.start, {
|
|
325
|
+
start: child.start,
|
|
326
|
+
end: child.start
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
let pos = 0;
|
|
334
|
+
return /* @__PURE__ */ jsx(Fragment$1, { children: runs.map((r) => {
|
|
335
|
+
const start = pos;
|
|
336
|
+
pos += r.str.length;
|
|
337
|
+
const linkInfo = linkMap.get(start);
|
|
338
|
+
const isLinkSpan = linkInfo != null;
|
|
339
|
+
const isHidingErrorSpan = dontHighlightErrors && (r.style === "schemaError" || r.style === "syntaxError");
|
|
340
|
+
const cursorWithinSpan = focused && isLinkSpan && cursorIdx != null && cursorIdx >= start && cursorIdx <= start + r.str.length;
|
|
341
|
+
return /* @__PURE__ */ jsx(MonoSpan, {
|
|
342
|
+
"data-style": r.style,
|
|
343
|
+
$style: isHidingErrorSpan ? "none" : r.style,
|
|
344
|
+
$interactive: interactive && isLinkSpan && !cursorWithinSpan,
|
|
345
|
+
onMouseDown: isLinkSpan && interactive && onLinkMouseDown ? (e) => {
|
|
346
|
+
e.preventDefault();
|
|
347
|
+
onLinkMouseDown(linkInfo.start, linkInfo.end, e);
|
|
348
|
+
} : void 0,
|
|
349
|
+
children: r.str.replace(/ /g, "\xA0")
|
|
350
|
+
}, start);
|
|
351
|
+
}) });
|
|
352
|
+
};
|
|
353
|
+
//#endregion
|
|
354
|
+
//#region components/SmartTextInput/types.ts
|
|
355
|
+
/**
|
|
356
|
+
* The mode of the SmartTextInput. Determined by the position of the cursor in the input and the
|
|
357
|
+
* result of the parser.
|
|
358
|
+
*
|
|
359
|
+
* Mode determines behavior of the input.
|
|
360
|
+
*/
|
|
361
|
+
let Mode = /* @__PURE__ */ function(Mode) {
|
|
362
|
+
Mode["MethodChain"] = "method-chain";
|
|
363
|
+
Mode["Code"] = "code";
|
|
364
|
+
Mode["Text"] = "text";
|
|
365
|
+
return Mode;
|
|
366
|
+
}({});
|
|
367
|
+
/**
|
|
368
|
+
* The value type of the SmartTextInput. Value type indicates the semantic meaning of the input's
|
|
369
|
+
* raw string value.
|
|
370
|
+
*/
|
|
371
|
+
let ValueType = /* @__PURE__ */ function(ValueType) {
|
|
372
|
+
ValueType["Interpolation"] = "interpolation";
|
|
373
|
+
ValueType["MethodChain"] = "method-chain";
|
|
374
|
+
return ValueType;
|
|
375
|
+
}({});
|
|
376
|
+
//#endregion
|
|
377
|
+
//#region components/SmartTextInput/parser/safe-parse.ts
|
|
378
|
+
/**
|
|
379
|
+
* Parses the input string into an ASTNode tree.
|
|
380
|
+
*/
|
|
381
|
+
function safeParse(input, options) {
|
|
382
|
+
try {
|
|
383
|
+
return peg$parse(input, {
|
|
384
|
+
startRule: "Root",
|
|
385
|
+
strict: false,
|
|
386
|
+
...options
|
|
387
|
+
});
|
|
388
|
+
} catch {
|
|
389
|
+
return {
|
|
390
|
+
type: NodeType.Root,
|
|
391
|
+
start: 0,
|
|
392
|
+
end: input.length,
|
|
393
|
+
children: [{
|
|
394
|
+
type: NodeType.Error,
|
|
395
|
+
start: 0,
|
|
396
|
+
end: input.length
|
|
397
|
+
}]
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
//#endregion
|
|
402
|
+
//#region components/SmartTextInput/utils.ts
|
|
403
|
+
const createMeasureCanvas = () => {
|
|
404
|
+
const canvas = document.createElement("canvas");
|
|
405
|
+
return [canvas, () => {
|
|
406
|
+
canvas.width = 0;
|
|
407
|
+
canvas.height = 0;
|
|
408
|
+
canvas.remove();
|
|
409
|
+
}];
|
|
410
|
+
};
|
|
411
|
+
const safeCursorIdx = (cursorIdx, ast) => {
|
|
412
|
+
const idx = cursorIdx ?? ast.end;
|
|
413
|
+
return Math.max(Math.min(idx, ast.end), 0);
|
|
414
|
+
};
|
|
415
|
+
/**
|
|
416
|
+
* Returns true if the input is allowed to transition to the given value type based on allowed type.
|
|
417
|
+
* When allowedValueType is set, transitions to a different type are prohibited.
|
|
418
|
+
*/
|
|
419
|
+
function canTransitionToValueType(valueType, allowedValueType) {
|
|
420
|
+
if (!allowedValueType) return true;
|
|
421
|
+
return allowedValueType === valueType;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Returns true if the given interpolation mode (handlebars or code) is allowed.
|
|
425
|
+
* When allowedValueType is 'method-chain', interpolation modes are never allowed.
|
|
426
|
+
*/
|
|
427
|
+
function isInterpolationModeAllowed(mode, allowedValueType, allowedInterpolationModes) {
|
|
428
|
+
if (allowedValueType === "method-chain") return false;
|
|
429
|
+
if (!allowedInterpolationModes) return true;
|
|
430
|
+
return allowedInterpolationModes.includes(mode);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Returns true if the input can exit method-chain value type back to interpolation.
|
|
434
|
+
* Requires an empty value and that the allowed value type is interpolation.
|
|
435
|
+
*/
|
|
436
|
+
function canExitToInterpolation(value, allowedValueType) {
|
|
437
|
+
return value === "" && canTransitionToValueType("interpolation", allowedValueType);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Apply from element scrollLeft to the to element scrollLeft
|
|
441
|
+
*/
|
|
442
|
+
const syncScroll = (from, to) => {
|
|
443
|
+
if (from.current && to.current) to.current.scrollLeft = from.current.scrollLeft;
|
|
444
|
+
};
|
|
445
|
+
const [globalMeasureCanvas] = createMeasureCanvas();
|
|
446
|
+
/**
|
|
447
|
+
* Scroll the input so the cursor at cursorIdx is visible, then sync the overlay.
|
|
448
|
+
*
|
|
449
|
+
* overflow:hidden on the StyledInput prevents the browser from auto-scrolling to
|
|
450
|
+
* the cursor when setSelectionRange is called programmatically. We replicate the
|
|
451
|
+
* same manual scrollLeft update that handleWheel uses.
|
|
452
|
+
*/
|
|
453
|
+
const scrollInputToCursor = (inputRef, cursorIdx) => {
|
|
454
|
+
const input = inputRef.current;
|
|
455
|
+
if (!input) return;
|
|
456
|
+
const ctx = globalMeasureCanvas.getContext("2d");
|
|
457
|
+
if (!ctx) return;
|
|
458
|
+
const style = window.getComputedStyle(input);
|
|
459
|
+
ctx.font = `${style.fontStyle} ${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;
|
|
460
|
+
const cursorPx = ctx.measureText(input.value.slice(0, cursorIdx)).width;
|
|
461
|
+
const lookaheadPx = ctx.measureText(input.value.slice(0, cursorIdx + 1)).width;
|
|
462
|
+
const paddingLeft = parseFloat(style.paddingLeft) || 0;
|
|
463
|
+
const paddingRight = parseFloat(style.paddingRight) || 0;
|
|
464
|
+
const contentWidth = input.clientWidth - paddingLeft - paddingRight;
|
|
465
|
+
const margin = 4;
|
|
466
|
+
if (cursorPx < input.scrollLeft) input.scrollLeft = Math.max(0, cursorPx - margin);
|
|
467
|
+
else if (lookaheadPx > input.scrollLeft + contentWidth) input.scrollLeft = lookaheadPx - contentWidth + margin;
|
|
468
|
+
};
|
|
469
|
+
/**
|
|
470
|
+
* Returns true if the value is a valid method chain where the root is valid given the passed
|
|
471
|
+
* accepted chain roots.
|
|
472
|
+
*/
|
|
473
|
+
const isChainWithValidRoot = (value, chainRoots, { onlyAllowSingleLink = false } = {}) => {
|
|
474
|
+
const firstChild = (safeParse(value, { startRule: "ChainRoot" }).children ?? [])[0];
|
|
475
|
+
return firstChild != null && firstChild.type === NodeType.Chain && isASTChainNode(firstChild) && chainRoots.some((r) => {
|
|
476
|
+
const firstLink = firstChild.children[0];
|
|
477
|
+
return firstLink != null && isMethodChainNode(firstLink) && r.label === firstLink.name;
|
|
478
|
+
}) && (!onlyAllowSingleLink || firstChild.children.length === 1);
|
|
479
|
+
};
|
|
480
|
+
/**
|
|
481
|
+
* Returns the ASTChain node that contains the cursor, or undefined if none.
|
|
482
|
+
*/
|
|
483
|
+
function findChainAtCursor(tree, cursorIdx, valueType) {
|
|
484
|
+
const idx = cursorIdx ?? 0;
|
|
485
|
+
if (valueType === "method-chain") {
|
|
486
|
+
const chainNode = findAll(tree, NodeType.Chain)[0];
|
|
487
|
+
return chainNode && isASTChainNode(chainNode) ? chainNode : void 0;
|
|
488
|
+
}
|
|
489
|
+
const node = resolve(tree, idx > 0 ? idx - 1 : 0);
|
|
490
|
+
if (node && (node.type === NodeType.HBOpen || node.type === NodeType.HBClose || node.type === NodeType.CodeOpen || node.type === NodeType.CodeClose) && idx > node.start && idx < node.end) return;
|
|
491
|
+
if (node) {
|
|
492
|
+
const expr = enclosingExpr(tree, node);
|
|
493
|
+
if (expr && isASTContainerNode(expr) && idx > expr.start) {
|
|
494
|
+
const chainChild = (expr.children ?? []).find((c) => isASTChainNode(c));
|
|
495
|
+
if (chainChild && isASTChainNode(chainChild)) return chainChild;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
const fallback = findAll(tree, NodeType.Chain).find((c) => c.start <= idx && idx <= c.end);
|
|
499
|
+
return fallback && isASTChainNode(fallback) ? fallback : void 0;
|
|
500
|
+
}
|
|
501
|
+
/**
|
|
502
|
+
* Replace the chain string at the cursor position.
|
|
503
|
+
*
|
|
504
|
+
* - ValueType.MethodChain: replaces the entire value.
|
|
505
|
+
* - ValueType.Interpolation: replaces the chain inside the {{...}} or ${...}
|
|
506
|
+
* expression the cursor is currently in.
|
|
507
|
+
*
|
|
508
|
+
* Returns the new value string and the new cursor position (end of inserted chain).
|
|
509
|
+
*/
|
|
510
|
+
const replaceChainAtCursor = (value, valueType, cursorIdx, tree, newChainString) => {
|
|
511
|
+
if (valueType === "method-chain") return {
|
|
512
|
+
newValue: newChainString,
|
|
513
|
+
newCursorIdx: newChainString.length
|
|
514
|
+
};
|
|
515
|
+
const nodeAtCursor = resolve(tree, cursorIdx != null && cursorIdx > 0 ? cursorIdx - 1 : 0);
|
|
516
|
+
if (!nodeAtCursor) return {
|
|
517
|
+
newValue: value,
|
|
518
|
+
newCursorIdx: cursorIdx ?? value.length
|
|
519
|
+
};
|
|
520
|
+
let expr = enclosingExpr(tree, nodeAtCursor);
|
|
521
|
+
if (!expr && (nodeAtCursor.type === NodeType.Handlebars || nodeAtCursor.type === NodeType.Code)) expr = nodeAtCursor;
|
|
522
|
+
if (!expr || !isASTContainerNode(expr)) return {
|
|
523
|
+
newValue: value,
|
|
524
|
+
newCursorIdx: cursorIdx ?? value.length
|
|
525
|
+
};
|
|
526
|
+
const children = expr.children ?? [];
|
|
527
|
+
const openNode = children.find((c) => c.type === NodeType.HBOpen || c.type === NodeType.CodeOpen);
|
|
528
|
+
const closeNode = children.find((c) => c.type === NodeType.HBClose || c.type === NodeType.CodeClose);
|
|
529
|
+
if (!openNode) return {
|
|
530
|
+
newValue: value,
|
|
531
|
+
newCursorIdx: cursorIdx ?? value.length
|
|
532
|
+
};
|
|
533
|
+
const before = value.slice(0, openNode.end);
|
|
534
|
+
const after = closeNode ? value.slice(closeNode.start) : "";
|
|
535
|
+
return {
|
|
536
|
+
newValue: before + newChainString + after,
|
|
537
|
+
newCursorIdx: before.length + newChainString.length
|
|
538
|
+
};
|
|
539
|
+
};
|
|
540
|
+
/**
|
|
541
|
+
* Returns context about a method chain function whenever the cursor falls anywhere within
|
|
542
|
+
* the function node's span (name, parens, or params).
|
|
543
|
+
*/
|
|
544
|
+
function getFunctionAtCursor(tree, cursorIdx, valueType) {
|
|
545
|
+
const idx = cursorIdx ?? 0;
|
|
546
|
+
const chainNode = findChainAtCursor(tree, cursorIdx, valueType);
|
|
547
|
+
if (!chainNode) return null;
|
|
548
|
+
for (const link of chainNode.children) {
|
|
549
|
+
if (!isAnyASTFunctionNode(link)) continue;
|
|
550
|
+
if (idx < link.start || idx >= link.end) continue;
|
|
551
|
+
const parenOpenNode = link.children.find((c) => c.type === NodeType.ParenOpen);
|
|
552
|
+
const parenCloseNode = link.children.find((c) => c.type === NodeType.ParenClose);
|
|
553
|
+
const cursorInParens = parenOpenNode != null && parenCloseNode != null && idx > parenOpenNode.start && idx < parenCloseNode.end;
|
|
554
|
+
const existingParams = link.children.filter(isRealASTFunctionParamType).map(normalizeFunctionParam);
|
|
555
|
+
return {
|
|
556
|
+
functionName: isASTCustomFunctionNode(link) ? `@${link.name}` : link.name,
|
|
557
|
+
existingParams,
|
|
558
|
+
start: link.start,
|
|
559
|
+
end: link.end,
|
|
560
|
+
cursorInParens,
|
|
561
|
+
custom: isASTCustomFunctionNode(link)
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
return null;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Returns true if there is a CustomFunction node that starts at the given position.
|
|
568
|
+
* Used to detect clicks on custom code function spans.
|
|
569
|
+
*/
|
|
570
|
+
function isCustomFunctionAtStart(tree, position) {
|
|
571
|
+
return findAll(tree, NodeType.CustomFunction).some((n) => n.start === position);
|
|
572
|
+
}
|
|
573
|
+
/**
|
|
574
|
+
* Returns true when the cursor sits immediately after a function call's closing paren
|
|
575
|
+
* (e.g. cursor at the `|` in `accounts.filter(x)|`). Used to derive assumeOnNextLink
|
|
576
|
+
* from cursor position rather than relying solely on state.
|
|
577
|
+
*/
|
|
578
|
+
function isCursorAfterFunctionClose(tree, cursorIdx, valueType) {
|
|
579
|
+
const idx = cursorIdx ?? 0;
|
|
580
|
+
const chainNode = findChainAtCursor(tree, cursorIdx, valueType);
|
|
581
|
+
if (!chainNode) return false;
|
|
582
|
+
for (const link of chainNode.children) {
|
|
583
|
+
if (!isAnyASTFunctionNode(link)) continue;
|
|
584
|
+
const parenCloseNode = link.children.find((c) => c.type === NodeType.ParenClose);
|
|
585
|
+
if (parenCloseNode && idx === parenCloseNode.end) return true;
|
|
586
|
+
}
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Return the current Mode of the input. The mode determines what is valid syntax.
|
|
591
|
+
*/
|
|
592
|
+
const getMode = (tree, valueType, cursorIdx) => {
|
|
593
|
+
cursorIdx = cursorIdx ?? 0;
|
|
594
|
+
if (valueType === "method-chain") return "method-chain";
|
|
595
|
+
const n = resolve(tree, cursorIdx > 0 ? cursorIdx - 1 : 0);
|
|
596
|
+
if (!n) return "text";
|
|
597
|
+
const expr = enclosingExpr(tree, n);
|
|
598
|
+
if (!expr) {
|
|
599
|
+
if (n.type === NodeType.Handlebars || n.type === NodeType.Code) return "method-chain";
|
|
600
|
+
return "text";
|
|
601
|
+
}
|
|
602
|
+
const exprChildren = isASTContainerNode(expr) ? expr.children ?? [] : [];
|
|
603
|
+
const openNode = exprChildren.find((c) => c.type === NodeType.HBOpen || c.type === NodeType.CodeOpen);
|
|
604
|
+
const closeNode = exprChildren.find((c) => c.type === NodeType.HBClose || c.type === NodeType.CodeClose);
|
|
605
|
+
if (closeNode && cursorIdx > closeNode.start) return "text";
|
|
606
|
+
if (openNode && cursorIdx < openNode.end) return "text";
|
|
607
|
+
if (expr.type === NodeType.Handlebars) return "method-chain";
|
|
608
|
+
if (expr.type === NodeType.Code) return "code";
|
|
609
|
+
return "text";
|
|
610
|
+
};
|
|
611
|
+
/**
|
|
612
|
+
* Determine if the cursor is strictly between chars of a delimiter token (like `{{`). In this
|
|
613
|
+
* state we want to hide the popover.
|
|
614
|
+
*/
|
|
615
|
+
const isCursorInExpressionToken = (tree, cursorIdx, valueType) => {
|
|
616
|
+
if (valueType === "method-chain") return false;
|
|
617
|
+
const idx = safeCursorIdx(cursorIdx, tree);
|
|
618
|
+
if (idx === 0) return false;
|
|
619
|
+
const n = resolve(tree, idx - 1);
|
|
620
|
+
if (!n || n.type !== NodeType.HBOpen && n.type !== NodeType.HBClose && n.type !== NodeType.CodeOpen && n.type !== NodeType.CodeClose) return false;
|
|
621
|
+
return idx > n.start && idx < n.end;
|
|
622
|
+
};
|
|
623
|
+
/**
|
|
624
|
+
* When the user selects a chain option that already exists at the cursor position
|
|
625
|
+
* (e.g. confirming "page_number" while the value is "accounts.page_number(#1)", or
|
|
626
|
+
* confirming "accounts" while the cursor is inside "accounts.id"), returns the cursor
|
|
627
|
+
* position to move to rather than replacing the value via appendChain (which would
|
|
628
|
+
* discard existing parameters or suffixes after the link).
|
|
629
|
+
*
|
|
630
|
+
* Returns null when the link is not already present — caller should appendChain instead.
|
|
631
|
+
*
|
|
632
|
+
* Note: options always carry Identifier chain nodes (appendedMethodChain uses strings),
|
|
633
|
+
* so `isFunction` is derived from the schema rather than chain.type.
|
|
634
|
+
*/
|
|
635
|
+
const getConfirmLinkCursorPos = (tree, valueType, currentChain, chain, schema, cursorIdx) => {
|
|
636
|
+
const astChain = findChainAtCursor(tree, cursorIdx, valueType);
|
|
637
|
+
if (!astChain) return null;
|
|
638
|
+
const isFunction = isFunctionSchema(schema ?? {});
|
|
639
|
+
const targetLink = astChain.children.filter(isMethodChainNode)[currentChain.links.length];
|
|
640
|
+
if (!targetLink || targetLink.name !== chain.name) return null;
|
|
641
|
+
if (isFunction && (targetLink.type === NodeType.Function || targetLink.type === NodeType.CustomFunction)) {
|
|
642
|
+
const parenOpen = targetLink.children.find((c) => c.type === NodeType.ParenOpen);
|
|
643
|
+
return parenOpen ? parenOpen.end : targetLink.end;
|
|
644
|
+
}
|
|
645
|
+
const linkIdxInChain = astChain.children.indexOf(targetLink);
|
|
646
|
+
const dotAfter = astChain.children[linkIdxInChain + 1];
|
|
647
|
+
return dotAfter?.type === NodeType.Dot ? dotAfter.end : targetLink.end;
|
|
648
|
+
};
|
|
649
|
+
/**
|
|
650
|
+
* Matching function for filtering chain options given a partially typed option name.
|
|
651
|
+
*
|
|
652
|
+
* TODO: Add more sophistication here (e.g. fuzzy matching, etc.)
|
|
653
|
+
*/
|
|
654
|
+
const isQueryMatch = (query, chain) => {
|
|
655
|
+
const prop = chain.property.toLowerCase();
|
|
656
|
+
if (query.startsWith("@")) return prop.startsWith(query);
|
|
657
|
+
return (prop.startsWith("@") ? prop.slice(1) : prop).startsWith(query);
|
|
658
|
+
};
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region components/SmartTextInput/listbox-options.ts
|
|
661
|
+
const CONTEXT_MENU_OPTIONS = {
|
|
662
|
+
enterMethodChainMode: {
|
|
663
|
+
label: "trigger.id",
|
|
664
|
+
returnType: "Data path",
|
|
665
|
+
ariaLabel: "Enter data path",
|
|
666
|
+
interactive: true,
|
|
667
|
+
description: void 0
|
|
668
|
+
},
|
|
669
|
+
insertCustomCode: {
|
|
670
|
+
label: "${...}",
|
|
671
|
+
returnType: "Code expression",
|
|
672
|
+
ariaLabel: "Insert code expression",
|
|
673
|
+
interactive: true,
|
|
674
|
+
description: void 0
|
|
675
|
+
},
|
|
676
|
+
insertMethodChainHandlebars: {
|
|
677
|
+
label: "Hello, {{...}}",
|
|
678
|
+
returnType: "Data expression",
|
|
679
|
+
ariaLabel: "Insert data expression",
|
|
680
|
+
interactive: true,
|
|
681
|
+
description: void 0
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
const EXIT_METHOD_CHAIN_VALUE_TYPE_OPTION = {
|
|
685
|
+
type: "method-chain-option",
|
|
686
|
+
id: "exitMethodChainValueType",
|
|
687
|
+
ariaLabel: "Exit data path",
|
|
688
|
+
label: "Data path",
|
|
689
|
+
returnType: void 0,
|
|
690
|
+
description: void 0,
|
|
691
|
+
disabled: false,
|
|
692
|
+
interactive: true
|
|
693
|
+
};
|
|
694
|
+
const isContextMenuOption = (item) => {
|
|
695
|
+
return item.type === "context-menu-option";
|
|
696
|
+
};
|
|
697
|
+
const CONTEXT_MENU_EXAMPLE_KEY = {
|
|
698
|
+
insertCustomCode: "code",
|
|
699
|
+
insertMethodChainHandlebars: "handlebars",
|
|
700
|
+
enterMethodChainMode: "methodChain"
|
|
701
|
+
};
|
|
702
|
+
const getContextMenuOptions = (valueIsEmpty, allowedValueType, allowedInterpolationModes, examples) => {
|
|
703
|
+
return Object.entries(CONTEXT_MENU_OPTIONS).filter(([key]) => {
|
|
704
|
+
if (key === "insertCustomCode") return isInterpolationModeAllowed("code", allowedValueType, allowedInterpolationModes);
|
|
705
|
+
if (key === "insertMethodChainHandlebars") return isInterpolationModeAllowed("method-chain", allowedValueType, allowedInterpolationModes);
|
|
706
|
+
if (key === "enterMethodChainMode") return canTransitionToValueType("method-chain", allowedValueType) && valueIsEmpty;
|
|
707
|
+
return true;
|
|
708
|
+
}).map(([key, value]) => ({
|
|
709
|
+
type: "context-menu-option",
|
|
710
|
+
id: key,
|
|
711
|
+
...value,
|
|
712
|
+
label: examples?.[CONTEXT_MENU_EXAMPLE_KEY[key]] ?? value.label,
|
|
713
|
+
disabled: false
|
|
714
|
+
}));
|
|
715
|
+
};
|
|
716
|
+
const getMethodChainOptions = (options) => {
|
|
717
|
+
return options.map((option) => ({
|
|
718
|
+
type: "method-chain-option",
|
|
719
|
+
id: option.value,
|
|
720
|
+
disabled: false,
|
|
721
|
+
ariaLabel: `Select ${option.label}`,
|
|
722
|
+
label: option.label,
|
|
723
|
+
returnType: option.returnType,
|
|
724
|
+
description: option.schema.description,
|
|
725
|
+
interactive: true
|
|
726
|
+
}));
|
|
727
|
+
};
|
|
728
|
+
//#endregion
|
|
729
|
+
//#region components/SmartTextInput/SmartTextInputFunctionDialog.tsx
|
|
730
|
+
const StyledDialog = styled(Stack)`
|
|
731
|
+
height: 100%;
|
|
732
|
+
gap: 0;
|
|
733
|
+
overflow: hidden;
|
|
734
|
+
`;
|
|
735
|
+
const DialogHeading = styled.div`
|
|
736
|
+
${Typography.TextMono};
|
|
737
|
+
padding: ${Spacing[3]} ${Spacing[2]};
|
|
738
|
+
border-bottom: 1px solid ${Color.BorderDivider};
|
|
739
|
+
`;
|
|
740
|
+
const DialogContent$1 = styled(Stack)`
|
|
741
|
+
gap: 0;
|
|
742
|
+
overflow: hidden;
|
|
743
|
+
`;
|
|
744
|
+
const FormContent = styled.div`
|
|
745
|
+
padding: ${Spacing[3]};
|
|
746
|
+
overflow-y: auto;
|
|
747
|
+
`;
|
|
748
|
+
const SmartTextInputFunctionDialog = ({ id, inputRef, functionAtCursor, nextPossibleChains, chainRoots, onConfirm, onCancel, renderFunctionForm, renderCustomFunctionDetail, openCodeChainFunctionPanel }) => {
|
|
749
|
+
const ref = useRef(null);
|
|
750
|
+
const { dialogProps } = useDialog({
|
|
751
|
+
role: "dialog",
|
|
752
|
+
"aria-label": `Edit ${functionAtCursor.functionName} parameters`,
|
|
753
|
+
id
|
|
754
|
+
}, ref);
|
|
755
|
+
const { tabIndex: _tabIndex, ...restDialogProps } = dialogProps;
|
|
756
|
+
useInteractOutside({
|
|
757
|
+
ref,
|
|
758
|
+
onInteractOutside: (e) => {
|
|
759
|
+
if (inputRef.current?.contains(e.target)) return;
|
|
760
|
+
if (e.target?.closest("#combobox-dropdown-portal-wrapper")) return;
|
|
761
|
+
onCancel();
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
const functionSchema = useMemo(() => {
|
|
765
|
+
for (const opt of nextPossibleChains) if (opt.property === functionAtCursor.functionName && isFunctionSchema(opt.schema)) {
|
|
766
|
+
const ccfToken = "codeChainFunctionToken" in opt.schema ? opt.schema.codeChainFunctionToken : void 0;
|
|
767
|
+
return {
|
|
768
|
+
schema: opt.schema,
|
|
769
|
+
parentSchema: isJsonSchemaArray(opt.parentSchema) ? opt.parentSchema.items : opt.parentSchema,
|
|
770
|
+
ccfToken
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
}, [functionAtCursor, nextPossibleChains]);
|
|
774
|
+
return /* @__PURE__ */ jsxs(StyledDialog, {
|
|
775
|
+
ref,
|
|
776
|
+
...restDialogProps,
|
|
777
|
+
children: [/* @__PURE__ */ jsx(DialogHeading, { children: functionAtCursor.functionName }), /* @__PURE__ */ jsx(DialogContent$1, { children: functionSchema != null ? functionAtCursor.custom && functionSchema.ccfToken != null ? renderCustomFunctionDetail?.({
|
|
778
|
+
token: functionSchema.ccfToken,
|
|
779
|
+
name: functionAtCursor.functionName,
|
|
780
|
+
onCancel,
|
|
781
|
+
onEdit: openCodeChainFunctionPanel
|
|
782
|
+
}) : renderFunctionForm?.({
|
|
783
|
+
baseId: id,
|
|
784
|
+
functionName: functionAtCursor.functionName,
|
|
785
|
+
schema: functionSchema.schema,
|
|
786
|
+
parentItemSchema: functionSchema.parentSchema,
|
|
787
|
+
receiverSchema: functionSchema.parentSchema,
|
|
788
|
+
defaultParameters: functionAtCursor.existingParams,
|
|
789
|
+
chainRoots,
|
|
790
|
+
onComplete: onConfirm,
|
|
791
|
+
onCancel
|
|
792
|
+
}) : /* @__PURE__ */ jsx(FormContent, { children: /* @__PURE__ */ jsxs(Paragraph, {
|
|
793
|
+
size: "sm",
|
|
794
|
+
children: [
|
|
795
|
+
"Could not find a valid schema for the function ",
|
|
796
|
+
functionAtCursor.functionName,
|
|
797
|
+
"."
|
|
798
|
+
]
|
|
799
|
+
}) }) })]
|
|
800
|
+
});
|
|
801
|
+
};
|
|
802
|
+
//#endregion
|
|
803
|
+
//#region components/SmartTextInput/SmartTextInputCodeDialog.tsx
|
|
804
|
+
const DialogContent = styled.div`
|
|
805
|
+
padding: ${Spacing[3]};
|
|
806
|
+
overflow-y: auto;
|
|
807
|
+
flex: 1;
|
|
808
|
+
${Typography.TextMono};
|
|
809
|
+
color: ${Color.TextSecondary};
|
|
810
|
+
`;
|
|
811
|
+
const DialogFooter = styled.div`
|
|
812
|
+
padding: ${Spacing[2]};
|
|
813
|
+
border-top: 1px solid ${Color.BorderDivider};
|
|
814
|
+
`;
|
|
815
|
+
const SmartTextInputCodeDialog = ({ id, inputRef, onConfirm, onCancel }) => {
|
|
816
|
+
const ref = useRef(null);
|
|
817
|
+
const { dialogProps } = useDialog({
|
|
818
|
+
role: "dialog",
|
|
819
|
+
"aria-label": "Edit code expression",
|
|
820
|
+
id
|
|
821
|
+
}, ref);
|
|
822
|
+
const { tabIndex: _tabIndex, ...restDialogProps } = dialogProps;
|
|
823
|
+
useInteractOutside({
|
|
824
|
+
ref,
|
|
825
|
+
onInteractOutside: (e) => {
|
|
826
|
+
if (inputRef.current?.contains(e.target)) return;
|
|
827
|
+
onCancel();
|
|
828
|
+
}
|
|
829
|
+
});
|
|
830
|
+
return /* @__PURE__ */ jsxs(StyledDialog, {
|
|
831
|
+
ref,
|
|
832
|
+
...restDialogProps,
|
|
833
|
+
children: [
|
|
834
|
+
/* @__PURE__ */ jsx(DialogHeading, { children: "Code" }),
|
|
835
|
+
/* @__PURE__ */ jsx(DialogContent, { children: /* @__PURE__ */ jsx("div", {
|
|
836
|
+
style: {
|
|
837
|
+
minHeight: "100px",
|
|
838
|
+
width: "100%",
|
|
839
|
+
display: "flex",
|
|
840
|
+
justifyContent: "center",
|
|
841
|
+
alignItems: "center"
|
|
842
|
+
},
|
|
843
|
+
children: "--Code editor goes here--"
|
|
844
|
+
}) }),
|
|
845
|
+
/* @__PURE__ */ jsx(DialogFooter, { children: /* @__PURE__ */ jsxs(HStack, {
|
|
846
|
+
justify: "flex-end",
|
|
847
|
+
spacing: Spacing[1],
|
|
848
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
849
|
+
onClick: onCancel,
|
|
850
|
+
width: "auto",
|
|
851
|
+
size: "sm",
|
|
852
|
+
variant: "basic",
|
|
853
|
+
children: "Cancel"
|
|
854
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
855
|
+
onClick: onConfirm,
|
|
856
|
+
width: "auto",
|
|
857
|
+
size: "sm",
|
|
858
|
+
variant: "primary",
|
|
859
|
+
children: "Confirm"
|
|
860
|
+
})]
|
|
861
|
+
}) })
|
|
862
|
+
]
|
|
863
|
+
});
|
|
864
|
+
};
|
|
865
|
+
//#endregion
|
|
866
|
+
//#region components/SmartTextInput/SmartTextInputPopover.tsx
|
|
867
|
+
const PopoverContainer = styled.div`
|
|
868
|
+
${({ $isDialog }) => $isDialog ? css`
|
|
869
|
+
min-width: 340px;
|
|
870
|
+
max-width: 400px;
|
|
871
|
+
` : css`
|
|
872
|
+
min-width: 320px;
|
|
873
|
+
max-width: 380px;
|
|
874
|
+
`}
|
|
875
|
+
overflow: hidden;
|
|
876
|
+
display: flex;
|
|
877
|
+
flex-direction: column;
|
|
878
|
+
position: ${({ $position = "absolute" }) => $position};
|
|
879
|
+
border-radius: 4px;
|
|
880
|
+
border: 1px solid ${Color.BorderDivider};
|
|
881
|
+
box-shadow: ${"0px 4px 5px 0px rgba(0, 0, 0, 0.08), 0px 3px 14px 0px rgba(0, 0, 0, 0.04), 0px 8px 10px 0px rgba(0, 0, 0, 0.04)"};
|
|
882
|
+
background: ${Color.BackgroundPrimary};
|
|
883
|
+
font-size: ${Typography.TextMono.fontSize};
|
|
884
|
+
font-family: ${Typography.TextMono.fontFamily};
|
|
885
|
+
`;
|
|
886
|
+
const DialogFocusHandle = forwardRef(function DialogFocusHandle(_props, ref) {
|
|
887
|
+
const focusManager = useFocusManager();
|
|
888
|
+
useImperativeHandle(ref, () => ({ focusFirst: () => {
|
|
889
|
+
focusManager?.focusFirst({ tabbable: true });
|
|
890
|
+
} }), [focusManager]);
|
|
891
|
+
return null;
|
|
892
|
+
});
|
|
893
|
+
const FooterContainer = styled.div`
|
|
894
|
+
border-top: 1px solid ${Color.BorderDivider};
|
|
895
|
+
padding: ${Spacing[1]};
|
|
896
|
+
`;
|
|
897
|
+
const SmartTextInputPopover = ({ id, children, comboboxState, inputRef, popoverRef, variant, portalContainerRef, dialogFocusRef, isDialog, onDialogClose, footer }) => {
|
|
898
|
+
const { popoverProps } = usePopover({
|
|
899
|
+
triggerRef: inputRef,
|
|
900
|
+
popoverRef,
|
|
901
|
+
placement: "bottom start",
|
|
902
|
+
offset: variant === "table-cell" ? 1 : 4,
|
|
903
|
+
isNonModal: true,
|
|
904
|
+
maxHeight: isDialog ? 375 : 295,
|
|
905
|
+
shouldCloseOnInteractOutside: (element) => !element.closest("#combobox-dropdown-portal-wrapper")
|
|
906
|
+
}, {
|
|
907
|
+
...comboboxState,
|
|
908
|
+
close: () => {
|
|
909
|
+
onDialogClose();
|
|
910
|
+
}
|
|
911
|
+
});
|
|
912
|
+
const [popoverWidth, setPopoverWidth] = useState(void 0);
|
|
913
|
+
useLayoutEffect(() => {
|
|
914
|
+
if (comboboxState.isOpen) setPopoverWidth(inputRef.current?.scrollWidth);
|
|
915
|
+
}, [comboboxState.isOpen, inputRef]);
|
|
916
|
+
if (!comboboxState.isOpen) return null;
|
|
917
|
+
const render = () => {
|
|
918
|
+
return /* @__PURE__ */ jsx(PopoverContainer, {
|
|
919
|
+
...popoverProps,
|
|
920
|
+
ref: popoverRef,
|
|
921
|
+
$isDialog: isDialog,
|
|
922
|
+
id,
|
|
923
|
+
style: {
|
|
924
|
+
zIndex: Z_INDICES.modalDropdown,
|
|
925
|
+
width: popoverWidth
|
|
926
|
+
},
|
|
927
|
+
children: /* @__PURE__ */ jsxs(FocusScope, {
|
|
928
|
+
contain: isDialog,
|
|
929
|
+
children: [
|
|
930
|
+
dialogFocusRef && /* @__PURE__ */ jsx(DialogFocusHandle, { ref: dialogFocusRef }),
|
|
931
|
+
children,
|
|
932
|
+
!isDialog && footer != null && /* @__PURE__ */ jsx(FooterContainer, { children: footer })
|
|
933
|
+
]
|
|
934
|
+
})
|
|
935
|
+
});
|
|
936
|
+
};
|
|
937
|
+
if (portalContainerRef === null) return render();
|
|
938
|
+
else return createPortal(render(), portalContainerRef ?? document.body);
|
|
939
|
+
};
|
|
940
|
+
//#endregion
|
|
941
|
+
//#region components/SmartTextInput/SmartTextInputListbox.tsx
|
|
942
|
+
const EmptyOptionList = styled.div`
|
|
943
|
+
display: flex;
|
|
944
|
+
align-items: center;
|
|
945
|
+
justify-content: center;
|
|
946
|
+
${Typography.TextMono};
|
|
947
|
+
color: ${Color.TextSecondary};
|
|
948
|
+
padding: ${Spacing[4]} ${Spacing[5]};
|
|
949
|
+
`;
|
|
950
|
+
const StyledArrowLeftIcon = styled(ArrowLeftIcon$1)`
|
|
951
|
+
border-radius: 3px;
|
|
952
|
+
`;
|
|
953
|
+
const StyledListBox = styled.div`
|
|
954
|
+
flex: 1;
|
|
955
|
+
min-height: 0;
|
|
956
|
+
overflow-y: auto;
|
|
957
|
+
`;
|
|
958
|
+
const OptionDescription = styled.div`
|
|
959
|
+
${Typography.TextSmall};
|
|
960
|
+
color: ${Color.TextSecondary};
|
|
961
|
+
padding: 2px 0; // Added to containers/gap 4px padding to equal 6px
|
|
962
|
+
`;
|
|
963
|
+
const OptionLabel = styled.div`
|
|
964
|
+
${Typography.TextMono};
|
|
965
|
+
font-size: 12px;
|
|
966
|
+
line-height: 16px;
|
|
967
|
+
|
|
968
|
+
color: ${({ $heading }) => $heading ? Color.TextSecondary : Color.TextPrimary};
|
|
969
|
+
`;
|
|
970
|
+
const StyledListboxOption = styled.div`
|
|
971
|
+
display: flex;
|
|
972
|
+
flex-direction: column;
|
|
973
|
+
gap: ${Spacing[1]};
|
|
974
|
+
padding: ${Spacing[1]} ${Spacing[2]};
|
|
975
|
+
border-bottom: ${({ $bottomBorder }) => $bottomBorder ? `1px solid ${Color.BorderDivider}` : "none"};
|
|
976
|
+
|
|
977
|
+
${OptionDescription} {
|
|
978
|
+
display: none;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
${({ $interactive, $iconFocus }) => $interactive && css`
|
|
983
|
+
&:not([aria-disabled='true']) {
|
|
984
|
+
cursor: pointer;
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
&[aria-disabled='true'] ${OptionLabel} {
|
|
988
|
+
color: ${Color.TextDisabled};
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
&[data-focused='true'] {
|
|
992
|
+
${$iconFocus ? css`
|
|
993
|
+
${StyledArrowLeftIcon} {
|
|
994
|
+
background-color: ${Color.CoreSlate100};
|
|
995
|
+
}
|
|
996
|
+
` : css`
|
|
997
|
+
background-color: ${Color.BackgroundSecondary};
|
|
998
|
+
`}
|
|
999
|
+
|
|
1000
|
+
${OptionDescription} {
|
|
1001
|
+
display: block;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
`}
|
|
1005
|
+
`;
|
|
1006
|
+
const buildTextModeHeading = (nodes) => {
|
|
1007
|
+
const parts = [];
|
|
1008
|
+
for (const node of nodes) if (node.value?.id === "insertCustomCode") parts.push("Code expression");
|
|
1009
|
+
else if (node.value?.id === "insertMethodChainHandlebars") parts.push("Data expression");
|
|
1010
|
+
else if (node.value?.id === "enterMethodChainMode") parts.push("Data path");
|
|
1011
|
+
parts.push("String");
|
|
1012
|
+
return parts.join(", ");
|
|
1013
|
+
};
|
|
1014
|
+
const ListboxOption = ({ item, state }) => {
|
|
1015
|
+
const ref = useRef(null);
|
|
1016
|
+
const { optionProps, isFocused } = useOption({ key: item.id }, state, ref);
|
|
1017
|
+
if (isContextMenuOption(item)) return /* @__PURE__ */ jsxs(StyledListboxOption, {
|
|
1018
|
+
$interactive: item.interactive,
|
|
1019
|
+
ref,
|
|
1020
|
+
...optionProps,
|
|
1021
|
+
"aria-label": item.ariaLabel,
|
|
1022
|
+
"aria-disabled": item.disabled || !item.interactive ? "true" : "false",
|
|
1023
|
+
"data-focused": isFocused ? "true" : "false",
|
|
1024
|
+
children: [/* @__PURE__ */ jsxs(HStack, {
|
|
1025
|
+
justify: "space-between",
|
|
1026
|
+
children: [/* @__PURE__ */ jsx(OptionLabel, { children: item.disabled ? /* @__PURE__ */ jsx("span", { children: item.label }) : /* @__PURE__ */ jsx(HighlightedText, {
|
|
1027
|
+
value: item.label,
|
|
1028
|
+
tree: safeParse(item.label, {
|
|
1029
|
+
startRule: item.id === "enterMethodChainMode" ? "ChainRoot" : "Root",
|
|
1030
|
+
allowHandlebars: true,
|
|
1031
|
+
allowCode: true
|
|
1032
|
+
}),
|
|
1033
|
+
focused: false,
|
|
1034
|
+
interactive: false,
|
|
1035
|
+
schemaValidator: () => null,
|
|
1036
|
+
onLinkMouseDown: () => {},
|
|
1037
|
+
dontHighlightErrors: true
|
|
1038
|
+
}) }), /* @__PURE__ */ jsx(PillType, { children: item.returnType })]
|
|
1039
|
+
}), item.description && /* @__PURE__ */ jsx(OptionDescription, { children: item.description })]
|
|
1040
|
+
});
|
|
1041
|
+
else {
|
|
1042
|
+
const isExitMethodChainOption = item.id === EXIT_METHOD_CHAIN_VALUE_TYPE_OPTION.id;
|
|
1043
|
+
return /* @__PURE__ */ jsxs(StyledListboxOption, {
|
|
1044
|
+
$interactive: true,
|
|
1045
|
+
$bottomBorder: isExitMethodChainOption,
|
|
1046
|
+
$iconFocus: isExitMethodChainOption,
|
|
1047
|
+
ref,
|
|
1048
|
+
...optionProps,
|
|
1049
|
+
"aria-label": item.ariaLabel,
|
|
1050
|
+
"data-focused": isFocused ? "true" : "false",
|
|
1051
|
+
children: [/* @__PURE__ */ jsxs(HStack, {
|
|
1052
|
+
justify: "space-between",
|
|
1053
|
+
children: [isExitMethodChainOption ? /* @__PURE__ */ jsx(OptionLabel, {
|
|
1054
|
+
$heading: true,
|
|
1055
|
+
children: /* @__PURE__ */ jsxs(HStack, {
|
|
1056
|
+
align: "center",
|
|
1057
|
+
justify: "center",
|
|
1058
|
+
children: [/* @__PURE__ */ jsx(StyledArrowLeftIcon, {}), item.label]
|
|
1059
|
+
})
|
|
1060
|
+
}) : /* @__PURE__ */ jsx(OptionLabel, { children: item.label }), item.returnType && /* @__PURE__ */ jsx(PillType, { children: item.returnType })]
|
|
1061
|
+
}), item.description && /* @__PURE__ */ jsx(OptionDescription, { children: item.description })]
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
};
|
|
1065
|
+
const SmartTextInputListbox = ({ comboboxState, listBoxRef, listBoxProps, mode, isLoading, openCodeChainFunctionPanel }) => {
|
|
1066
|
+
const listBox = useListBox({
|
|
1067
|
+
...listBoxProps,
|
|
1068
|
+
"aria-label": mode === "text" ? "Context menu" : "Data path options"
|
|
1069
|
+
}, comboboxState, listBoxRef);
|
|
1070
|
+
const nodes = [...comboboxState.collection];
|
|
1071
|
+
return /* @__PURE__ */ jsxs(StyledListBox, {
|
|
1072
|
+
ref: listBoxRef,
|
|
1073
|
+
...listBox.listBoxProps,
|
|
1074
|
+
children: [
|
|
1075
|
+
mode === "method-chain" && nodes[0]?.value?.id !== "exitMethodChainValueType" && /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(StyledListboxOption, {
|
|
1076
|
+
$bottomBorder: true,
|
|
1077
|
+
children: /* @__PURE__ */ jsx(OptionLabel, {
|
|
1078
|
+
$heading: true,
|
|
1079
|
+
children: "Data path"
|
|
1080
|
+
})
|
|
1081
|
+
}) }),
|
|
1082
|
+
mode === "text" && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(StyledListboxOption, {
|
|
1083
|
+
$bottomBorder: true,
|
|
1084
|
+
children: /* @__PURE__ */ jsx(OptionLabel, {
|
|
1085
|
+
$heading: true,
|
|
1086
|
+
children: buildTextModeHeading(nodes)
|
|
1087
|
+
})
|
|
1088
|
+
}), /* @__PURE__ */ jsx(StyledListboxOption, { children: /* @__PURE__ */ jsx(OptionLabel, {
|
|
1089
|
+
$heading: true,
|
|
1090
|
+
children: "Modes"
|
|
1091
|
+
}) })] }),
|
|
1092
|
+
nodes.length === 0 || mode !== "text" && isLoading ? /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(EmptyOptionList, { children: "No options available" }), openCodeChainFunctionPanel && /* @__PURE__ */ jsx(FooterContainer, { children: /* @__PURE__ */ jsx(Button, {
|
|
1093
|
+
variant: "basic",
|
|
1094
|
+
size: "sm",
|
|
1095
|
+
onClick: openCodeChainFunctionPanel,
|
|
1096
|
+
children: "Create custom chain"
|
|
1097
|
+
}) })] }) : nodes.map((node) => node.value ? /* @__PURE__ */ jsx(ListboxOption, {
|
|
1098
|
+
item: node.value,
|
|
1099
|
+
state: comboboxState
|
|
1100
|
+
}, node.key) : null)
|
|
1101
|
+
]
|
|
1102
|
+
});
|
|
1103
|
+
};
|
|
1104
|
+
//#endregion
|
|
1105
|
+
//#region components/SmartTextInput/useChainAtCursor.ts
|
|
1106
|
+
/**
|
|
1107
|
+
* Extracts the chain context at the cursor position in a single pass.
|
|
1108
|
+
*
|
|
1109
|
+
* Returns:
|
|
1110
|
+
* - `chainString`: dot-joined names of all identifier links that end strictly
|
|
1111
|
+
* before the cursor. The link at or containing the cursor is excluded so
|
|
1112
|
+
* that `useChain` resolves the PARENT's options.
|
|
1113
|
+
* When `assumeOnNextLink` is true, the link at the cursor IS included so
|
|
1114
|
+
* that `useChain` resolves that link's children instead.
|
|
1115
|
+
* - `partialQuery`: partial text typed for the link at the cursor, used to
|
|
1116
|
+
* filter the dropdown. Always '' when `assumeOnNextLink` is true.
|
|
1117
|
+
*
|
|
1118
|
+
* Examples (cursor position denoted by |, normal mode):
|
|
1119
|
+
* `trigger.|` → { chainString: "trigger", partialQuery: "" }
|
|
1120
|
+
* `trigger.case.|` → { chainString: "trigger.case", partialQuery: "" }
|
|
1121
|
+
* `trigger.cas|e` → { chainString: "trigger", partialQuery: "cas" }
|
|
1122
|
+
* `trigger.case|` → { chainString: "trigger", partialQuery: "case" }
|
|
1123
|
+
* `trigger|` → { chainString: "", partialQuery: "trigger" }
|
|
1124
|
+
* `tri|gger` → { chainString: "", partialQuery: "tri" }
|
|
1125
|
+
*/
|
|
1126
|
+
function extractChainContextAtCursor(tree, cursorIdx, valueType, assumeOnNextLink) {
|
|
1127
|
+
const chainNode = findChainAtCursor(tree, cursorIdx, valueType);
|
|
1128
|
+
if (!chainNode) return {
|
|
1129
|
+
chainString: "",
|
|
1130
|
+
partialQuery: ""
|
|
1131
|
+
};
|
|
1132
|
+
const idx = cursorIdx ?? 0;
|
|
1133
|
+
let cutoffIdx = chainNode.children.length;
|
|
1134
|
+
let partialQuery = "";
|
|
1135
|
+
for (let i = 0; i < chainNode.children.length; i++) {
|
|
1136
|
+
const link = chainNode.children[i];
|
|
1137
|
+
if (link.type === NodeType.Error && link.kind === "trailingAtSign") {
|
|
1138
|
+
if (!assumeOnNextLink) {
|
|
1139
|
+
partialQuery = "@";
|
|
1140
|
+
cutoffIdx = i;
|
|
1141
|
+
}
|
|
1142
|
+
break;
|
|
1143
|
+
}
|
|
1144
|
+
if (link.type !== NodeType.Identifier && link.type !== NodeType.Function && link.type !== NodeType.CustomFunction) continue;
|
|
1145
|
+
let shouldInclude = assumeOnNextLink ? link.end <= idx : link.end < idx;
|
|
1146
|
+
if (shouldInclude && (link.type === NodeType.Function || link.type === NodeType.CustomFunction)) {
|
|
1147
|
+
const fn = link;
|
|
1148
|
+
const parenOpen = fn.children.find((c) => c.type === NodeType.ParenOpen);
|
|
1149
|
+
const hasParenClose = fn.children.some((c) => c.type === NodeType.ParenClose);
|
|
1150
|
+
if (parenOpen && !hasParenClose && parenOpen.end <= idx) shouldInclude = false;
|
|
1151
|
+
}
|
|
1152
|
+
if (!shouldInclude) {
|
|
1153
|
+
cutoffIdx = i;
|
|
1154
|
+
if (!assumeOnNextLink && link.start < idx) partialQuery = link.name.slice(0, Math.min(idx - link.start, link.name.length));
|
|
1155
|
+
break;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
return {
|
|
1159
|
+
chainString: methodChainToString(normalizeChain({
|
|
1160
|
+
...chainNode,
|
|
1161
|
+
children: chainNode.children.slice(0, cutoffIdx)
|
|
1162
|
+
})),
|
|
1163
|
+
partialQuery
|
|
1164
|
+
};
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* Resolves schema-driven method chain options for the current cursor
|
|
1168
|
+
* position in a SmartTextInput.
|
|
1169
|
+
*
|
|
1170
|
+
* Wraps `useChain` with cursor-aware chain extraction: it reads the AST to
|
|
1171
|
+
* determine which chain context the cursor is in (inside `{{...}}`, inside
|
|
1172
|
+
* `${...}`, or a bare top-level chain), derives the partial chain string
|
|
1173
|
+
* representing all links before the cursor, and returns the next possible
|
|
1174
|
+
* options from the schema.
|
|
1175
|
+
*
|
|
1176
|
+
* When `chainConfig` is absent, returns an empty options list.
|
|
1177
|
+
*/
|
|
1178
|
+
const useChainAtCursor = ({ value, onUpdateChain, tree, cursorIdx, valueType, assumeOnNextLink = false, useChainRootDescriptions, chainRoots, primitivesSchema, platformObjectJsonSchema, defaultPrimitiveUtilities, codeChainFunctionSchema, getSchemaOptionsOverride, sortOptionsBy }) => {
|
|
1179
|
+
const { chainString, partialQuery } = extractChainContextAtCursor(tree, cursorIdx, valueType, assumeOnNextLink);
|
|
1180
|
+
const [currentChain, { appendChain, commitChain, nextPossibleChains, resolveSchema, currentSchema }] = useChain({
|
|
1181
|
+
chainString,
|
|
1182
|
+
chainRoots,
|
|
1183
|
+
primitivesSchema,
|
|
1184
|
+
platformObjectJsonSchema,
|
|
1185
|
+
defaultPrimitiveUtilities,
|
|
1186
|
+
codeChainFunctionSchema,
|
|
1187
|
+
useChainRootDescriptions,
|
|
1188
|
+
getSchemaOptionsOverride,
|
|
1189
|
+
onUpdateChain: (newChainString, meta) => {
|
|
1190
|
+
if (meta.isFunction) newChainString = newChainString + "()";
|
|
1191
|
+
const { newValue, newCursorIdx: rawCursorIdx } = replaceChainAtCursor(value, valueType, cursorIdx, tree, newChainString);
|
|
1192
|
+
onUpdateChain(newValue, meta.isFunction ? rawCursorIdx - 1 : rawCursorIdx);
|
|
1193
|
+
}
|
|
1194
|
+
});
|
|
1195
|
+
const nextPossibleChainsSorted = useMemo(() => {
|
|
1196
|
+
let chains = nextPossibleChains;
|
|
1197
|
+
if (partialQuery) {
|
|
1198
|
+
const query = partialQuery.toLowerCase();
|
|
1199
|
+
chains = chains.filter((item) => isQueryMatch(query, item));
|
|
1200
|
+
}
|
|
1201
|
+
if (!sortOptionsBy) return chains;
|
|
1202
|
+
return [...chains].sort((a, b) => sortOptionsBy(a) - sortOptionsBy(b));
|
|
1203
|
+
}, [
|
|
1204
|
+
nextPossibleChains,
|
|
1205
|
+
partialQuery,
|
|
1206
|
+
sortOptionsBy
|
|
1207
|
+
]);
|
|
1208
|
+
const insertChainAtCursor = (nodes) => {
|
|
1209
|
+
const fullChainNode = findChainAtCursor(tree, cursorIdx, valueType);
|
|
1210
|
+
if (fullChainNode == null) {
|
|
1211
|
+
appendChain(nodes);
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
const suffix = normalizeChain(fullChainNode).links.slice(currentChain.links.length + nodes.length);
|
|
1215
|
+
commitChain(methodChainToString({
|
|
1216
|
+
type: NodeType.Chain,
|
|
1217
|
+
links: [
|
|
1218
|
+
...currentChain.links,
|
|
1219
|
+
...nodes,
|
|
1220
|
+
...suffix
|
|
1221
|
+
]
|
|
1222
|
+
}));
|
|
1223
|
+
};
|
|
1224
|
+
return [currentChain, {
|
|
1225
|
+
appendChain,
|
|
1226
|
+
insertChainAtCursor,
|
|
1227
|
+
nextPossibleChains: nextPossibleChainsSorted,
|
|
1228
|
+
resolveSchema,
|
|
1229
|
+
currentSchema,
|
|
1230
|
+
query: partialQuery
|
|
1231
|
+
}];
|
|
1232
|
+
};
|
|
1233
|
+
//#endregion
|
|
1234
|
+
//#region components/SmartTextInput/useCodeChainFunctionPanel.tsx
|
|
1235
|
+
/**
|
|
1236
|
+
* Manages opening and rendering the CCF editing panel.
|
|
1237
|
+
*/
|
|
1238
|
+
const useCodeChainFunctionPanel = ({ enabled, canCreate, renderPanel: renderPanelContent, onOpen, onSaveNew }) => {
|
|
1239
|
+
const [panelProps, setPanelProps] = useState(null);
|
|
1240
|
+
const closePanel = useCallback(({ savedName } = {}) => {
|
|
1241
|
+
setPanelProps(null);
|
|
1242
|
+
if (savedName) onSaveNew(savedName);
|
|
1243
|
+
}, [onSaveNew]);
|
|
1244
|
+
const renderPanel = useCallback(() => {
|
|
1245
|
+
return panelProps != null && renderPanelContent != null ? renderPanelContent({
|
|
1246
|
+
...panelProps,
|
|
1247
|
+
onClose: closePanel
|
|
1248
|
+
}) : null;
|
|
1249
|
+
}, [
|
|
1250
|
+
panelProps,
|
|
1251
|
+
closePanel,
|
|
1252
|
+
renderPanelContent
|
|
1253
|
+
]);
|
|
1254
|
+
const openPanel = useCallback((panelProps) => {
|
|
1255
|
+
setPanelProps(panelProps);
|
|
1256
|
+
onOpen();
|
|
1257
|
+
}, [onOpen]);
|
|
1258
|
+
return {
|
|
1259
|
+
renderPanel,
|
|
1260
|
+
openPanel: enabled && canCreate && renderPanelContent != null ? openPanel : void 0
|
|
1261
|
+
};
|
|
1262
|
+
};
|
|
1263
|
+
//#endregion
|
|
1264
|
+
//#region components/SmartTextInput/validation.tsx
|
|
1265
|
+
const SchemaErrorMessage = styled.span`
|
|
1266
|
+
display: inline-flex;
|
|
1267
|
+
align-items: center;
|
|
1268
|
+
gap: ${Spacing[1]};
|
|
1269
|
+
`;
|
|
1270
|
+
function validateFunctionParams(link, parentSchema, platformObjectJsonSchema, primitiveUtilities) {
|
|
1271
|
+
if (!link.children.some((c) => c.type === NodeType.ParenClose)) return null;
|
|
1272
|
+
const funcSchema = getFunctionSchemaForNode({
|
|
1273
|
+
parentSchema,
|
|
1274
|
+
functionName: link.type === NodeType.CustomFunction ? `@${link.name}` : link.name,
|
|
1275
|
+
isCustomFunction: link.type === NodeType.CustomFunction,
|
|
1276
|
+
platformObjectJsonSchema: platformObjectJsonSchema ?? {},
|
|
1277
|
+
primitiveUtilities: primitiveUtilities ?? {}
|
|
1278
|
+
});
|
|
1279
|
+
if (funcSchema == null) return {
|
|
1280
|
+
start: link.start,
|
|
1281
|
+
end: link.end,
|
|
1282
|
+
name: link.name
|
|
1283
|
+
};
|
|
1284
|
+
const expectedParamCount = Object.keys(funcSchema.properties.parameterTypes.properties).length;
|
|
1285
|
+
const actualParamCount = link.children.filter((c) => c.type === NodeType.Chain || c.type === NodeType.String || c.type === NodeType.Number || c.type === NodeType.Array).length;
|
|
1286
|
+
if (expectedParamCount !== actualParamCount) return {
|
|
1287
|
+
start: link.start,
|
|
1288
|
+
end: link.end,
|
|
1289
|
+
name: link.name,
|
|
1290
|
+
message: `has ${expectedParamCount} parameter, but ${actualParamCount} were provided.`
|
|
1291
|
+
};
|
|
1292
|
+
return null;
|
|
1293
|
+
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Returns the first chain identifier span that fails schema validation, walking
|
|
1296
|
+
* all chains left-to-right. Once the first invalid link is found, subsequent
|
|
1297
|
+
* links are meaningless and validation stops.
|
|
1298
|
+
*/
|
|
1299
|
+
function findSchemaErrors(tree, rootSchema, platformObjectJsonSchema, primitiveUtilities) {
|
|
1300
|
+
const nodes = findAll(tree, NodeType.Chain).filter(isASTChainNode);
|
|
1301
|
+
for (const chainNode of nodes) {
|
|
1302
|
+
const identifierLinks = chainNode.children.filter(isMethodChainNode);
|
|
1303
|
+
let prevSchema = rootSchema;
|
|
1304
|
+
for (const [linkIndex, link] of identifierLinks.entries()) {
|
|
1305
|
+
const { schema } = getSchemaForFieldPath({
|
|
1306
|
+
path: methodChainToString(normalizeChain({
|
|
1307
|
+
...chainNode,
|
|
1308
|
+
children: identifierLinks.slice(0, linkIndex + 1)
|
|
1309
|
+
})).replace(/^\./, ""),
|
|
1310
|
+
initialSchema: rootSchema,
|
|
1311
|
+
platformObjectJsonSchema,
|
|
1312
|
+
primitiveUtilities
|
|
1313
|
+
});
|
|
1314
|
+
if (schema == null) {
|
|
1315
|
+
if (link.type === NodeType.CustomFunction && (getNonNullableRefSchema(prevSchema) != null || getNonNullableType(prevSchema) != null)) {
|
|
1316
|
+
const fn = getFunctionSchemaForNode({
|
|
1317
|
+
parentSchema: prevSchema,
|
|
1318
|
+
functionName: `@${link.name}`,
|
|
1319
|
+
isCustomFunction: true,
|
|
1320
|
+
platformObjectJsonSchema: platformObjectJsonSchema ?? {},
|
|
1321
|
+
primitiveUtilities: primitiveUtilities ?? {}
|
|
1322
|
+
});
|
|
1323
|
+
if (fn != null && fn.acceptsNullReceiver !== true) return {
|
|
1324
|
+
start: link.start,
|
|
1325
|
+
end: link.end,
|
|
1326
|
+
name: link.name,
|
|
1327
|
+
message: "does not accept a possibly null value."
|
|
1328
|
+
};
|
|
1329
|
+
}
|
|
1330
|
+
return {
|
|
1331
|
+
start: link.start,
|
|
1332
|
+
end: link.end,
|
|
1333
|
+
name: link.name
|
|
1334
|
+
};
|
|
1335
|
+
}
|
|
1336
|
+
if (isAnyASTFunctionNode(link)) {
|
|
1337
|
+
const paramError = validateFunctionParams(link, prevSchema, platformObjectJsonSchema, primitiveUtilities);
|
|
1338
|
+
if (paramError != null) return paramError;
|
|
1339
|
+
}
|
|
1340
|
+
prevSchema = schema;
|
|
1341
|
+
}
|
|
1342
|
+
const hasIncomplete = findAll(chainNode, NodeType.Error).some((c) => c.wip);
|
|
1343
|
+
const enclosing = enclosingExpr(tree, chainNode);
|
|
1344
|
+
const inClosedHandlebars = enclosing?.type === NodeType.Handlebars && !enclosing.children?.some((c) => c.type === NodeType.Error && c.kind === "unclosedHandlebars");
|
|
1345
|
+
if (!hasIncomplete && identifierLinks.length > 0 && inClosedHandlebars) {
|
|
1346
|
+
if (!isSchemaTypeAllowed(prevSchema, JsonSchemaStringifiableTypes)) {
|
|
1347
|
+
const lastLink = identifierLinks[identifierLinks.length - 1];
|
|
1348
|
+
return {
|
|
1349
|
+
start: lastLink.start,
|
|
1350
|
+
end: lastLink.end,
|
|
1351
|
+
name: lastLink.name,
|
|
1352
|
+
message: "is not a string value."
|
|
1353
|
+
};
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return null;
|
|
1358
|
+
}
|
|
1359
|
+
const useSchemaValidator = ({ chainRoots, primitivesSchema, platformObjectJsonSchema, defaultPrimitiveUtilities, codeChainFunctionSchema, isLoading }) => {
|
|
1360
|
+
const { platformObjectJsonSchema: resolvedPlatformSchema, primitiveUtilities } = useChainSchema({
|
|
1361
|
+
primitivesSchema,
|
|
1362
|
+
platformObjectJsonSchema,
|
|
1363
|
+
defaultPrimitiveUtilities,
|
|
1364
|
+
codeChainFunctionSchema
|
|
1365
|
+
});
|
|
1366
|
+
const rootSchema = useMemo(() => ({
|
|
1367
|
+
type: "object",
|
|
1368
|
+
properties: Object.fromEntries(chainRoots.map((r) => [methodChainToString(r.chain), r.schema]))
|
|
1369
|
+
}), [chainRoots]);
|
|
1370
|
+
return useCallback((tree) => isLoading ? null : findSchemaErrors(tree, rootSchema, resolvedPlatformSchema, primitiveUtilities), [
|
|
1371
|
+
rootSchema,
|
|
1372
|
+
resolvedPlatformSchema,
|
|
1373
|
+
primitiveUtilities,
|
|
1374
|
+
isLoading
|
|
1375
|
+
]);
|
|
1376
|
+
};
|
|
1377
|
+
function getError(leftmostSyntaxError, leftmostIncompleteError, leftmostSchemaError, focused, valueIsEmpty) {
|
|
1378
|
+
if (leftmostSyntaxError != null) return {
|
|
1379
|
+
errorKey: `syntax:${leftmostSyntaxError.kind}`,
|
|
1380
|
+
errorText: leftmostSyntaxError.kind && ErrorMessageByKind[leftmostSyntaxError.kind] || "Syntax error"
|
|
1381
|
+
};
|
|
1382
|
+
else if (leftmostSchemaError != null && !focused) return {
|
|
1383
|
+
errorKey: `schema:${leftmostSchemaError.name}:${leftmostSchemaError.message ?? ""}`,
|
|
1384
|
+
errorText: /* @__PURE__ */ jsxs(SchemaErrorMessage, { children: [
|
|
1385
|
+
/* @__PURE__ */ jsx(PillType, {
|
|
1386
|
+
as: "span",
|
|
1387
|
+
error: true,
|
|
1388
|
+
children: leftmostSchemaError.name
|
|
1389
|
+
}),
|
|
1390
|
+
" ",
|
|
1391
|
+
leftmostSchemaError.message ?? "does not exist."
|
|
1392
|
+
] })
|
|
1393
|
+
};
|
|
1394
|
+
else if (leftmostIncompleteError != null && !focused && !valueIsEmpty) return {
|
|
1395
|
+
errorKey: `incomplete:${leftmostIncompleteError.kind}`,
|
|
1396
|
+
errorText: leftmostIncompleteError.kind && ErrorMessageByKind[leftmostIncompleteError.kind] || "Expression is incomplete"
|
|
1397
|
+
};
|
|
1398
|
+
else return {
|
|
1399
|
+
errorKey: null,
|
|
1400
|
+
errorText: null
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Calls the onValidationChange callback when the input's value is invalid in some manner based
|
|
1405
|
+
* on syntax or schema.
|
|
1406
|
+
*/
|
|
1407
|
+
const useInternalValidation = ({ tree, valueIsEmpty, focused, schemaValidator, onValidationChange, value, valueType }) => {
|
|
1408
|
+
const errorNodes = findAll(tree, NodeType.Error);
|
|
1409
|
+
let leftmostSyntaxError = errorNodes.find((e) => e.start < e.end && !e.wip);
|
|
1410
|
+
const leftmostIncompleteError = errorNodes.find((e) => e.start === e.end);
|
|
1411
|
+
const leftmostSchemaError = useMemo(() => schemaValidator(tree), [tree, schemaValidator]);
|
|
1412
|
+
if (leftmostSyntaxError != null && valueType === "method-chain" && (value.includes("{{") || value.includes("${"))) leftmostSyntaxError = {
|
|
1413
|
+
...leftmostSyntaxError,
|
|
1414
|
+
kind: "interpolationInDataPath"
|
|
1415
|
+
};
|
|
1416
|
+
const { errorKey, errorText } = getError(leftmostSyntaxError, leftmostIncompleteError, leftmostSchemaError ?? void 0, focused, valueIsEmpty);
|
|
1417
|
+
useEffect(() => {
|
|
1418
|
+
onValidationChange?.(errorText);
|
|
1419
|
+
}, [errorKey, onValidationChange]);
|
|
1420
|
+
};
|
|
1421
|
+
//#endregion
|
|
1422
|
+
//#region components/SmartTextInput/SmartTextInput.tsx
|
|
1423
|
+
const StyledInput = styled(Input_default)`
|
|
1424
|
+
${Typography.TextMono}
|
|
1425
|
+
position: relative;
|
|
1426
|
+
z-index: 2;
|
|
1427
|
+
color: transparent;
|
|
1428
|
+
background: transparent;
|
|
1429
|
+
caret-color: ${Color.TextPrimary};
|
|
1430
|
+
white-space: pre;
|
|
1431
|
+
overflow: hidden;
|
|
1432
|
+
|
|
1433
|
+
${({ size }) => size === "sm" && css`
|
|
1434
|
+
font-size: 12px;
|
|
1435
|
+
`}
|
|
1436
|
+
${({ $variant }) => $variant === "table-cell" && css`
|
|
1437
|
+
border: none;
|
|
1438
|
+
padding: 0;
|
|
1439
|
+
height: 18px;
|
|
1440
|
+
border-radius: 0;
|
|
1441
|
+
`}
|
|
1442
|
+
`;
|
|
1443
|
+
const withClosingToken = (key) => {
|
|
1444
|
+
switch (key) {
|
|
1445
|
+
case "{": return "{}";
|
|
1446
|
+
case "(": return "()";
|
|
1447
|
+
case "[": return "[]";
|
|
1448
|
+
case "'": return "''";
|
|
1449
|
+
default: assertNever(key);
|
|
1450
|
+
}
|
|
1451
|
+
};
|
|
1452
|
+
const spliceAtCursor = (value, insert, cursorIdx) => value.slice(0, cursorIdx) + insert + value.slice(cursorIdx);
|
|
1453
|
+
const getInitialValueType = (chainRoots, initialValue, allowedValueType) => {
|
|
1454
|
+
if (allowedValueType != null) return allowedValueType;
|
|
1455
|
+
return initialValue && isChainWithValidRoot(initialValue, chainRoots) ? "method-chain" : "interpolation";
|
|
1456
|
+
};
|
|
1457
|
+
/**
|
|
1458
|
+
* Smart text input for configuring access to data, interpolated strings, or inline code.
|
|
1459
|
+
*/
|
|
1460
|
+
const SmartTextInput = ({ value: passedValue, onChange, valueType: allowedValueType, allowedInterpolationModes, chainRoots, platformObjectJsonSchema, defaultPrimitiveUtilities, codeChainFunctionSchema, useChainRootDescriptions = false, primitivesSchema = "default", isLoading = false, portalContainerRef, getSchemaOptionsOverride, creatable = false, renderFunctionForm, renderCustomFunctionDetail, renderCodeChainFunctionPanel, canCreateCodeChainFunction = false, sortOptionsBy, onValidationChange, contextMenuExamples, popoverFooter, id, placeholder = "Select or type", disabled = false, size = "md", variant = "default", ...props }) => {
|
|
1461
|
+
const lastNotifiedValueRef = useRef(passedValue ?? "");
|
|
1462
|
+
const [value, setValue] = useState(passedValue ?? "");
|
|
1463
|
+
useEffect(() => {
|
|
1464
|
+
if (passedValue !== void 0 && passedValue !== lastNotifiedValueRef.current) {
|
|
1465
|
+
setValue(passedValue);
|
|
1466
|
+
lastNotifiedValueRef.current = passedValue;
|
|
1467
|
+
}
|
|
1468
|
+
}, [passedValue]);
|
|
1469
|
+
const onChangeRef = useRef(onChange);
|
|
1470
|
+
onChangeRef.current = onChange;
|
|
1471
|
+
const [cursorIdx, setCursor] = useState(null);
|
|
1472
|
+
const [valueType, setValueType] = useState(getInitialValueType(chainRoots, passedValue, allowedValueType));
|
|
1473
|
+
const [assumeOnNextLinkState, setAssumeOnNextLink] = useState(false);
|
|
1474
|
+
const [forceFunctionDialog, setForceFunctionDialog] = useState(false);
|
|
1475
|
+
const inputRef = useRef(null);
|
|
1476
|
+
const overlayRef = useRef(null);
|
|
1477
|
+
const listBoxRef = useRef(null);
|
|
1478
|
+
const popoverRef = useRef(null);
|
|
1479
|
+
const dialogFocusRef = useRef(null);
|
|
1480
|
+
const nextRenderRef = useRef({});
|
|
1481
|
+
const blockEscapePropagationRef = useRef(false);
|
|
1482
|
+
const tree = safeParse(value, {
|
|
1483
|
+
startRule: valueType === "method-chain" ? "ChainRoot" : "Root",
|
|
1484
|
+
allowHandlebars: isInterpolationModeAllowed("method-chain", allowedValueType, allowedInterpolationModes),
|
|
1485
|
+
allowCode: isInterpolationModeAllowed("code", allowedValueType, allowedInterpolationModes)
|
|
1486
|
+
});
|
|
1487
|
+
const mode = getMode(tree, valueType, cursorIdx);
|
|
1488
|
+
const suppressPopover = isCursorInExpressionToken(tree, cursorIdx, valueType);
|
|
1489
|
+
const assumeOnNextLink = assumeOnNextLinkState || isCursorAfterFunctionClose(tree, cursorIdx, valueType);
|
|
1490
|
+
useEffect(() => {
|
|
1491
|
+
if (!inputRef.current) return;
|
|
1492
|
+
const input = inputRef.current;
|
|
1493
|
+
const listener = () => {
|
|
1494
|
+
setCursor(input.selectionStart);
|
|
1495
|
+
syncScroll(inputRef, overlayRef);
|
|
1496
|
+
};
|
|
1497
|
+
input.addEventListener("selectionchange", listener);
|
|
1498
|
+
return () => {
|
|
1499
|
+
input.removeEventListener("selectionchange", listener);
|
|
1500
|
+
};
|
|
1501
|
+
}, []);
|
|
1502
|
+
const [currentChain, { appendChain, insertChainAtCursor, nextPossibleChains, resolveSchema, currentSchema, query }] = useChainAtCursor({
|
|
1503
|
+
value,
|
|
1504
|
+
tree,
|
|
1505
|
+
cursorIdx,
|
|
1506
|
+
valueType,
|
|
1507
|
+
chainRoots,
|
|
1508
|
+
primitivesSchema,
|
|
1509
|
+
platformObjectJsonSchema,
|
|
1510
|
+
defaultPrimitiveUtilities,
|
|
1511
|
+
codeChainFunctionSchema,
|
|
1512
|
+
getSchemaOptionsOverride,
|
|
1513
|
+
useChainRootDescriptions,
|
|
1514
|
+
sortOptionsBy,
|
|
1515
|
+
assumeOnNextLink,
|
|
1516
|
+
onUpdateChain: (newValue, newCursorIdx) => {
|
|
1517
|
+
setValue(newValue);
|
|
1518
|
+
nextRenderRef.current.cursor = {
|
|
1519
|
+
start: newCursorIdx,
|
|
1520
|
+
end: newCursorIdx
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
});
|
|
1524
|
+
useEffect(() => {
|
|
1525
|
+
if (value === lastNotifiedValueRef.current) return;
|
|
1526
|
+
lastNotifiedValueRef.current = value;
|
|
1527
|
+
onChangeRef.current?.(value, {
|
|
1528
|
+
valueType,
|
|
1529
|
+
schema: resolveSchema(value),
|
|
1530
|
+
ast: tree
|
|
1531
|
+
});
|
|
1532
|
+
}, [value]);
|
|
1533
|
+
const functionAtCursor = getFunctionAtCursor(tree, cursorIdx, valueType);
|
|
1534
|
+
const popupMode = functionAtCursor != null && (functionAtCursor.cursorInParens || forceFunctionDialog) ? "function-dialog" : mode === "code" ? "code-dialog" : "listbox";
|
|
1535
|
+
const comboboxItems = useMemo(() => {
|
|
1536
|
+
if (suppressPopover) return [];
|
|
1537
|
+
if (popupMode === "function-dialog" || popupMode === "code-dialog") return [];
|
|
1538
|
+
else if (mode === "text") return getContextMenuOptions(value === "", allowedValueType, allowedInterpolationModes, contextMenuExamples);
|
|
1539
|
+
else if (mode === "method-chain") {
|
|
1540
|
+
const items = getMethodChainOptions(nextPossibleChains);
|
|
1541
|
+
if (valueType === "method-chain" && canExitToInterpolation(value, allowedValueType)) items.unshift(EXIT_METHOD_CHAIN_VALUE_TYPE_OPTION);
|
|
1542
|
+
return items;
|
|
1543
|
+
} else return [];
|
|
1544
|
+
}, [
|
|
1545
|
+
valueType,
|
|
1546
|
+
allowedValueType,
|
|
1547
|
+
allowedInterpolationModes,
|
|
1548
|
+
contextMenuExamples,
|
|
1549
|
+
suppressPopover,
|
|
1550
|
+
popupMode,
|
|
1551
|
+
mode,
|
|
1552
|
+
value,
|
|
1553
|
+
nextPossibleChains
|
|
1554
|
+
]);
|
|
1555
|
+
const comboboxState = useComboBoxState({
|
|
1556
|
+
items: comboboxItems,
|
|
1557
|
+
children: (item) => /* @__PURE__ */ jsx(Item, { children: item.label }, item.id),
|
|
1558
|
+
allowsCustomValue: true,
|
|
1559
|
+
allowsEmptyCollection: true,
|
|
1560
|
+
disabledKeys: comboboxItems.filter((item) => item.disabled || !item.interactive).map((item) => item.id),
|
|
1561
|
+
menuTrigger: "focus",
|
|
1562
|
+
onOpenChange: (open, trigger) => {
|
|
1563
|
+
if (open && trigger === "input") comboboxState.setOpen(false);
|
|
1564
|
+
},
|
|
1565
|
+
selectedKey: null,
|
|
1566
|
+
onSelectionChange: (key) => {
|
|
1567
|
+
switch (mode) {
|
|
1568
|
+
case "text":
|
|
1569
|
+
switch (key) {
|
|
1570
|
+
case "insertCustomCode": {
|
|
1571
|
+
const idx = safeCursorIdx(cursorIdx, tree);
|
|
1572
|
+
setValue(spliceAtCursor(value, "${}", idx));
|
|
1573
|
+
nextRenderRef.current.cursor = {
|
|
1574
|
+
start: idx + 2,
|
|
1575
|
+
end: idx + 2
|
|
1576
|
+
};
|
|
1577
|
+
break;
|
|
1578
|
+
}
|
|
1579
|
+
case "insertMethodChainHandlebars": {
|
|
1580
|
+
const idx = safeCursorIdx(cursorIdx, tree);
|
|
1581
|
+
setValue(spliceAtCursor(value, "{{}}", idx));
|
|
1582
|
+
nextRenderRef.current.cursor = {
|
|
1583
|
+
start: idx + 2,
|
|
1584
|
+
end: idx + 2
|
|
1585
|
+
};
|
|
1586
|
+
break;
|
|
1587
|
+
}
|
|
1588
|
+
case "enterMethodChainMode":
|
|
1589
|
+
setValueType("method-chain");
|
|
1590
|
+
setValue("");
|
|
1591
|
+
nextRenderRef.current.focusedKey = "__secondKey";
|
|
1592
|
+
break;
|
|
1593
|
+
}
|
|
1594
|
+
break;
|
|
1595
|
+
case "method-chain": {
|
|
1596
|
+
if (key === "exitMethodChainValueType") {
|
|
1597
|
+
setValueType("interpolation");
|
|
1598
|
+
setValue("");
|
|
1599
|
+
nextRenderRef.current.focusedKey = "enterMethodChainMode";
|
|
1600
|
+
break;
|
|
1601
|
+
}
|
|
1602
|
+
const option = nextPossibleChains.find((n) => n.value === key);
|
|
1603
|
+
const chain = option?.methodChain?.links?.[0];
|
|
1604
|
+
if (chain) {
|
|
1605
|
+
const schema = option?.schema;
|
|
1606
|
+
const isNoArgCCF = schema != null && isFunctionSchema(schema) && isNoArgCodeChainFunction(schema);
|
|
1607
|
+
const confirmCursorPos = getConfirmLinkCursorPos(tree, valueType, currentChain, chain, schema, cursorIdx);
|
|
1608
|
+
if (confirmCursorPos != null) {
|
|
1609
|
+
setCursor(confirmCursorPos);
|
|
1610
|
+
nextRenderRef.current.cursor = {
|
|
1611
|
+
start: confirmCursorPos,
|
|
1612
|
+
end: confirmCursorPos
|
|
1613
|
+
};
|
|
1614
|
+
} else appendChain([chain], { isFunction: isFunctionSchema(schema) && !isNoArgCCF });
|
|
1615
|
+
if (chain.type !== NodeType.Function && (chain.type !== NodeType.CustomFunction || isNoArgCCF)) setAssumeOnNextLink(true);
|
|
1616
|
+
}
|
|
1617
|
+
break;
|
|
1618
|
+
}
|
|
1619
|
+
case "code": break;
|
|
1620
|
+
}
|
|
1621
|
+
}
|
|
1622
|
+
});
|
|
1623
|
+
const combobox = useComboBox({
|
|
1624
|
+
id,
|
|
1625
|
+
inputRef,
|
|
1626
|
+
listBoxRef,
|
|
1627
|
+
popoverRef,
|
|
1628
|
+
shouldFocusWrap: true,
|
|
1629
|
+
...props
|
|
1630
|
+
}, comboboxState);
|
|
1631
|
+
useEffect(() => {
|
|
1632
|
+
if (nextRenderRef.current.focusInput === true) {
|
|
1633
|
+
nextRenderRef.current.focusInput = void 0;
|
|
1634
|
+
inputRef.current?.focus();
|
|
1635
|
+
}
|
|
1636
|
+
if (nextRenderRef.current.cursor) {
|
|
1637
|
+
const { start, end } = nextRenderRef.current.cursor;
|
|
1638
|
+
nextRenderRef.current.cursor = void 0;
|
|
1639
|
+
inputRef.current?.setSelectionRange(start, end);
|
|
1640
|
+
if (start === value.length) {
|
|
1641
|
+
const startCapture = start;
|
|
1642
|
+
Promise.resolve().then(() => setCursor(startCapture));
|
|
1643
|
+
}
|
|
1644
|
+
scrollInputToCursor(inputRef, end);
|
|
1645
|
+
syncScroll(inputRef, overlayRef);
|
|
1646
|
+
}
|
|
1647
|
+
if (nextRenderRef.current.focusedKey) {
|
|
1648
|
+
let key = nextRenderRef.current.focusedKey;
|
|
1649
|
+
nextRenderRef.current.focusedKey = void 0;
|
|
1650
|
+
switch (key) {
|
|
1651
|
+
case "__firstKey":
|
|
1652
|
+
key = comboboxState.collection.getFirstKey();
|
|
1653
|
+
break;
|
|
1654
|
+
case "__secondKey":
|
|
1655
|
+
key = comboboxState.collection.getFirstKey();
|
|
1656
|
+
if (key != null) key = comboboxState.collection.getKeyAfter(key);
|
|
1657
|
+
break;
|
|
1658
|
+
}
|
|
1659
|
+
comboboxState.selectionManager.setFocusedKey(key);
|
|
1660
|
+
}
|
|
1661
|
+
if (nextRenderRef.current.openPopover === true) {
|
|
1662
|
+
nextRenderRef.current.openPopover = void 0;
|
|
1663
|
+
comboboxState.setOpen(true);
|
|
1664
|
+
}
|
|
1665
|
+
});
|
|
1666
|
+
useEffect(() => {
|
|
1667
|
+
if (mode === "method-chain" && comboboxState.isFocused) comboboxState.open("first", "manual");
|
|
1668
|
+
}, [mode]);
|
|
1669
|
+
/**
|
|
1670
|
+
* Effect to select the first key in the popover consistently
|
|
1671
|
+
* - When the popover is opened.
|
|
1672
|
+
* - When popover options change.
|
|
1673
|
+
*/
|
|
1674
|
+
useEffect(() => {
|
|
1675
|
+
if (comboboxState.isOpen && comboboxState.selectionManager.focusedKey == null) {
|
|
1676
|
+
let key = comboboxState.collection.getFirstKey();
|
|
1677
|
+
if (key != null) {
|
|
1678
|
+
if (key === "exitMethodChainValueType") key = comboboxState.collection.getKeyAfter(key);
|
|
1679
|
+
comboboxState.selectionManager.setFocusedKey(key);
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
}, [
|
|
1683
|
+
comboboxState.isOpen,
|
|
1684
|
+
comboboxState.selectionManager.focusedKey,
|
|
1685
|
+
comboboxState.collection,
|
|
1686
|
+
comboboxState.selectionManager,
|
|
1687
|
+
comboboxItems
|
|
1688
|
+
]);
|
|
1689
|
+
const handleWheel = useCallback(function(e) {
|
|
1690
|
+
const input = inputRef.current;
|
|
1691
|
+
if (!input) return;
|
|
1692
|
+
e.preventDefault();
|
|
1693
|
+
input.scrollLeft += e.deltaX || e.deltaY;
|
|
1694
|
+
syncScroll(inputRef, overlayRef);
|
|
1695
|
+
}, []);
|
|
1696
|
+
const handleMouseMove = useCallback(function() {
|
|
1697
|
+
syncScroll(inputRef, overlayRef);
|
|
1698
|
+
}, []);
|
|
1699
|
+
/**
|
|
1700
|
+
* Handle clicks on links in a method chain to automatically text select the link.
|
|
1701
|
+
*/
|
|
1702
|
+
const handleLinkMouseDown = useCallback(function(linkStart, linkEnd, _e) {
|
|
1703
|
+
setAssumeOnNextLink(false);
|
|
1704
|
+
if (isCustomFunctionAtStart(tree, linkStart)) setForceFunctionDialog(true);
|
|
1705
|
+
const el = inputRef.current;
|
|
1706
|
+
if (el) {
|
|
1707
|
+
el.focus();
|
|
1708
|
+
el.setSelectionRange(linkStart, linkEnd);
|
|
1709
|
+
comboboxState.setOpen(true);
|
|
1710
|
+
}
|
|
1711
|
+
}, [comboboxState, tree]);
|
|
1712
|
+
const handleFunctionConfirm = useCallback((nodes) => {
|
|
1713
|
+
insertChainAtCursor(nodes);
|
|
1714
|
+
comboboxState.setOpen(false);
|
|
1715
|
+
setAssumeOnNextLink(true);
|
|
1716
|
+
setForceFunctionDialog(false);
|
|
1717
|
+
nextRenderRef.current.focusInput = true;
|
|
1718
|
+
nextRenderRef.current.openPopover = true;
|
|
1719
|
+
if (functionAtCursor != null) {
|
|
1720
|
+
const newFnStr = methodChainToString({
|
|
1721
|
+
type: NodeType.Chain,
|
|
1722
|
+
links: nodes
|
|
1723
|
+
});
|
|
1724
|
+
const newCursorIdx = functionAtCursor.start + newFnStr.length - 1;
|
|
1725
|
+
setCursor(newCursorIdx);
|
|
1726
|
+
nextRenderRef.current.cursor = {
|
|
1727
|
+
start: newCursorIdx,
|
|
1728
|
+
end: newCursorIdx
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
}, [
|
|
1732
|
+
insertChainAtCursor,
|
|
1733
|
+
functionAtCursor,
|
|
1734
|
+
setAssumeOnNextLink,
|
|
1735
|
+
nextRenderRef,
|
|
1736
|
+
comboboxState,
|
|
1737
|
+
setCursor
|
|
1738
|
+
]);
|
|
1739
|
+
const handleCodeConfirm = useCallback(() => {
|
|
1740
|
+
comboboxState.setOpen(false);
|
|
1741
|
+
nextRenderRef.current.focusInput = true;
|
|
1742
|
+
}, [comboboxState]);
|
|
1743
|
+
const handleDialogCancel = useCallback(() => {
|
|
1744
|
+
nextRenderRef.current.focusInput = true;
|
|
1745
|
+
setForceFunctionDialog(false);
|
|
1746
|
+
if (functionAtCursor != null && functionAtCursor.custom && forceFunctionDialog) return;
|
|
1747
|
+
else comboboxState.setOpen(false);
|
|
1748
|
+
}, [
|
|
1749
|
+
comboboxState,
|
|
1750
|
+
functionAtCursor,
|
|
1751
|
+
forceFunctionDialog
|
|
1752
|
+
]);
|
|
1753
|
+
const schemaValidator = useSchemaValidator({
|
|
1754
|
+
chainRoots,
|
|
1755
|
+
primitivesSchema,
|
|
1756
|
+
isLoading,
|
|
1757
|
+
platformObjectJsonSchema,
|
|
1758
|
+
defaultPrimitiveUtilities,
|
|
1759
|
+
codeChainFunctionSchema
|
|
1760
|
+
});
|
|
1761
|
+
useInternalValidation({
|
|
1762
|
+
tree,
|
|
1763
|
+
valueIsEmpty: value === "",
|
|
1764
|
+
focused: comboboxState.isFocused,
|
|
1765
|
+
schemaValidator,
|
|
1766
|
+
onValidationChange,
|
|
1767
|
+
value,
|
|
1768
|
+
valueType
|
|
1769
|
+
});
|
|
1770
|
+
const { renderPanel: renderCcfPanel, openPanel: openCcfPanel } = useCodeChainFunctionPanel({
|
|
1771
|
+
enabled: creatable && !isEmpty(currentChain) && isCreatableReceiverSchema(currentSchema),
|
|
1772
|
+
canCreate: canCreateCodeChainFunction,
|
|
1773
|
+
renderPanel: renderCodeChainFunctionPanel,
|
|
1774
|
+
onOpen: () => {
|
|
1775
|
+
comboboxState.setOpen(false);
|
|
1776
|
+
},
|
|
1777
|
+
onSaveNew: (savedName) => {
|
|
1778
|
+
appendChain([{
|
|
1779
|
+
type: MethodChainNodeTypes.CustomFunction,
|
|
1780
|
+
name: savedName,
|
|
1781
|
+
params: []
|
|
1782
|
+
}]);
|
|
1783
|
+
setAssumeOnNextLink(true);
|
|
1784
|
+
setForceFunctionDialog(false);
|
|
1785
|
+
nextRenderRef.current.focusInput = true;
|
|
1786
|
+
comboboxState.setOpen(true);
|
|
1787
|
+
}
|
|
1788
|
+
});
|
|
1789
|
+
const showFunctionDialog = popupMode === "function-dialog" && comboboxState.isOpen;
|
|
1790
|
+
const showCodeDialog = popupMode === "code-dialog" && comboboxState.isOpen;
|
|
1791
|
+
const popoverFooterRendered = useMemo(() => {
|
|
1792
|
+
return popoverFooter == null ? void 0 : popoverFooter({ closePopover() {
|
|
1793
|
+
comboboxState.setOpen(false);
|
|
1794
|
+
if (inputRef.current) inputRef.current.scrollLeft = 0;
|
|
1795
|
+
} });
|
|
1796
|
+
}, [popoverFooter, comboboxState]);
|
|
1797
|
+
const { "aria-errormessage": _ariaErrormessage, "aria-invalid": _ariaInvalid, ...inputProps } = combobox.inputProps;
|
|
1798
|
+
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(FocusScope, {
|
|
1799
|
+
contain: showFunctionDialog || showCodeDialog,
|
|
1800
|
+
children: [/* @__PURE__ */ jsx(HighlightedTextOverlay, {
|
|
1801
|
+
onWheel: handleWheel,
|
|
1802
|
+
onMouseMove: handleMouseMove,
|
|
1803
|
+
overlayRef,
|
|
1804
|
+
inputIsFocused: comboboxState.isFocused,
|
|
1805
|
+
mode,
|
|
1806
|
+
size,
|
|
1807
|
+
variant,
|
|
1808
|
+
valueType,
|
|
1809
|
+
isLoading,
|
|
1810
|
+
highlightedText: value ? /* @__PURE__ */ jsx(HighlightedText, {
|
|
1811
|
+
value,
|
|
1812
|
+
tree,
|
|
1813
|
+
focused: comboboxState.isFocused,
|
|
1814
|
+
interactive: !disabled,
|
|
1815
|
+
schemaValidator,
|
|
1816
|
+
onLinkMouseDown: handleLinkMouseDown,
|
|
1817
|
+
cursorIdx
|
|
1818
|
+
}) : null,
|
|
1819
|
+
children: /* @__PURE__ */ jsx(StyledInput, {
|
|
1820
|
+
...mergeProps({
|
|
1821
|
+
...inputProps,
|
|
1822
|
+
onKeyDown: (e) => {
|
|
1823
|
+
if (e.key === "Tab" && (showFunctionDialog || showCodeDialog)) {
|
|
1824
|
+
e.preventDefault();
|
|
1825
|
+
e.stopPropagation();
|
|
1826
|
+
dialogFocusRef.current?.focusFirst();
|
|
1827
|
+
return;
|
|
1828
|
+
}
|
|
1829
|
+
inputProps.onKeyDown?.(e);
|
|
1830
|
+
}
|
|
1831
|
+
}, {
|
|
1832
|
+
onPaste: (e) => {
|
|
1833
|
+
if (value === "" && canTransitionToValueType("method-chain", allowedValueType) && isChainWithValidRoot(e.clipboardData.getData("text"), chainRoots)) setValueType("method-chain");
|
|
1834
|
+
},
|
|
1835
|
+
onKeyDownCapture: (e) => {
|
|
1836
|
+
if (e.key === "Tab" && comboboxState.isOpen && !showFunctionDialog && !showCodeDialog) comboboxState.setOpen(false);
|
|
1837
|
+
if (e.key === "ArrowDown" || e.key === "ArrowUp") e.preventDefault();
|
|
1838
|
+
},
|
|
1839
|
+
onKeyDown: (e) => {
|
|
1840
|
+
if (e.key === "Backspace" && valueType === "method-chain" && value === "" && canTransitionToValueType("interpolation", allowedValueType)) {
|
|
1841
|
+
setValueType("interpolation");
|
|
1842
|
+
setValue("");
|
|
1843
|
+
nextRenderRef.current.focusedKey = "enterMethodChainMode";
|
|
1844
|
+
return;
|
|
1845
|
+
}
|
|
1846
|
+
if (e.key === "Backspace" && valueType === "method-chain" && inputRef.current?.selectionStart === 0 && inputRef.current?.selectionEnd === value.length && canTransitionToValueType("interpolation", allowedValueType)) {
|
|
1847
|
+
setValueType("interpolation");
|
|
1848
|
+
setValue("");
|
|
1849
|
+
return;
|
|
1850
|
+
}
|
|
1851
|
+
if (e.key === "." && valueType === "interpolation" && canTransitionToValueType("method-chain", allowedValueType)) {
|
|
1852
|
+
if (value === "") {
|
|
1853
|
+
setValueType("method-chain");
|
|
1854
|
+
setValue("");
|
|
1855
|
+
nextRenderRef.current.focusedKey = "__secondKey";
|
|
1856
|
+
e.preventDefault();
|
|
1857
|
+
return;
|
|
1858
|
+
} else if (isChainWithValidRoot(value, chainRoots, { onlyAllowSingleLink: true })) {
|
|
1859
|
+
setValueType("method-chain");
|
|
1860
|
+
return;
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
if (assumeOnNextLink && /^[a-zA-Z0-9]$/.test(e.key)) {
|
|
1864
|
+
const idx = safeCursorIdx(cursorIdx, tree);
|
|
1865
|
+
setValue(spliceAtCursor(value, ".", idx));
|
|
1866
|
+
nextRenderRef.current.cursor = {
|
|
1867
|
+
start: idx + 1,
|
|
1868
|
+
end: idx + 1
|
|
1869
|
+
};
|
|
1870
|
+
setAssumeOnNextLink(false);
|
|
1871
|
+
return;
|
|
1872
|
+
}
|
|
1873
|
+
if (e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "Escape") {
|
|
1874
|
+
setAssumeOnNextLink(false);
|
|
1875
|
+
setForceFunctionDialog(false);
|
|
1876
|
+
}
|
|
1877
|
+
if (e.key === "Backspace") {
|
|
1878
|
+
setCursor(safeCursorIdx(cursorIdx, tree));
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
if (e.key === "{" || e.key === "(") {
|
|
1882
|
+
const idx = safeCursorIdx(cursorIdx, tree);
|
|
1883
|
+
setValue(spliceAtCursor(value, withClosingToken(e.key), idx));
|
|
1884
|
+
nextRenderRef.current.cursor = {
|
|
1885
|
+
start: idx + 1,
|
|
1886
|
+
end: idx + 1
|
|
1887
|
+
};
|
|
1888
|
+
e.preventDefault();
|
|
1889
|
+
return;
|
|
1890
|
+
}
|
|
1891
|
+
if ((e.key === "'" || e.key === "[") && mode === "method-chain") {
|
|
1892
|
+
const idx = safeCursorIdx(cursorIdx, tree);
|
|
1893
|
+
setValue(spliceAtCursor(value, withClosingToken(e.key), idx));
|
|
1894
|
+
nextRenderRef.current.cursor = {
|
|
1895
|
+
start: idx + 1,
|
|
1896
|
+
end: idx + 1
|
|
1897
|
+
};
|
|
1898
|
+
e.preventDefault();
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
if (e.key === "Escape" && comboboxState.isOpen) {
|
|
1902
|
+
blockEscapePropagationRef.current = true;
|
|
1903
|
+
e.stopPropagation();
|
|
1904
|
+
}
|
|
1905
|
+
},
|
|
1906
|
+
onKeyUp: (e) => {
|
|
1907
|
+
if (e.key === "Escape" && blockEscapePropagationRef.current) {
|
|
1908
|
+
blockEscapePropagationRef.current = false;
|
|
1909
|
+
e.stopPropagation();
|
|
1910
|
+
}
|
|
1911
|
+
},
|
|
1912
|
+
onMouseDown: () => {
|
|
1913
|
+
setAssumeOnNextLink(false);
|
|
1914
|
+
setForceFunctionDialog(false);
|
|
1915
|
+
},
|
|
1916
|
+
onClick: () => {
|
|
1917
|
+
const clickCursorPos = inputRef.current?.selectionStart ?? null;
|
|
1918
|
+
if (clickCursorPos != null) setCursor(clickCursorPos);
|
|
1919
|
+
if (clickCursorPos != null && clickCursorPos === inputRef.current?.selectionEnd) {
|
|
1920
|
+
const chainNode = findChainAtCursor(tree, clickCursorPos, valueType);
|
|
1921
|
+
if (chainNode && clickCursorPos === chainNode.end) setAssumeOnNextLink(true);
|
|
1922
|
+
}
|
|
1923
|
+
},
|
|
1924
|
+
onBlur: () => {
|
|
1925
|
+
setAssumeOnNextLink(false);
|
|
1926
|
+
},
|
|
1927
|
+
onChange: (e) => {
|
|
1928
|
+
setAssumeOnNextLink(false);
|
|
1929
|
+
setForceFunctionDialog(false);
|
|
1930
|
+
setValue(e.target.value);
|
|
1931
|
+
syncScroll(inputRef, overlayRef);
|
|
1932
|
+
if (comboboxState.isOpen && mode === "text") comboboxState.setOpen(false);
|
|
1933
|
+
}
|
|
1934
|
+
}),
|
|
1935
|
+
"data-smart-text-input": "true",
|
|
1936
|
+
ref: inputRef,
|
|
1937
|
+
value,
|
|
1938
|
+
placeholder,
|
|
1939
|
+
disabled,
|
|
1940
|
+
size,
|
|
1941
|
+
$variant: variant,
|
|
1942
|
+
"aria-haspopup": popupMode === "function-dialog" || popupMode === "code-dialog" ? "dialog" : inputProps["aria-haspopup"],
|
|
1943
|
+
...suppressPopover ? { "aria-expanded": false } : {}
|
|
1944
|
+
})
|
|
1945
|
+
}), !suppressPopover && /* @__PURE__ */ jsx(SmartTextInputPopover, {
|
|
1946
|
+
id: `${id}__popover`,
|
|
1947
|
+
comboboxState,
|
|
1948
|
+
popoverRef,
|
|
1949
|
+
inputRef,
|
|
1950
|
+
variant,
|
|
1951
|
+
isDialog: showFunctionDialog || showCodeDialog,
|
|
1952
|
+
onDialogClose: handleDialogCancel,
|
|
1953
|
+
dialogFocusRef,
|
|
1954
|
+
portalContainerRef,
|
|
1955
|
+
footer: popoverFooterRendered,
|
|
1956
|
+
children: showFunctionDialog && functionAtCursor != null ? /* @__PURE__ */ jsx(SmartTextInputFunctionDialog, {
|
|
1957
|
+
id: combobox.listBoxProps.id,
|
|
1958
|
+
inputRef,
|
|
1959
|
+
functionAtCursor,
|
|
1960
|
+
nextPossibleChains,
|
|
1961
|
+
chainRoots,
|
|
1962
|
+
onConfirm: handleFunctionConfirm,
|
|
1963
|
+
onCancel: handleDialogCancel,
|
|
1964
|
+
renderFunctionForm,
|
|
1965
|
+
renderCustomFunctionDetail,
|
|
1966
|
+
openCodeChainFunctionPanel: openCcfPanel
|
|
1967
|
+
}) : showCodeDialog ? /* @__PURE__ */ jsx(SmartTextInputCodeDialog, {
|
|
1968
|
+
id: combobox.listBoxProps.id,
|
|
1969
|
+
inputRef,
|
|
1970
|
+
onConfirm: handleCodeConfirm,
|
|
1971
|
+
onCancel: handleDialogCancel
|
|
1972
|
+
}) : /* @__PURE__ */ jsx(SmartTextInputListbox, {
|
|
1973
|
+
comboboxState,
|
|
1974
|
+
listBoxRef,
|
|
1975
|
+
listBoxProps: combobox.listBoxProps,
|
|
1976
|
+
mode,
|
|
1977
|
+
isLoading,
|
|
1978
|
+
openCodeChainFunctionPanel: openCcfPanel ? () => {
|
|
1979
|
+
openCcfPanel({
|
|
1980
|
+
initialName: query,
|
|
1981
|
+
inputSchema: currentSchema
|
|
1982
|
+
});
|
|
1983
|
+
} : void 0
|
|
1984
|
+
})
|
|
1985
|
+
})]
|
|
1986
|
+
}), renderCcfPanel()] });
|
|
1987
|
+
};
|
|
1988
|
+
//#endregion
|
|
1989
|
+
//#region components/SmartTextInput/SmartTextInputField.tsx
|
|
1990
|
+
const SmartTextInputForField = (props) => {
|
|
1991
|
+
const field = useFormField({ inputId: props.id });
|
|
1992
|
+
return /* @__PURE__ */ jsx(SmartTextInput, {
|
|
1993
|
+
...props,
|
|
1994
|
+
id: field.inputId,
|
|
1995
|
+
"aria-labelledby": field.labelId
|
|
1996
|
+
});
|
|
1997
|
+
};
|
|
1998
|
+
/**
|
|
1999
|
+
* FormField wrapper for SmartTextInput so callers can use shared
|
|
2000
|
+
* helper/warning/error text plumbing without duplicating wrappers.
|
|
2001
|
+
*/
|
|
2002
|
+
const SmartTextInputField = (props) => {
|
|
2003
|
+
const [fromInputErrorText, setErrorText] = useState(null);
|
|
2004
|
+
const { formFieldProps, inputProps } = splitOutFormFieldProps(props);
|
|
2005
|
+
const { formFieldStyle, hasError, asTableBoxCell, tableBoxCellProps, ...rest } = inputProps;
|
|
2006
|
+
const errorText = formFieldProps.errorText ?? fromInputErrorText;
|
|
2007
|
+
if (asTableBoxCell) return /* @__PURE__ */ jsx(TableBoxField.Cell, {
|
|
2008
|
+
...tableBoxCellProps,
|
|
2009
|
+
children: /* @__PURE__ */ jsx(SmartTextInputForField, {
|
|
2010
|
+
onValidationChange: setErrorText,
|
|
2011
|
+
variant: "table-cell",
|
|
2012
|
+
size: "sm",
|
|
2013
|
+
...rest
|
|
2014
|
+
})
|
|
2015
|
+
});
|
|
2016
|
+
return /* @__PURE__ */ jsx(FormField, {
|
|
2017
|
+
...formFieldProps,
|
|
2018
|
+
inputId: formFieldProps.inputId ?? rest.id,
|
|
2019
|
+
errorText,
|
|
2020
|
+
hasError: hasError || !!errorText,
|
|
2021
|
+
style: formFieldStyle,
|
|
2022
|
+
children: /* @__PURE__ */ jsxs(Stack, {
|
|
2023
|
+
spacing: Spacing[1],
|
|
2024
|
+
fullWidth: true,
|
|
2025
|
+
children: [/* @__PURE__ */ jsx(SmartTextInputForField, {
|
|
2026
|
+
onValidationChange: setErrorText,
|
|
2027
|
+
...rest
|
|
2028
|
+
}), errorText && formFieldProps.configField && /* @__PURE__ */ jsx(ErrorText, { children: errorText })]
|
|
2029
|
+
})
|
|
2030
|
+
});
|
|
2031
|
+
};
|
|
2032
|
+
//#endregion
|
|
2033
|
+
export { Mode, SmartTextInputField, ValueType, SmartTextInput as default };
|
|
2034
|
+
|
|
2035
|
+
//# sourceMappingURL=index.mjs.map
|