@rio-cloud/rio-uikit 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/actionBarItem/ActionBarItem.d.ts +2 -2
- package/components/actionBarItem/ActionBarItem.js.map +1 -1
- package/components/applicationHeader/ApplicationHeader.d.ts +6 -7
- package/components/applicationHeader/ApplicationHeader.js.map +1 -1
- package/components/applicationLayout/SubNavigation.d.ts +7 -0
- package/components/applicationLayout/SubNavigation.js.map +1 -1
- package/components/assetTree/AssetTree.d.ts +7 -0
- package/components/assetTree/AssetTree.js.map +1 -1
- package/components/assetTree/Tree.d.ts +15 -0
- package/components/assetTree/Tree.js.map +1 -1
- package/components/assetTree/TreeIcon.d.ts +30 -0
- package/components/assetTree/TreeIcon.js +16 -0
- package/components/assetTree/TreeIcon.js.map +1 -0
- package/components/assetTree/TreeLeaf.js +22 -22
- package/components/assetTree/TreeLeaf.js.map +1 -1
- package/components/assetTree/TreeNode.js +25 -25
- package/components/assetTree/TreeNode.js.map +1 -1
- package/components/assetTree/TreeSearch.d.ts +2 -0
- package/components/assetTree/TreeSearch.js.map +1 -1
- package/components/barList/BarList.d.ts +26 -0
- package/components/barList/BarList.js.map +1 -1
- package/components/bottomSheet/BottomSheet.d.ts +17 -3
- package/components/bottomSheet/BottomSheet.js.map +1 -1
- package/components/bottomSheet/TimedBottomSheet.d.ts +10 -0
- package/components/bottomSheet/TimedBottomSheet.js.map +1 -1
- package/components/calendarStripe/CalendarStripe.d.ts +1 -1
- package/components/calendarStripe/CalendarStripe.js +34 -36
- package/components/calendarStripe/CalendarStripe.js.map +1 -1
- package/components/charts/Area.d.ts +2 -2
- package/components/charts/Area.js.map +1 -1
- package/components/charts/Line.d.ts +2 -2
- package/components/charts/Line.js.map +1 -1
- package/components/checkbox/Checkbox.d.ts +0 -3
- package/components/checkbox/Checkbox.js.map +1 -1
- package/components/clearableInput/ClearableInput.d.ts +21 -20
- package/components/clearableInput/ClearableInput.js.map +1 -1
- package/components/collapse/Collapse.d.ts +3 -0
- package/components/collapse/Collapse.js +12 -12
- package/components/collapse/Collapse.js.map +1 -1
- package/components/contentLoader/ContentLoader.d.ts +10 -2
- package/components/contentLoader/ContentLoader.js.map +1 -1
- package/components/dataTabs/DataTabs.d.ts +6 -0
- package/components/dataTabs/DataTabs.js.map +1 -1
- package/components/dialog/ConfirmationDialog.d.ts +22 -0
- package/components/dialog/ConfirmationDialog.js.map +1 -1
- package/components/dialog/Dialog.d.ts +13 -1
- package/components/dialog/Dialog.js.map +1 -1
- package/components/dialog/ReleaseNotesDialog.d.ts +3 -3
- package/components/dialog/ReleaseNotesDialog.js.map +1 -1
- package/components/dropdown/ButtonDropdown.d.ts +4 -0
- package/components/dropdown/ButtonDropdown.js +51 -51
- package/components/dropdown/ButtonDropdown.js.map +1 -1
- package/components/dropdown/DropdownSubmenu.d.ts +4 -0
- package/components/dropdown/DropdownSubmenu.js.map +1 -1
- package/components/editableContent/EditableContent.d.ts +6 -0
- package/components/editableContent/EditableContent.js.map +1 -1
- package/components/expander/ExpanderList.d.ts +3 -0
- package/components/expander/ExpanderList.js.map +1 -1
- package/components/expander/ExpanderPanel.d.ts +14 -4
- package/components/expander/ExpanderPanel.js.map +1 -1
- package/components/fade/Fade.d.ts +1 -1
- package/components/fade/Fade.js.map +1 -1
- package/components/filepicker/FilePicker.d.ts +0 -2
- package/components/filepicker/FilePicker.js.map +1 -1
- package/components/groupedItemList/GroupedItemList.d.ts +10 -7
- package/components/groupedItemList/GroupedItemList.js.map +1 -1
- package/components/listMenu/ListMenu.js.map +1 -1
- package/components/listMenu/ListMenuGroup.d.ts +2 -1
- package/components/listMenu/ListMenuGroup.js.map +1 -1
- package/components/map/components/Map.js.map +1 -1
- package/components/map/components/constants.js.map +1 -1
- package/components/map/components/features/ContextMenuItem.d.ts +1 -1
- package/components/map/components/features/ContextMenuItem.js +2 -17
- package/components/map/components/features/ContextMenuItem.js.map +1 -1
- package/components/map/components/features/basics/Polyline.d.ts +4 -1
- package/components/map/components/features/basics/Polyline.js +1 -1
- package/components/map/components/features/basics/Polyline.js.map +1 -1
- package/components/map/components/features/layers/MarkerLayer.d.ts +3 -1
- package/components/map/components/features/layers/MarkerLayer.js.map +1 -1
- package/components/map/components/features/layers/clustering/ClusterLayer.js +1 -1
- package/components/map/components/features/layers/clustering/ClusterLayer.js.map +1 -1
- package/components/map/components/features/layers/clustering/SimpleClusterLayer.d.ts +3 -2
- package/components/map/components/features/layers/clustering/SimpleClusterLayer.js.map +1 -1
- package/components/map/components/features/layers/overlayLayers/RoadRestrictionLayer.js +7 -7
- package/components/map/components/features/layers/overlayLayers/RoadRestrictionLayer.js.map +1 -1
- package/components/map/components/features/layers/overlayLayers/TrafficLayer.js +4 -4
- package/components/map/components/features/layers/overlayLayers/TrafficLayer.js.map +1 -1
- package/components/map/utils/clustering.d.ts +6 -1
- package/components/map/utils/clustering.js +25 -19
- package/components/map/utils/clustering.js.map +1 -1
- package/components/map/utils/rendering.d.ts +1 -1
- package/components/map/utils/rendering.js +23 -23
- package/components/map/utils/rendering.js.map +1 -1
- package/components/menuItems/MenuItem.d.ts +23 -0
- package/components/menuItems/MenuItem.js.map +1 -1
- package/components/notification/Notification.js +4 -4
- package/components/notification/Notification.js.map +1 -1
- package/components/onboarding/OnboardingTip.d.ts +18 -12
- package/components/onboarding/OnboardingTip.js.map +1 -1
- package/components/overlay/OverlayTrigger.d.ts +43 -1
- package/components/overlay/OverlayTrigger.js.map +1 -1
- package/components/pager/Pager.d.ts +3 -0
- package/components/pager/Pager.js.map +1 -1
- package/components/popover/Popover.d.ts +1 -0
- package/components/popover/Popover.js.map +1 -1
- package/components/preloader/ImagePreloader.d.ts +1 -1
- package/components/preloader/ImagePreloader.js.map +1 -1
- package/components/radiobutton/RadioButton.d.ts +9 -5
- package/components/radiobutton/RadioButton.js.map +1 -1
- package/components/releaseNotes/ReleaseNotes.d.ts +0 -3
- package/components/releaseNotes/ReleaseNotes.js.map +1 -1
- package/components/resizer/Resizer.d.ts +17 -3
- package/components/resizer/Resizer.js.map +1 -1
- package/components/rioglyph/Rioglyph.d.ts +20 -8
- package/components/rioglyph/Rioglyph.js.map +1 -1
- package/components/rules/RulesWrapper.js +1 -1
- package/components/rules/RulesWrapper.js.map +1 -1
- package/components/saveableInput/SaveableDateInput.d.ts +20 -2
- package/components/saveableInput/SaveableDateInput.js.map +1 -1
- package/components/saveableInput/SaveableInput.d.ts +10 -2
- package/components/saveableInput/SaveableInput.js.map +1 -1
- package/components/selects/BaseSelectDropdown.js +90 -79
- package/components/selects/BaseSelectDropdown.js.map +1 -1
- package/components/selects/Select.d.ts +5 -0
- package/components/selects/Select.js +94 -94
- package/components/selects/Select.js.map +1 -1
- package/components/sidebars/Sidebar.d.ts +19 -3
- package/components/sidebars/Sidebar.js.map +1 -1
- package/components/slider/RangeSlider.d.ts +15 -0
- package/components/slider/RangeSlider.js.map +1 -1
- package/components/slider/Slider.d.ts +9 -0
- package/components/slider/Slider.js.map +1 -1
- package/components/smoothScrollbars/SmoothScrollbars.d.ts +44 -0
- package/components/smoothScrollbars/SmoothScrollbars.js.map +1 -1
- package/components/spinner/Spinner.d.ts +3 -3
- package/components/spinner/Spinner.js.map +1 -1
- package/components/states/BaseStateProps.d.ts +6 -2
- package/components/states/StateIcon.d.ts +14 -1
- package/components/states/StateIcon.js.map +1 -1
- package/components/statsWidget/StatsWidget.d.ts +2 -0
- package/components/statsWidget/StatsWidget.js.map +1 -1
- package/components/statsWidget/StatsWidgetBody.d.ts +1 -0
- package/components/statsWidget/StatsWidgetBody.js.map +1 -1
- package/components/statsWidget/StatsWidgetNumber.d.ts +2 -0
- package/components/statsWidget/StatsWidgetNumber.js.map +1 -1
- package/components/statusBar/StatusBar.d.ts +2 -31
- package/components/statusBar/StatusBar.js.map +1 -1
- package/components/statusBar/StatusBarIcon.d.ts +2 -2
- package/components/statusBar/StatusBarIcon.js.map +1 -1
- package/components/statusBar/StatusBarLabel.d.ts +2 -2
- package/components/statusBar/StatusBarLabel.js.map +1 -1
- package/components/statusBar/StatusBarProgressBar.d.ts +1 -1
- package/components/statusBar/StatusBarProgressBar.js.map +1 -1
- package/components/statusBar/{StatusBar.types.d.ts → StatusBarProps.d.ts} +44 -2
- package/components/steppedProgressBar/SteppedProgressBar.d.ts +1 -1
- package/components/steppedProgressBar/SteppedProgressBar.js.map +1 -1
- package/components/switch/Switch.d.ts +13 -1
- package/components/switch/Switch.js.map +1 -1
- package/components/table/SortArrowDown.d.ts +1 -1
- package/components/table/SortArrowDown.js.map +1 -1
- package/components/table/SortArrowUp.d.ts +1 -1
- package/components/table/SortArrowUp.js.map +1 -1
- package/components/table/TableSettingsDialog.d.ts +5 -0
- package/components/table/TableSettingsDialog.js +119 -109
- package/components/table/TableSettingsDialog.js.map +1 -1
- package/components/table/TableSettingsDialogFooter.js +9 -9
- package/components/table/TableSettingsDialogFooter.js.map +1 -1
- package/components/table/TableViewToggles.d.ts +21 -1
- package/components/table/TableViewToggles.js.map +1 -1
- package/components/tag/Tag.d.ts +7 -2
- package/components/tag/Tag.js.map +1 -1
- package/components/tagManager/TagManager.d.ts +15 -0
- package/components/tagManager/TagManager.js.map +1 -1
- package/components/tagManager/TagManagerTag.d.ts +9 -0
- package/components/teaser/Teaser.d.ts +57 -55
- package/components/teaser/Teaser.js.map +1 -1
- package/components/teaser/TeaserContainer.d.ts +1 -1
- package/components/teaser/TeaserContainer.js.map +1 -1
- package/components/tooltip/SimpleTooltip.d.ts +22 -4
- package/components/tooltip/SimpleTooltip.js.map +1 -1
- package/components/tooltip/Tooltip.d.ts +22 -2
- package/components/tooltip/Tooltip.js.map +1 -1
- package/components/video/ResponsiveVideo.d.ts +8 -3
- package/components/video/ResponsiveVideo.js.map +1 -1
- package/hooks/useKey.d.ts +1 -1
- package/hooks/useKey.js.map +1 -1
- package/hooks/useOnboarding.d.ts +86 -80
- package/hooks/useOnboarding.js.map +1 -1
- package/hooks/useTableExport.js.map +1 -1
- package/hooks/useUncontrollable.d.ts +1 -1
- package/hooks/useUncontrollable.js.map +1 -1
- package/package.json +12 -14
- package/utils/colorScheme.js +14 -13
- package/utils/colorScheme.js.map +1 -1
- package/utils/cssuseragent.js.map +1 -1
- package/utils/scrollItemIntoView.js +12 -11
- package/utils/scrollItemIntoView.js.map +1 -1
- package/utils/urlFeatureToggles.js +19 -20
- package/utils/urlFeatureToggles.js.map +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioButton.js","sources":["../../../src/components/radiobutton/RadioButton.tsx"],"sourcesContent":["import {\n type ChangeEventHandler,\n type KeyboardEvent,\n type MouseEventHandler,\n type PropsWithChildren,\n type ReactNode,\n type Ref,\n useRef,\n type HTMLProps,\n} from 'react';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/compat';\n\ntype RadioButtonIconProps = {\n icon: string;\n iconSize: number;\n iconLabelPosition: 'vertical' | 'horizontal';\n text: string | ReactNode;\n};\n\nconst RadioButtonIcon = (props: RadioButtonIconProps) => {\n const { icon, iconSize, iconLabelPosition, text } = props;\n\n const iconStyles = {\n width: `${iconSize}px`,\n height: `${iconSize}px`,\n fontSize: `${iconSize}px`,\n lineHeight: `${iconSize}px`,\n };\n\n return (\n <span className={`radio-icon label-${iconLabelPosition}`}>\n <span className={`rioglyph ${icon}`} style={iconStyles} />\n <span className='radio-label'>{text}</span>\n </span>\n );\n};\n\nexport type RadioButtonProps = Omit<HTMLProps<HTMLLabelElement>, 'label' | 'onClick'> & {\n /**\n * Define any rioglyph icon like \"rioglyph-truck\".\n */\n icon?: string;\n\n /**\n * The label position.\n *\n * Possible values are: \"horizontal\" or \"vertical\".\n *\n * @default 'vertical'\n */\n iconLabelPosition?: 'vertical' | 'horizontal';\n\n /**\n * The icon Size in px.\n *\n * @default 16\n */\n iconSize?: number;\n\n /**\n * Defines the label text.\n */\n label?: string | ReactNode;\n\n /**\n * Callback function that is invoked when the radio button is clicked.\n *\n * @default noop\n */\n onClick?: MouseEventHandler<{ value: string | string[] | number }>;\n\n /**\n * Callback function that is invoked when the radio button is toggled and the state should change (for controlled\n * usage).\n *\n * @default noop\n */\n onChange?: ChangeEventHandler;\n\n /**\n * Defines whether the radio is checked (for controlled usage).\n */\n checked?: boolean;\n\n /**\n * Defines whether the radio is initially checked (state can be changed on click).\n */\n defaultChecked?: boolean;\n\n /**\n * Defines whether the checkbox is disabled.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the input element.\n */\n className?: string;\n\n /**\n * Defines whether the radio button is applying an inline style.\n *\n * Use this in combination with other radio buttons.\n *\n * @default false\n */\n inline?: boolean;\n\n /**\n * Displays the icon on the right side of the text.\n *\n * @default false\n */\n right?: boolean;\n\n /**\n * Allows for rendering a completely different layout with or without a radio tick.\n *\n * @default false\n */\n custom?: boolean;\n\n /**\n * Name to be given to the input element.\n */\n name?: string;\n\n /**\n * The value attribute is a string containing the radio button's value but __it is never shown to the user__.\n * It serves a special purpose for inputs of type radio: when a form is submitted, only radio buttons which are\n * currently checked are submitted, and the reported value is the value of the value attribute.\n * If the value is not otherwise specified, it is the string on by default.\n *\n * This is useful when using native `FormData` when submitting a form to get the selected radio button value.\n */\n value?: string;\n\n /**\n * Number of the index used for keyboard support.\n *\n * An index of 0 means that the element should be focusable in sequential keyboard navigation, but its order is\n * defined by the document's source order. To disable the focus set the value to -1. A positive value means the\n * element should be focusable in sequential keyboard navigation, with its order defined by the value of the number.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Ref which is added to the input element.\n */\n inputRef?: Ref<HTMLInputElement>;\n};\n\nconst RadioButton = (props: PropsWithChildren<RadioButtonProps>) => {\n const {\n icon = '',\n iconLabelPosition = 'vertical',\n iconSize = 16,\n label,\n onClick = noop,\n onChange = noop,\n checked,\n defaultChecked,\n disabled = false,\n className,\n inline = false,\n right = false,\n custom = false,\n name,\n value,\n tabIndex = 0,\n inputRef,\n children,\n ...remainingProps\n } = props;\n\n const isControlled = checked !== null && checked !== undefined;\n\n const labelRef = useRef<HTMLLabelElement>(null);\n\n const handleToggleKeyDown = (event: KeyboardEvent<HTMLLabelElement>) => {\n switch (event.key) {\n case ' ': // toggle on space\n case 'Enter': // open on enter\n toggle(event);\n break;\n\n default:\n break;\n }\n };\n\n const toggle = (event: KeyboardEvent<HTMLLabelElement>) => {\n event.preventDefault();\n\n if (disabled) {\n return;\n }\n\n // Controlled case - uses \"onChange()\" instead of \"onClick()\" callback\n if (isControlled) {\n onChange(event);\n return;\n }\n\n // Uncontrolled case - set the input checked or unchecked\n if (labelRef.current) {\n const checkbox = labelRef.current.firstChild as HTMLInputElement;\n checkbox.checked = !checkbox.checked;\n }\n };\n\n const text = label || children;\n\n const labelClassnames = classNames('radio', inline && 'radio-inline', className);\n const inputClassnames = classNames(right && 'icon-right', className);\n\n const renderCustomIcon = !!icon;\n const renderCustomContent = custom && children;\n const renderDefault = !icon && !custom;\n\n return (\n <label\n {...remainingProps}\n className={labelClassnames}\n tabIndex={tabIndex}\n onKeyDown={handleToggleKeyDown}\n ref={labelRef}\n >\n <input\n type='radio'\n defaultChecked={defaultChecked}\n checked={checked}\n disabled={disabled}\n className={inputClassnames}\n ref={inputRef}\n onClick={onClick}\n // Only wire onChange for controlled usage; uncontrolled relies on native state + onClick.\n onChange={isControlled ? onChange : undefined}\n name={name}\n value={value}\n />\n {renderCustomIcon && (\n <RadioButtonIcon icon={icon} iconSize={iconSize} iconLabelPosition={iconLabelPosition} text={text} />\n )}\n {renderDefault && (\n <span className='radio-text'>\n <span>{text}</span>\n </span>\n )}\n {renderCustomContent && children}\n </label>\n );\n};\n\nRadioButton.ICON_LABEL_VERTICAL = 'vertical';\nRadioButton.ICON_LABEL_HORIZONTAL = 'horizontal';\n\nexport default RadioButton;\n"],"names":["RadioButtonIcon","props","icon","iconSize","iconLabelPosition","text","iconStyles","jsxs","jsx","RadioButton","label","onClick","noop","onChange","checked","defaultChecked","disabled","className","inline","right","custom","name","value","tabIndex","inputRef","children","remainingProps","isControlled","labelRef","useRef","handleToggleKeyDown","event","toggle","checkbox","labelClassnames","classNames","inputClassnames"],"mappings":";;;;AAoBA,MAAMA,IAAkB,CAACC,MAAgC;AACrD,QAAM,EAAE,MAAAC,GAAM,UAAAC,GAAU,mBAAAC,GAAmB,MAAAC,MAASJ,GAE9CK,IAAa;AAAA,IACf,OAAO,GAAGH,CAAQ;AAAA,IAClB,QAAQ,GAAGA,CAAQ;AAAA,IACnB,UAAU,GAAGA,CAAQ;AAAA,IACrB,YAAY,GAAGA,CAAQ;AAAA,EAAA;AAG3B,SACI,gBAAAI,EAAC,QAAA,EAAK,WAAW,oBAAoBH,CAAiB,IAClD,UAAA;AAAA,IAAA,gBAAAI,EAAC,UAAK,WAAW,YAAYN,CAAI,IAAI,OAAOI,GAAY;AAAA,IACxD,gBAAAE,EAAC,QAAA,EAAK,WAAU,eAAe,UAAAH,EAAA,CAAK;AAAA,EAAA,GACxC;AAER,GAyHMI,IAAc,CAACR,MAA+C;AAChE,QAAM;AAAA,IACF,MAAAC,IAAO;AAAA,IACP,mBAAAE,IAAoB;AAAA,IACpB,UAAAD,IAAW;AAAA,IACX,OAAAO;AAAA,IACA,SAAAC,IAAUC;AAAA,IACV,UAAAC,IAAWD;AAAA,IACX,SAAAE;AAAA,IACA,gBAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,QAAAC,IAAS;AAAA,IACT,OAAAC,IAAQ;AAAA,IACR,QAAAC,IAAS;AAAA,IACT,MAAAC;AAAA,IACA,OAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,UAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHzB,GAEE0B,IAAeb,KAAY,MAE3Bc,IAAWC,EAAyB,IAAI,GAExCC,IAAsB,CAACC,MAA2C;AACpE,YAAQA,EAAM,KAAA;AAAA,MACV,KAAK;AAAA;AAAA,MACL,KAAK;AACD,QAAAC,EAAOD,CAAK;AACZ;AAAA,IAGA;AAAA,EAEZ,GAEMC,IAAS,CAACD,MAA2C;AAGvD,QAFAA,EAAM,eAAA,GAEF,CAAAf,GAKJ;AAAA,UAAIW,GAAc;AACd,QAAAd,EAASkB,CAAK;AACd;AAAA,MACJ;AAGA,UAAIH,EAAS,SAAS;AAClB,cAAMK,IAAWL,EAAS,QAAQ;AAClC,QAAAK,EAAS,UAAU,CAACA,EAAS;AAAA,MACjC;AAAA;AAAA,EACJ,GAEM5B,IAAOK,KAASe,GAEhBS,IAAkBC,EAAW,SAASjB,KAAU,gBAAgBD,CAAS,GACzEmB,IAAkBD,EAAWhB,KAAS,cAAcF,CAAS;AAMnE,SACI,gBAAAV;AAAA,IAAC;AAAA,IAAA;AAAA,MACI,GAAGmB;AAAA,MACJ,WAAWQ;AAAA,MACX,UAAAX;AAAA,MACA,WAAWO;AAAA,MACX,KAAKF;AAAA,MAEL,UAAA;AAAA,QAAA,gBAAApB;AAAA,UAAC;AAAA,UAAA;AAAA,YACG,MAAK;AAAA,YACL,gBAAAO;AAAA,YACA,SAAAD;AAAA,YACA,UAAAE;AAAA,YACA,WAAWoB;AAAA,YACX,KAAKZ;AAAA,YACL,SAAAb;AAAA,YAEA,UAAUgB,IAAed,IAAW;AAAA,YACpC,MAAAQ;AAAA,YACA,OAAAC;AAAA,UAAA;AAAA,QAAA;AAAA,QAvBa,CAAC,CAACpB,KA0Bf,gBAAAM,EAACR,GAAA,EAAgB,MAAAE,GAAY,UAAAC,GAAoB,mBAAAC,GAAsC,MAAAC,GAAY;AAAA,QAxBzF,CAACH,KAAQ,CAACkB,uBA2BnB,QAAA,EAAK,WAAU,cACZ,UAAA,gBAAAZ,EAAC,QAAA,EAAM,aAAK,EAAA,CAChB;AAAA,QA9BgBY,KAAUK,KAgCNA;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGpC;AAEAhB,EAAY,sBAAsB;AAClCA,EAAY,wBAAwB;"}
|
|
1
|
+
{"version":3,"file":"RadioButton.js","sources":["../../../src/components/radiobutton/RadioButton.tsx"],"sourcesContent":["import {\n type ChangeEventHandler,\n type KeyboardEvent,\n type MouseEventHandler,\n type PropsWithChildren,\n type ReactNode,\n type Ref,\n useRef,\n type HTMLProps,\n} from 'react';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/compat';\n\ntype RadioButtonIconProps = {\n icon: string;\n iconSize: number;\n iconLabelPosition: 'vertical' | 'horizontal';\n text: string | ReactNode;\n};\n\nconst RadioButtonIcon = (props: RadioButtonIconProps) => {\n const { icon, iconSize, iconLabelPosition, text } = props;\n\n const iconStyles = {\n width: `${iconSize}px`,\n height: `${iconSize}px`,\n fontSize: `${iconSize}px`,\n lineHeight: `${iconSize}px`,\n };\n\n return (\n <span className={`radio-icon label-${iconLabelPosition}`}>\n <span className={`rioglyph ${icon}`} style={iconStyles} />\n <span className='radio-label'>{text}</span>\n </span>\n );\n};\n\nexport type RadioButtonProps = Omit<HTMLProps<HTMLLabelElement>, 'label' | 'onClick'> & {\n /**\n * Define any rioglyph icon like \"rioglyph-truck\".\n */\n icon?: string;\n\n /**\n * The label position.\n *\n * Possible values are: `'horizontal'` or `'vertical'`.\n *\n * @default 'vertical'\n */\n iconLabelPosition?: 'vertical' | 'horizontal';\n\n /**\n * The icon Size in px.\n *\n * @default 16\n */\n iconSize?: number;\n\n /**\n * Defines the label text.\n */\n label?: string | ReactNode;\n\n /**\n * Callback function that is invoked when the radio button is clicked.\n *\n * @default () => {}\n */\n onClick?: MouseEventHandler<{ value: string | string[] | number }>;\n\n /**\n * Callback function that is invoked when the radio button is toggled and the state should change (for controlled\n * usage).\n *\n * @default () => {}\n */\n onChange?: ChangeEventHandler;\n\n /**\n * Defines whether the radio is checked (for controlled usage).\n */\n checked?: boolean;\n\n /**\n * Defines whether the radio is initially checked (state can be changed on click).\n */\n defaultChecked?: boolean;\n\n /**\n * Defines whether the checkbox is disabled.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the input element.\n */\n className?: string;\n\n /**\n * Defines whether the radio button is applying an inline style.\n *\n * Use this in combination with other radio buttons.\n *\n * @default false\n */\n inline?: boolean;\n\n /**\n * Displays the icon on the right side of the text.\n *\n * @default false\n */\n right?: boolean;\n\n /**\n * Allows for rendering a completely different layout with or without a radio tick.\n *\n * @default false\n */\n custom?: boolean;\n\n /**\n * Name to be given to the input element.\n */\n name?: string;\n\n /**\n * The value attribute is a string containing the radio button's value but __it is never shown to the user__.\n *\n * It serves a special purpose for inputs of type radio: when a form is submitted, only radio buttons which are\n * currently checked are submitted, and the reported value is the value of the value attribute.\n *\n * If the value is not otherwise specified, it is the string on by default.\n *\n * This is useful when using native `FormData` when submitting a form to get the selected radio button value.\n */\n value?: string;\n\n /**\n * Number of the index used for keyboard support.\n *\n * An index of 0 means that the element should be focusable in sequential keyboard navigation, but its order is\n * defined by the document's source order. To disable the focus set the value to -1.\n *\n * A positive value means the element should be focusable in sequential keyboard navigation,\n * with its order defined by the value of the number.\n *\n * @default 0\n */\n tabIndex?: number;\n\n /**\n * Ref which is added to the input element.\n */\n inputRef?: Ref<HTMLInputElement>;\n};\n\nconst RadioButton = (props: PropsWithChildren<RadioButtonProps>) => {\n const {\n icon = '',\n iconLabelPosition = 'vertical',\n iconSize = 16,\n label,\n onClick = noop,\n onChange = noop,\n checked,\n defaultChecked,\n disabled = false,\n className,\n inline = false,\n right = false,\n custom = false,\n name,\n value,\n tabIndex = 0,\n inputRef,\n children,\n ...remainingProps\n } = props;\n\n const isControlled = checked !== null && checked !== undefined;\n\n const labelRef = useRef<HTMLLabelElement>(null);\n\n const handleToggleKeyDown = (event: KeyboardEvent<HTMLLabelElement>) => {\n switch (event.key) {\n case ' ': // toggle on space\n case 'Enter': // open on enter\n toggle(event);\n break;\n\n default:\n break;\n }\n };\n\n const toggle = (event: KeyboardEvent<HTMLLabelElement>) => {\n event.preventDefault();\n\n if (disabled) {\n return;\n }\n\n // Controlled case - uses \"onChange()\" instead of \"onClick()\" callback\n if (isControlled) {\n onChange(event);\n return;\n }\n\n // Uncontrolled case - set the input checked or unchecked\n if (labelRef.current) {\n const checkbox = labelRef.current.firstChild as HTMLInputElement;\n checkbox.checked = !checkbox.checked;\n }\n };\n\n const text = label || children;\n\n const labelClassnames = classNames('radio', inline && 'radio-inline', className);\n const inputClassnames = classNames(right && 'icon-right', className);\n\n const renderCustomIcon = !!icon;\n const renderCustomContent = custom && children;\n const renderDefault = !icon && !custom;\n\n return (\n <label\n {...remainingProps}\n className={labelClassnames}\n tabIndex={tabIndex}\n onKeyDown={handleToggleKeyDown}\n ref={labelRef}\n >\n <input\n type='radio'\n defaultChecked={defaultChecked}\n checked={checked}\n disabled={disabled}\n className={inputClassnames}\n ref={inputRef}\n onClick={onClick}\n // Only wire onChange for controlled usage; uncontrolled relies on native state + onClick.\n onChange={isControlled ? onChange : undefined}\n name={name}\n value={value}\n />\n {renderCustomIcon && (\n <RadioButtonIcon icon={icon} iconSize={iconSize} iconLabelPosition={iconLabelPosition} text={text} />\n )}\n {renderDefault && (\n <span className='radio-text'>\n <span>{text}</span>\n </span>\n )}\n {renderCustomContent && children}\n </label>\n );\n};\n\nRadioButton.ICON_LABEL_VERTICAL = 'vertical';\nRadioButton.ICON_LABEL_HORIZONTAL = 'horizontal';\n\nexport default RadioButton;\n"],"names":["RadioButtonIcon","props","icon","iconSize","iconLabelPosition","text","iconStyles","jsxs","jsx","RadioButton","label","onClick","noop","onChange","checked","defaultChecked","disabled","className","inline","right","custom","name","value","tabIndex","inputRef","children","remainingProps","isControlled","labelRef","useRef","handleToggleKeyDown","event","toggle","checkbox","labelClassnames","classNames","inputClassnames"],"mappings":"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"}
|
|
@@ -18,8 +18,6 @@ export type ReleaseNotesProps = {
|
|
|
18
18
|
* Translated release notes of the following shape:
|
|
19
19
|
*
|
|
20
20
|
* @example
|
|
21
|
-
*
|
|
22
|
-
* ```tsx
|
|
23
21
|
* {
|
|
24
22
|
* "0.1.2": {
|
|
25
23
|
* date: '23.07.2018',
|
|
@@ -32,7 +30,6 @@ export type ReleaseNotesProps = {
|
|
|
32
30
|
* ),
|
|
33
31
|
* }
|
|
34
32
|
* }
|
|
35
|
-
* ```
|
|
36
33
|
*/
|
|
37
34
|
releaseNotes: ReleaseNotesData;
|
|
38
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReleaseNotes.js","sources":["../../../src/components/releaseNotes/ReleaseNotes.tsx"],"sourcesContent":["import type React from 'react';\nimport { isArray, map, toPairs } from 'es-toolkit/compat';\n\nexport type NoteContent = (React.ReactNode | JSX.Element) | (React.ReactNode | JSX.Element)[];\n\nexport type NoteProps = {\n version: string;\n note: {\n date: string;\n content: NoteContent;\n };\n};\n\nconst Note = (props: NoteProps) => {\n const { note, version } = props;\n const { date, content } = note;\n return (\n <div className='panel panel-default' key={`${version}-note`}>\n <div className='panel-heading'>\n <div className='display-flex justify-content-between'>\n <span className='text-size-16 text-medium'>{`${version}`}</span>\n <span className='text-thin'>{date}</span>\n </div>\n </div>\n <div className='panel-body white-space-pre-line'>\n {isArray(content) ? (\n <ul className='margin-bottom-0 margin-left-5 padding-left-25'>\n {map(content, (item: React.ReactNode) => (\n <li key={`${version}-note-${Math.random()}`}>{item}</li>\n ))}\n </ul>\n ) : (\n <div>{content}</div>\n )}\n </div>\n </div>\n );\n};\n\nexport type ReleaseNotesData = {\n [key: string]: {\n date: string;\n content: NoteContent;\n };\n};\n\nexport type ReleaseNotesProps = {\n /**\n * Translated release notes of the following shape:\n *\n * @example\n
|
|
1
|
+
{"version":3,"file":"ReleaseNotes.js","sources":["../../../src/components/releaseNotes/ReleaseNotes.tsx"],"sourcesContent":["import type React from 'react';\nimport { isArray, map, toPairs } from 'es-toolkit/compat';\n\nexport type NoteContent = (React.ReactNode | JSX.Element) | (React.ReactNode | JSX.Element)[];\n\nexport type NoteProps = {\n version: string;\n note: {\n date: string;\n content: NoteContent;\n };\n};\n\nconst Note = (props: NoteProps) => {\n const { note, version } = props;\n const { date, content } = note;\n return (\n <div className='panel panel-default' key={`${version}-note`}>\n <div className='panel-heading'>\n <div className='display-flex justify-content-between'>\n <span className='text-size-16 text-medium'>{`${version}`}</span>\n <span className='text-thin'>{date}</span>\n </div>\n </div>\n <div className='panel-body white-space-pre-line'>\n {isArray(content) ? (\n <ul className='margin-bottom-0 margin-left-5 padding-left-25'>\n {map(content, (item: React.ReactNode) => (\n <li key={`${version}-note-${Math.random()}`}>{item}</li>\n ))}\n </ul>\n ) : (\n <div>{content}</div>\n )}\n </div>\n </div>\n );\n};\n\nexport type ReleaseNotesData = {\n [key: string]: {\n date: string;\n content: NoteContent;\n };\n};\n\nexport type ReleaseNotesProps = {\n /**\n * Translated release notes of the following shape:\n *\n * @example\n * {\n * \"0.1.2\": {\n * date: '23.07.2018',\n * content: (\n * <div className='padding-left-15'>\n * Map view within the tour history table\n * • Modern map design as used in the Beta of the fleet monitor\n * • Works with all event types\n * </div>\n * ),\n * }\n * }\n */\n releaseNotes: ReleaseNotesData;\n};\n\nconst ReleaseNotes = (props: ReleaseNotesProps) => {\n const { releaseNotes, ...remainingProps } = props;\n return (\n <div {...remainingProps}>\n {map(toPairs(releaseNotes), ([key, note]) => (\n <Note key={key} note={note} version={key} />\n ))}\n </div>\n );\n};\n\nexport default ReleaseNotes;\n"],"names":["Note","props","note","version","date","content","jsxs","jsx","isArray","map","item","ReleaseNotes","releaseNotes","remainingProps","toPairs","key"],"mappings":";;AAaA,MAAMA,IAAO,CAACC,MAAqB;AAC/B,QAAM,EAAE,MAAAC,GAAM,SAAAC,EAAA,IAAYF,GACpB,EAAE,MAAAG,GAAM,SAAAC,EAAA,IAAYH;AAC1B,SACI,gBAAAI,EAAC,OAAA,EAAI,WAAU,uBACX,UAAA;AAAA,IAAA,gBAAAC,EAAC,SAAI,WAAU,iBACX,UAAA,gBAAAD,EAAC,OAAA,EAAI,WAAU,wCACX,UAAA;AAAA,MAAA,gBAAAC,EAAC,QAAA,EAAK,WAAU,4BAA4B,UAAA,GAAGJ,CAAO,IAAG;AAAA,MACzD,gBAAAI,EAAC,QAAA,EAAK,WAAU,aAAa,UAAAH,EAAA,CAAK;AAAA,IAAA,EAAA,CACtC,EAAA,CACJ;AAAA,IACA,gBAAAG,EAAC,OAAA,EAAI,WAAU,mCACV,UAAAC,EAAQH,CAAO,IACZ,gBAAAE,EAAC,MAAA,EAAG,WAAU,iDACT,UAAAE,EAAIJ,GAAS,CAACK,MACX,gBAAAH,EAAC,MAAA,EAA6C,UAAAG,EAAA,GAArC,GAAGP,CAAO,SAAS,KAAK,OAAA,CAAQ,EAAU,CACtD,EAAA,CACL,IAEA,gBAAAI,EAAC,OAAA,EAAK,aAAQ,EAAA,CAEtB;AAAA,EAAA,EAAA,GAjBsC,GAAGJ,CAAO,OAkBpD;AAER,GA8BMQ,IAAe,CAACV,MAA6B;AAC/C,QAAM,EAAE,cAAAW,GAAc,GAAGC,EAAA,IAAmBZ;AAC5C,SACI,gBAAAM,EAAC,SAAK,GAAGM,GACJ,YAAIC,EAAQF,CAAY,GAAG,CAAC,CAACG,GAAKb,CAAI,wBAClCF,GAAA,EAAe,MAAAE,GAAY,SAASa,EAAA,GAA1BA,CAA+B,CAC7C,GACL;AAER;"}
|
|
@@ -10,19 +10,31 @@ export type ResizerProps = {
|
|
|
10
10
|
* Defines where the resize handle is positioned relative to the element to resize.
|
|
11
11
|
*
|
|
12
12
|
* Possible values are:
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
*
|
|
14
|
+
* - `Resizer.LEFT`,
|
|
15
|
+
* - `Resizer.RIGHT`,
|
|
16
|
+
* - `Resizer.TOP`,
|
|
17
|
+
* - `Resizer.BOTTOM`
|
|
18
|
+
* - `'left`',
|
|
19
|
+
* - `'right`',
|
|
20
|
+
* - `'top`',
|
|
21
|
+
* - `'bottom'`
|
|
15
22
|
*/
|
|
16
23
|
position?: typeof LEFT | typeof RIGHT | typeof TOP | typeof BOTTOM;
|
|
17
24
|
/**
|
|
18
25
|
* Defines on which axis to resize.
|
|
19
26
|
*
|
|
20
27
|
* Possible values are:
|
|
21
|
-
*
|
|
28
|
+
*
|
|
29
|
+
* - `Resizer.HORIZONTAL`
|
|
30
|
+
* - `Resizer.VERTICAL`
|
|
31
|
+
* - `'x'`
|
|
32
|
+
* - `'y'`
|
|
22
33
|
*/
|
|
23
34
|
direction?: typeof HORIZONTAL | typeof VERTICAL;
|
|
24
35
|
/**
|
|
25
36
|
* Callback when the resize starts, means when the handle is pressed. It returns the respective event.
|
|
37
|
+
*
|
|
26
38
|
* @param event
|
|
27
39
|
* @returns
|
|
28
40
|
*/
|
|
@@ -31,12 +43,14 @@ export type ResizerProps = {
|
|
|
31
43
|
* Callback when the resize handle is moved. The function returns the distant between the last
|
|
32
44
|
* position and the mouse movement. Means you can either subtract or add this diff to the elements
|
|
33
45
|
* width you want to change.
|
|
46
|
+
*
|
|
34
47
|
* @param diff
|
|
35
48
|
* @returns
|
|
36
49
|
*/
|
|
37
50
|
onResize?: (diff: number) => void;
|
|
38
51
|
/**
|
|
39
52
|
* Callback when the resize ends, means when the handle is released. It returns the respective event.
|
|
53
|
+
*
|
|
40
54
|
* @param event
|
|
41
55
|
* @returns
|
|
42
56
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Resizer.js","sources":["../../../src/components/resizer/Resizer.tsx"],"sourcesContent":["import React, { useEffect, useRef, type MouseEvent, type TouchEvent, type PropsWithChildren } from 'react';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\n\nconst HORIZONTAL = 'x';\nconst VERTICAL = 'y';\n\nconst LEFT = 'left';\nconst RIGHT = 'right';\nconst TOP = 'top';\nconst BOTTOM = 'bottom';\n\nexport type ResizerProps = {\n /**\n * Defines where the resize handle is positioned relative to the element to resize.\n *\n * Possible values are:\n * `Resizer.LEFT`, `Resizer.RIGHT`, `Resizer.TOP`, `Resizer.BOTTOM` or\n * `left`, `right`, `top`, `bottom`.\n */\n position?: typeof LEFT | typeof RIGHT | typeof TOP | typeof BOTTOM;\n\n /**\n * Defines on which axis to resize.\n *\n * Possible values are:\n * `Resizer.HORIZONTAL`, `Resizer.VERTICAL` or `x`, `y`.\n */\n direction?: typeof HORIZONTAL | typeof VERTICAL;\n\n /**\n * Callback when the resize starts, means when the handle is pressed. It returns the respective event.\n * @param event\n * @returns\n */\n onResizeStart?: (event: MouseEvent | TouchEvent) => void;\n\n /**\n * Callback when the resize handle is moved. The function returns the distant between the last\n * position and the mouse movement. Means you can either subtract or add this diff to the elements\n * width you want to change.\n * @param diff\n * @returns\n */\n onResize?: (diff: number) => void;\n\n /**\n * Callback when the resize ends, means when the handle is released. It returns the respective event.\n * @param event\n * @returns\n */\n onResizeEnd?: (event: Event) => void;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\ntype Position = {\n x: number;\n y: number;\n};\n\nconst createListeners = (\n targetNode: HTMLDivElement | null,\n onEnd: (event: Event) => void,\n onMove: (event: Event) => void\n) => {\n if (!targetNode) {\n return;\n }\n\n // The read-only ownerDocument property of the Node interface returns\n // the top-level document object of the node.\n const ownerDocument = targetNode.ownerDocument;\n\n ownerDocument.addEventListener('mouseup', onEnd);\n ownerDocument.addEventListener('mousemove', onMove);\n ownerDocument.addEventListener('touchend', onEnd);\n ownerDocument.addEventListener('touchmove', onMove);\n return {\n remove: () => {\n ownerDocument.removeEventListener('mouseup', onEnd);\n ownerDocument.removeEventListener('mousemove', onMove);\n ownerDocument.removeEventListener('touchend', onEnd);\n ownerDocument.removeEventListener('touchmove', onMove);\n },\n };\n};\n\nconst Resizer = (props: PropsWithChildren<ResizerProps>) => {\n const {\n className = '',\n direction = HORIZONTAL,\n position = RIGHT,\n onResizeStart = noop,\n onResize = noop,\n onResizeEnd = noop,\n children,\n ...remainingProps\n } = props;\n\n const eventsRef = useRef<{ remove: () => void } | undefined | null>(null);\n\n // Use refs here instead of local state as the move event listener fired before the state is set\n // and then it would work with outdated state at that time.\n const elementRef = useRef<HTMLDivElement>(null);\n const isDragRef = useRef<boolean>(false);\n const startPositionRef = useRef<Position>({ x: 0, y: 0 });\n\n useEffect(() => {\n return () => {\n removeListeners();\n };\n }, []);\n\n const getClientX = (event: Event) => {\n // Note: some browsers don't provide the global \"TouchEvent\" constructor!\n if (!!window.TouchEvent && event instanceof window.TouchEvent) {\n return event.touches[0].clientX;\n }\n\n if (event instanceof MouseEvent) {\n return event.clientX;\n }\n\n throw new Error('Unsupported event type');\n };\n\n const getClientY = (event: Event) => {\n // Note: some browsers don't provide the global \"TouchEvent\" constructor!\n if (!!window.TouchEvent && event instanceof window.TouchEvent) {\n return event.touches[0].clientY;\n }\n\n if (event instanceof MouseEvent) {\n return event.clientY;\n }\n\n throw new Error('Unsupported event type');\n };\n\n const handleMouseStart = (event: React.MouseEvent) => {\n isDragRef.current = true;\n\n // Use the native event to check for the event type. Otherwise the type check\n // fails and the start position would be { x: 0, y: 0 }.\n const mouseEvent = event.nativeEvent;\n const { clientX, clientY } = mouseEvent;\n startPositionRef.current = {\n x: clientX,\n y: clientY,\n };\n\n onResizeStart(event);\n\n eventsRef.current = createListeners(elementRef.current, handleEnd, handleMove);\n };\n\n const handleTouchStart = (event: React.TouchEvent) => {\n isDragRef.current = true;\n\n // Use the native event to check for the event type. Otherwise the type check\n // fails and the start position would be { x: 0, y: 0 }.\n const touchEvent = event.nativeEvent;\n const firstTouch = touchEvent.touches[0];\n startPositionRef.current = {\n x: firstTouch.clientX,\n y: firstTouch.clientY,\n };\n\n onResizeStart(event);\n\n eventsRef.current = createListeners(elementRef.current, handleEnd, handleMove);\n };\n\n const handleMove = (event: Event) => {\n if (!isDragRef.current) {\n return;\n }\n\n if (direction === Resizer.HORIZONTAL) {\n const diff = startPositionRef.current.x - getClientX(event);\n\n if (diff !== 0) {\n onResize(diff);\n }\n }\n\n if (direction === Resizer.VERTICAL) {\n const diff = startPositionRef.current.y - getClientY(event);\n if (diff !== 0) {\n onResize(diff);\n }\n }\n\n startPositionRef.current = {\n x: getClientX(event),\n y: getClientY(event),\n };\n };\n\n const handleEnd = (event: Event) => {\n isDragRef.current = false;\n onResizeEnd(event);\n removeListeners();\n };\n\n const removeListeners = () => {\n if (eventsRef.current) {\n eventsRef.current.remove();\n }\n };\n\n const wrapperClasses = classNames(\n 'Resizer',\n direction === 'x' && 'resize-horizontal',\n direction === 'y' && 'resize-vertical',\n position === 'left' && 'resize-left',\n position === 'right' && 'resize-right',\n position === 'top' && 'resize-top',\n position === 'bottom' && 'resize-bottom',\n className && className\n );\n\n return (\n <div\n ref={elementRef}\n className={wrapperClasses}\n onMouseDown={handleMouseStart}\n onTouchStart={handleTouchStart}\n {...remainingProps}\n >\n {children}\n </div>\n );\n};\n\nResizer.HORIZONTAL = HORIZONTAL as typeof HORIZONTAL;\nResizer.VERTICAL = VERTICAL as typeof VERTICAL;\n\nResizer.LEFT = LEFT as typeof LEFT;\nResizer.RIGHT = RIGHT as typeof RIGHT;\nResizer.TOP = TOP as typeof TOP;\nResizer.BOTTOM = BOTTOM as typeof BOTTOM;\n\nexport default Resizer;\n"],"names":["HORIZONTAL","VERTICAL","LEFT","RIGHT","TOP","BOTTOM","createListeners","targetNode","onEnd","onMove","ownerDocument","Resizer","props","className","direction","position","onResizeStart","noop","onResize","onResizeEnd","children","remainingProps","eventsRef","useRef","elementRef","isDragRef","startPositionRef","useEffect","removeListeners","getClientX","event","getClientY","handleMouseStart","mouseEvent","clientX","clientY","handleEnd","handleMove","handleTouchStart","firstTouch","diff","wrapperClasses","classNames","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Resizer.js","sources":["../../../src/components/resizer/Resizer.tsx"],"sourcesContent":["import React, { useEffect, useRef, type MouseEvent, type TouchEvent, type PropsWithChildren } from 'react';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\n\nconst HORIZONTAL = 'x';\nconst VERTICAL = 'y';\n\nconst LEFT = 'left';\nconst RIGHT = 'right';\nconst TOP = 'top';\nconst BOTTOM = 'bottom';\n\nexport type ResizerProps = {\n /**\n * Defines where the resize handle is positioned relative to the element to resize.\n *\n * Possible values are:\n *\n * - `Resizer.LEFT`,\n * - `Resizer.RIGHT`,\n * - `Resizer.TOP`,\n * - `Resizer.BOTTOM`\n * - `'left`',\n * - `'right`',\n * - `'top`',\n * - `'bottom'`\n */\n position?: typeof LEFT | typeof RIGHT | typeof TOP | typeof BOTTOM;\n\n /**\n * Defines on which axis to resize.\n *\n * Possible values are:\n *\n * - `Resizer.HORIZONTAL`\n * - `Resizer.VERTICAL`\n * - `'x'`\n * - `'y'`\n */\n direction?: typeof HORIZONTAL | typeof VERTICAL;\n\n /**\n * Callback when the resize starts, means when the handle is pressed. It returns the respective event.\n *\n * @param event\n * @returns\n */\n onResizeStart?: (event: MouseEvent | TouchEvent) => void;\n\n /**\n * Callback when the resize handle is moved. The function returns the distant between the last\n * position and the mouse movement. Means you can either subtract or add this diff to the elements\n * width you want to change.\n *\n * @param diff\n * @returns\n */\n onResize?: (diff: number) => void;\n\n /**\n * Callback when the resize ends, means when the handle is released. It returns the respective event.\n *\n * @param event\n * @returns\n */\n onResizeEnd?: (event: Event) => void;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\ntype Position = {\n x: number;\n y: number;\n};\n\nconst createListeners = (\n targetNode: HTMLDivElement | null,\n onEnd: (event: Event) => void,\n onMove: (event: Event) => void\n) => {\n if (!targetNode) {\n return;\n }\n\n // The read-only ownerDocument property of the Node interface returns\n // the top-level document object of the node.\n const ownerDocument = targetNode.ownerDocument;\n\n ownerDocument.addEventListener('mouseup', onEnd);\n ownerDocument.addEventListener('mousemove', onMove);\n ownerDocument.addEventListener('touchend', onEnd);\n ownerDocument.addEventListener('touchmove', onMove);\n return {\n remove: () => {\n ownerDocument.removeEventListener('mouseup', onEnd);\n ownerDocument.removeEventListener('mousemove', onMove);\n ownerDocument.removeEventListener('touchend', onEnd);\n ownerDocument.removeEventListener('touchmove', onMove);\n },\n };\n};\n\nconst Resizer = (props: PropsWithChildren<ResizerProps>) => {\n const {\n className = '',\n direction = HORIZONTAL,\n position = RIGHT,\n onResizeStart = noop,\n onResize = noop,\n onResizeEnd = noop,\n children,\n ...remainingProps\n } = props;\n\n const eventsRef = useRef<{ remove: () => void } | undefined | null>(null);\n\n // Use refs here instead of local state as the move event listener fired before the state is set\n // and then it would work with outdated state at that time.\n const elementRef = useRef<HTMLDivElement>(null);\n const isDragRef = useRef<boolean>(false);\n const startPositionRef = useRef<Position>({ x: 0, y: 0 });\n\n useEffect(() => {\n return () => {\n removeListeners();\n };\n }, []);\n\n const getClientX = (event: Event) => {\n // Note: some browsers don't provide the global \"TouchEvent\" constructor!\n if (!!window.TouchEvent && event instanceof window.TouchEvent) {\n return event.touches[0].clientX;\n }\n\n if (event instanceof MouseEvent) {\n return event.clientX;\n }\n\n throw new Error('Unsupported event type');\n };\n\n const getClientY = (event: Event) => {\n // Note: some browsers don't provide the global \"TouchEvent\" constructor!\n if (!!window.TouchEvent && event instanceof window.TouchEvent) {\n return event.touches[0].clientY;\n }\n\n if (event instanceof MouseEvent) {\n return event.clientY;\n }\n\n throw new Error('Unsupported event type');\n };\n\n const handleMouseStart = (event: React.MouseEvent) => {\n isDragRef.current = true;\n\n // Use the native event to check for the event type. Otherwise the type check\n // fails and the start position would be { x: 0, y: 0 }.\n const mouseEvent = event.nativeEvent;\n const { clientX, clientY } = mouseEvent;\n startPositionRef.current = {\n x: clientX,\n y: clientY,\n };\n\n onResizeStart(event);\n\n eventsRef.current = createListeners(elementRef.current, handleEnd, handleMove);\n };\n\n const handleTouchStart = (event: React.TouchEvent) => {\n isDragRef.current = true;\n\n // Use the native event to check for the event type. Otherwise the type check\n // fails and the start position would be { x: 0, y: 0 }.\n const touchEvent = event.nativeEvent;\n const firstTouch = touchEvent.touches[0];\n startPositionRef.current = {\n x: firstTouch.clientX,\n y: firstTouch.clientY,\n };\n\n onResizeStart(event);\n\n eventsRef.current = createListeners(elementRef.current, handleEnd, handleMove);\n };\n\n const handleMove = (event: Event) => {\n if (!isDragRef.current) {\n return;\n }\n\n if (direction === Resizer.HORIZONTAL) {\n const diff = startPositionRef.current.x - getClientX(event);\n\n if (diff !== 0) {\n onResize(diff);\n }\n }\n\n if (direction === Resizer.VERTICAL) {\n const diff = startPositionRef.current.y - getClientY(event);\n if (diff !== 0) {\n onResize(diff);\n }\n }\n\n startPositionRef.current = {\n x: getClientX(event),\n y: getClientY(event),\n };\n };\n\n const handleEnd = (event: Event) => {\n isDragRef.current = false;\n onResizeEnd(event);\n removeListeners();\n };\n\n const removeListeners = () => {\n if (eventsRef.current) {\n eventsRef.current.remove();\n }\n };\n\n const wrapperClasses = classNames(\n 'Resizer',\n direction === 'x' && 'resize-horizontal',\n direction === 'y' && 'resize-vertical',\n position === 'left' && 'resize-left',\n position === 'right' && 'resize-right',\n position === 'top' && 'resize-top',\n position === 'bottom' && 'resize-bottom',\n className && className\n );\n\n return (\n <div\n ref={elementRef}\n className={wrapperClasses}\n onMouseDown={handleMouseStart}\n onTouchStart={handleTouchStart}\n {...remainingProps}\n >\n {children}\n </div>\n );\n};\n\nResizer.HORIZONTAL = HORIZONTAL as typeof HORIZONTAL;\nResizer.VERTICAL = VERTICAL as typeof VERTICAL;\n\nResizer.LEFT = LEFT as typeof LEFT;\nResizer.RIGHT = RIGHT as typeof RIGHT;\nResizer.TOP = TOP as typeof TOP;\nResizer.BOTTOM = BOTTOM as typeof BOTTOM;\n\nexport default Resizer;\n"],"names":["HORIZONTAL","VERTICAL","LEFT","RIGHT","TOP","BOTTOM","createListeners","targetNode","onEnd","onMove","ownerDocument","Resizer","props","className","direction","position","onResizeStart","noop","onResize","onResizeEnd","children","remainingProps","eventsRef","useRef","elementRef","isDragRef","startPositionRef","useEffect","removeListeners","getClientX","event","getClientY","handleMouseStart","mouseEvent","clientX","clientY","handleEnd","handleMove","handleTouchStart","firstTouch","diff","wrapperClasses","classNames","jsx"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { RioglyphIconType } from './RioglyphIconType';
|
|
|
2
2
|
export type IconType = RioglyphIconType;
|
|
3
3
|
export type RioglyphProps = {
|
|
4
4
|
/**
|
|
5
|
-
* The icon
|
|
5
|
+
* The rioglyph icon string OR an external .svg link
|
|
6
6
|
*/
|
|
7
7
|
icon: IconType | string;
|
|
8
8
|
/**
|
|
@@ -14,31 +14,43 @@ export type RioglyphProps = {
|
|
|
14
14
|
*/
|
|
15
15
|
size?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | '10' | '11' | '12' | '14' | '16' | '18' | '20';
|
|
16
16
|
/**
|
|
17
|
-
* Spinning animation
|
|
17
|
+
* Spinning animation.
|
|
18
|
+
*
|
|
19
|
+
* @default false
|
|
18
20
|
*/
|
|
19
21
|
spinning?: boolean;
|
|
20
22
|
/**
|
|
21
|
-
* Pulsing animation
|
|
23
|
+
* Pulsing animation.
|
|
24
|
+
*
|
|
25
|
+
* @default false
|
|
22
26
|
*/
|
|
23
27
|
pulsing?: boolean;
|
|
24
28
|
/**
|
|
25
|
-
* Filled style
|
|
29
|
+
* Filled style.
|
|
30
|
+
*
|
|
31
|
+
* @default false
|
|
26
32
|
*/
|
|
27
33
|
filled?: boolean;
|
|
28
34
|
/**
|
|
29
|
-
*
|
|
35
|
+
* Add a disabled line
|
|
36
|
+
*
|
|
37
|
+
* @default false
|
|
30
38
|
*/
|
|
31
39
|
disabled?: boolean;
|
|
32
40
|
/**
|
|
33
|
-
*
|
|
41
|
+
* Recolor the disabled line to the danger color.
|
|
42
|
+
*
|
|
43
|
+
* @default false
|
|
34
44
|
*/
|
|
35
45
|
disabledDanger?: boolean;
|
|
36
46
|
/**
|
|
37
|
-
*
|
|
47
|
+
* Flip the disabled line.
|
|
48
|
+
*
|
|
49
|
+
* @default false
|
|
38
50
|
*/
|
|
39
51
|
disabledInverse?: boolean;
|
|
40
52
|
/**
|
|
41
|
-
* The icon
|
|
53
|
+
* The rioglyph icon string OR an external .svg link.
|
|
42
54
|
*/
|
|
43
55
|
pairIcon?: IconType | string;
|
|
44
56
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rioglyph.js","sources":["../../../src/components/rioglyph/Rioglyph.tsx"],"sourcesContent":["import classNames from 'classnames';\n\nimport type { RioglyphIconType } from './RioglyphIconType';\n\nexport type IconType = RioglyphIconType;\n\nexport type RioglyphProps = {\n /**\n * The icon
|
|
1
|
+
{"version":3,"file":"Rioglyph.js","sources":["../../../src/components/rioglyph/Rioglyph.tsx"],"sourcesContent":["import classNames from 'classnames';\n\nimport type { RioglyphIconType } from './RioglyphIconType';\n\nexport type IconType = RioglyphIconType;\n\nexport type RioglyphProps = {\n /**\n * The rioglyph icon string OR an external .svg link\n */\n icon: IconType | string;\n\n /**\n * Additional classes set to the icon span.\n */\n iconClassName?: string;\n\n /**\n * The size (text-size) of the icon\n */\n size?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | '10' | '11' | '12' | '14' | '16' | '18' | '20';\n\n /**\n * Spinning animation.\n * \n * @default false\n */\n spinning?: boolean;\n\n /**\n * Pulsing animation.\n * \n * @default false\n */\n pulsing?: boolean;\n\n /**\n * Filled style.\n * \n * @default false\n */\n filled?: boolean;\n\n /**\n * Add a disabled line\n * \n * @default false\n */\n disabled?: boolean;\n\n /**\n * Recolor the disabled line to the danger color.\n * \n * @default false\n */\n disabledDanger?: boolean;\n\n /**\n * Flip the disabled line.\n * \n * @default false\n */\n disabledInverse?: boolean;\n\n /**\n * The rioglyph icon string OR an external .svg link.\n */\n pairIcon?: IconType | string;\n\n /**\n * Additional classes set to the pairIcon span.\n */\n pairIconClassName?: string;\n};\n\nconst Rioglyph = (props: RioglyphProps) => {\n const {\n icon,\n iconClassName = '',\n pairIcon,\n pairIconClassName = '',\n size,\n spinning = false,\n pulsing = false,\n filled = false,\n disabled = false,\n disabledDanger = false,\n disabledInverse = false,\n } = props;\n\n const spinningClass = spinning ? 'spinning' : '';\n const pulsingClass = pulsing ? 'pulsing' : '';\n const filledClass = filled ? 'rioglyph-filled' : '';\n const disabledClass = disabled ? 'rioglyph-disabled' : '';\n const disabledDangerClass = disabledDanger ? 'rioglyph-disabled rioglyph-disabled-danger' : '';\n const disabledInverseClass = disabledInverse ? 'rioglyph-disabled rioglyph-disabled-inverse' : '';\n\n let iconStyle: React.CSSProperties | undefined;\n if (icon.includes('.svg')) {\n iconStyle = { '--i': `url(${icon})` } as React.CSSProperties;\n }\n\n if (pairIcon) {\n const wrapperClasses = classNames('rioglyph-icon-pair', size && `text-size-${size}`);\n const iconClasses = classNames('rioglyph', !icon.includes('.svg') && icon, iconClassName);\n const pairIconClasses = classNames(\n 'rioglyph',\n !pairIcon.includes('.svg') && pairIcon,\n pairIconClassName,\n spinningClass,\n pulsingClass\n );\n\n let pairIconStyle: React.CSSProperties | undefined;\n if (pairIcon?.includes('.svg')) {\n pairIconStyle = { '--i': `url(${pairIcon})` } as React.CSSProperties;\n }\n\n return (\n <span className={wrapperClasses}>\n <span className={iconClasses} style={iconStyle} />\n <span className={pairIconClasses} style={pairIconStyle} />\n </span>\n );\n }\n\n const iconClasses = classNames(\n 'rioglyph',\n !icon.includes('.svg') && icon,\n size && `text-size-${size}`,\n disabledClass,\n disabledDangerClass,\n disabledInverseClass,\n iconClassName,\n spinningClass,\n pulsingClass,\n filledClass\n );\n\n return <span className={iconClasses} style={iconStyle} />;\n};\n\nexport default Rioglyph;\n"],"names":["Rioglyph","props","icon","iconClassName","pairIcon","pairIconClassName","size","spinning","pulsing","filled","disabled","disabledDanger","disabledInverse","spinningClass","pulsingClass","filledClass","disabledClass","disabledDangerClass","disabledInverseClass","iconStyle","wrapperClasses","classNames","iconClasses","pairIconClasses","pairIconStyle","jsxs","jsx"],"mappings":";;AA2EA,MAAMA,IAAW,CAACC,MAAyB;AACvC,QAAM;AAAA,IACF,MAAAC;AAAA,IACA,eAAAC,IAAgB;AAAA,IAChB,UAAAC;AAAA,IACA,mBAAAC,IAAoB;AAAA,IACpB,MAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,SAAAC,IAAU;AAAA,IACV,QAAAC,IAAS;AAAA,IACT,UAAAC,IAAW;AAAA,IACX,gBAAAC,IAAiB;AAAA,IACjB,iBAAAC,IAAkB;AAAA,EAAA,IAClBX,GAEEY,IAAgBN,IAAW,aAAa,IACxCO,IAAeN,IAAU,YAAY,IACrCO,IAAcN,IAAS,oBAAoB,IAC3CO,IAAgBN,IAAW,sBAAsB,IACjDO,IAAsBN,IAAiB,+CAA+C,IACtFO,IAAuBN,IAAkB,gDAAgD;AAE/F,MAAIO;AAKJ,MAJIjB,EAAK,SAAS,MAAM,MACpBiB,IAAY,EAAE,OAAO,OAAOjB,CAAI,IAAA,IAGhCE,GAAU;AACV,UAAMgB,IAAiBC,EAAW,sBAAsBf,KAAQ,aAAaA,CAAI,EAAE,GAC7EgB,IAAcD,EAAW,YAAY,CAACnB,EAAK,SAAS,MAAM,KAAKA,GAAMC,CAAa,GAClFoB,IAAkBF;AAAA,MACpB;AAAA,MACA,CAACjB,EAAS,SAAS,MAAM,KAAKA;AAAA,MAC9BC;AAAA,MACAQ;AAAA,MACAC;AAAA,IAAA;AAGJ,QAAIU;AACJ,WAAIpB,GAAU,SAAS,MAAM,MACzBoB,IAAgB,EAAE,OAAO,OAAOpB,CAAQ,IAAA,IAIxC,gBAAAqB,EAAC,QAAA,EAAK,WAAWL,GACb,UAAA;AAAA,MAAA,gBAAAM,EAAC,QAAA,EAAK,WAAWJ,GAAa,OAAOH,GAAW;AAAA,MAChD,gBAAAO,EAAC,QAAA,EAAK,WAAWH,GAAiB,OAAOC,EAAA,CAAe;AAAA,IAAA,GAC5D;AAAA,EAER;AAEA,QAAMF,IAAcD;AAAA,IAChB;AAAA,IACA,CAACnB,EAAK,SAAS,MAAM,KAAKA;AAAA,IAC1BI,KAAQ,aAAaA,CAAI;AAAA,IACzBU;AAAA,IACAC;AAAA,IACAC;AAAA,IACAf;AAAA,IACAU;AAAA,IACAC;AAAA,IACAC;AAAA,EAAA;AAGJ,SAAO,gBAAAW,EAAC,QAAA,EAAK,WAAWJ,GAAa,OAAOH,GAAW;AAC3D;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as i } from "react/jsx-runtime";
|
|
2
2
|
import { motion as e, AnimatePresence as r } from "motion/react";
|
|
3
3
|
const n = ({ children: o, ...t }) => (
|
|
4
|
-
// @ts-
|
|
4
|
+
// @ts-expect-error-next-line
|
|
5
5
|
/* @__PURE__ */ i(e.div, { initial: !1, layout: !0, ...t, children: /* @__PURE__ */ i(r, { children: /* @__PURE__ */ i(e.div, { layout: "position", children: o }) }) })
|
|
6
6
|
);
|
|
7
7
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RulesWrapper.js","sources":["../../../src/components/rules/RulesWrapper.tsx"],"sourcesContent":["import type { HTMLAttributes, PropsWithChildren } from 'react';\nimport { AnimatePresence, motion } from 'motion/react';\n\ntype RulesWrapperProps = HTMLAttributes<HTMLDivElement>;\n\nconst RulesWrapper = ({ children, ...remainingProps }: PropsWithChildren<RulesWrapperProps>) => (\n // @ts-
|
|
1
|
+
{"version":3,"file":"RulesWrapper.js","sources":["../../../src/components/rules/RulesWrapper.tsx"],"sourcesContent":["import type { HTMLAttributes, PropsWithChildren } from 'react';\nimport { AnimatePresence, motion } from 'motion/react';\n\ntype RulesWrapperProps = HTMLAttributes<HTMLDivElement>;\n\nconst RulesWrapper = ({ children, ...remainingProps }: PropsWithChildren<RulesWrapperProps>) => (\n // @ts-expect-error-next-line\n <motion.div initial={false} layout {...remainingProps}>\n <AnimatePresence>\n <motion.div layout='position'>{children}</motion.div>\n </AnimatePresence>\n </motion.div>\n);\n\nexport default RulesWrapper;\n"],"names":["RulesWrapper","children","remainingProps","jsx","motion","AnimatePresence"],"mappings":";;AAKA,MAAMA,IAAe,CAAC,EAAE,UAAAC,GAAU,GAAGC,EAAA;AAAA;AAAA,EAEjC,gBAAAC,EAACC,EAAO,KAAP,EAAW,SAAS,IAAO,QAAM,IAAE,GAAGF,GACnC,4BAACG,GAAA,EACG,UAAA,gBAAAF,EAACC,EAAO,KAAP,EAAW,QAAO,YAAY,UAAAH,GAAS,GAC5C,EAAA,CACJ;AAAA;"}
|
|
@@ -18,15 +18,20 @@ export type SaveableDateInputProps = {
|
|
|
18
18
|
*/
|
|
19
19
|
isValid?: boolean;
|
|
20
20
|
/**
|
|
21
|
-
* This is the error message that is shown below the input. It uses the built-in error handling,
|
|
21
|
+
* This is the error message that is shown below the input. It uses the built-in error handling,
|
|
22
|
+
* and will be shown when the "isValid" prop is set to false.
|
|
22
23
|
*/
|
|
23
24
|
errorMessage?: string | React.ReactNode;
|
|
24
25
|
/**
|
|
25
|
-
* Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop
|
|
26
|
+
* Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop
|
|
27
|
+
* is set to false.
|
|
28
|
+
*
|
|
29
|
+
* @default false
|
|
26
30
|
*/
|
|
27
31
|
hideErrorIcon?: boolean;
|
|
28
32
|
/**
|
|
29
33
|
* Callback function triggered when the value changes and is saved.
|
|
34
|
+
*
|
|
30
35
|
* @param value
|
|
31
36
|
* @param previousValue
|
|
32
37
|
* @returns
|
|
@@ -35,6 +40,7 @@ export type SaveableDateInputProps = {
|
|
|
35
40
|
/**
|
|
36
41
|
* Callback function that gets triggered on every input change. Use this to control the component
|
|
37
42
|
* or when implementing key validation.
|
|
43
|
+
*
|
|
38
44
|
* @param keyValue the key value that has been entered
|
|
39
45
|
* @returns
|
|
40
46
|
*/
|
|
@@ -42,11 +48,13 @@ export type SaveableDateInputProps = {
|
|
|
42
48
|
/**
|
|
43
49
|
* Callback function that gets triggered when the input is in edit mode. Use this
|
|
44
50
|
* to control the component and to handle the previous value on the outside.
|
|
51
|
+
*
|
|
45
52
|
* @returns
|
|
46
53
|
*/
|
|
47
54
|
onEnterEdit?: () => void;
|
|
48
55
|
/**
|
|
49
56
|
* Callback function that gets triggered when edit mode is exited (either saved or cancelled).
|
|
57
|
+
*
|
|
50
58
|
* @param wasSaved - true if value was saved, false if cancelled/reset
|
|
51
59
|
* @returns
|
|
52
60
|
*/
|
|
@@ -54,6 +62,7 @@ export type SaveableDateInputProps = {
|
|
|
54
62
|
/**
|
|
55
63
|
* Callback function that gets triggered when the user aborts the edit mode. Use this
|
|
56
64
|
* to control the component and handle the resetting of previous value on the outside.
|
|
65
|
+
*
|
|
57
66
|
* @returns
|
|
58
67
|
*/
|
|
59
68
|
onCancel?: () => void;
|
|
@@ -67,15 +76,24 @@ export type SaveableDateInputProps = {
|
|
|
67
76
|
invalidExitBehavior?: 'stay-open' | 'reset-and-close';
|
|
68
77
|
/**
|
|
69
78
|
* Defines the button style: `default` or `primary`.
|
|
79
|
+
*
|
|
80
|
+
* @default 'primary'
|
|
70
81
|
*/
|
|
71
82
|
buttonStyle?: 'primary' | 'default';
|
|
72
83
|
/**
|
|
73
84
|
* Additional HTML attributes to be set on the input element.
|
|
74
85
|
*/
|
|
75
86
|
inputProps?: HTMLAttributes<HTMLInputElement>;
|
|
87
|
+
/**
|
|
88
|
+
* Additional props passed to the underlying DatePicker component.
|
|
89
|
+
*
|
|
90
|
+
* @default {}
|
|
91
|
+
*/
|
|
76
92
|
datePickerProps?: DatePickerProps;
|
|
77
93
|
/**
|
|
78
94
|
* Disables the component so the user cannot enter the edit mode.
|
|
95
|
+
*
|
|
96
|
+
* @default false
|
|
79
97
|
*/
|
|
80
98
|
disabled?: boolean;
|
|
81
99
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SaveableDateInput.js","sources":["../../../src/components/saveableInput/SaveableDateInput.tsx"],"sourcesContent":["import { useRef, useState, type HTMLAttributes, type CSSProperties } from 'react';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\nimport type { Moment } from 'moment';\n\nimport Button from '../../Button';\nimport DatePicker, { type DatePickerProps } from '../datepicker/DatePicker';\nimport useIsFocusWithin from '../../hooks/useIsFocusWithin';\nimport useEsc from '../../hooks/useEsc';\n\nconst DEFAULT_BUTTON_STYLE = 'primary';\n\nexport type SaveableDateInputProps = {\n /**\n * The input placeholder.\n */\n placeholder?: string;\n\n /**\n * The actual input value.\n */\n value?: Date | Moment | string;\n\n /**\n * Used to control the save button from the outside to disable it in case\n * the entered value is not valid.\n *\n * @default true\n */\n isValid?: boolean;\n\n /**\n * This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the \"isValid\" prop is set to false.\n */\n errorMessage?: string | React.ReactNode;\n\n /**\n * Defines wether the error icon is shown or not. If enabled, it will be shown when the \"isValid\" prop is set to false.\n */\n hideErrorIcon?: boolean;\n\n /**\n * Callback function triggered when the value changes and is saved.\n * @param value\n * @param previousValue\n * @returns\n */\n onValueChanged?: (value: Moment | string, previousValue: Moment | string | Date) => void;\n\n /**\n * Callback function that gets triggered on every input change. Use this to control the component\n * or when implementing key validation.\n * @param keyValue the key value that has been entered\n * @returns\n */\n onInputChange?: (value: Moment | string, isValid: boolean) => void;\n\n /**\n * Callback function that gets triggered when the input is in edit mode. Use this\n * to control the component and to handle the previous value on the outside.\n * @returns\n */\n onEnterEdit?: () => void;\n\n /**\n * Callback function that gets triggered when edit mode is exited (either saved or cancelled).\n * @param wasSaved - true if value was saved, false if cancelled/reset\n * @returns\n */\n onExitEdit?: (wasSaved: boolean) => void;\n\n /**\n * Callback function that gets triggered when the user aborts the edit mode. Use this\n * to control the component and handle the resetting of previous value on the outside.\n * @returns\n */\n onCancel?: () => void;\n\n /**\n * Behavior when trying to exit edit mode with invalid input:\n * - 'stay-open': Keep edit mode open until valid input is provided\n * - 'reset-and-close': Close edit mode and reset to initial value\n *\n * @default 'stay-open'\n */\n invalidExitBehavior?: 'stay-open' | 'reset-and-close';\n\n /**\n * Defines the button style: `default` or `primary`.\n */\n buttonStyle?: 'primary' | 'default';\n\n /**\n * Additional HTML attributes to be set on the input element.\n */\n inputProps?: HTMLAttributes<HTMLInputElement>;\n\n datePickerProps?: DatePickerProps;\n\n /**\n * Disables the component so the user cannot enter the edit mode.\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the input itself.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\n// Validate date outside the component (via form library) if controlled usage\n// Use as controlled component: value, is Valid, and change callback\n// - if is valid, on save, call callback \"onValueChanged\"\n// - if not valid, keep edit mode open, outside is showing error message\n// - close edit mode only if date is valid - or close edit mode and reset to initial value -> customizable via prop\n// Keep picker open until user has clicked save, otherwise he might forget to click save if the dropdown closes automatically\n\nconst SaveableDateInput = (props: SaveableDateInputProps) => {\n const {\n placeholder,\n value: externalValue = '',\n isValid = true,\n errorMessage,\n hideErrorIcon = false,\n onValueChanged = noop,\n onInputChange, // for controlled usage\n onEnterEdit = noop,\n onExitEdit = noop,\n onCancel = noop,\n buttonStyle = DEFAULT_BUTTON_STYLE,\n inputClassName,\n inputProps,\n invalidExitBehavior = 'stay-open',\n datePickerProps = {},\n disabled = false,\n className,\n ...remainingProps\n } = props;\n\n // if callback is provided, assume it is controlled case\n const isControlledCase = onInputChange !== undefined;\n\n const [inputValue, setInputValue] = useState<Date | Moment | string>(externalValue);\n\n const [editInput, setEditInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const [isPickerOpen, setIsPickerOpen] = useState(false);\n\n const wrapperRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const initialInputValueRef = useRef(inputValue);\n\n useIsFocusWithin({\n ref: wrapperRef,\n onFocusWithin: () => {\n setIsFocused(true);\n },\n onBlurWithin: () => {\n setIsFocused(false);\n },\n });\n\n // Handle escape key to cancel edit mode\n useEsc(() => {\n if (isFocused && editInput) {\n handleCancelEdit();\n }\n });\n\n // Update internal state in a controlled environment\n const [previousExternalValue, setPreviousExternalValue] = useState(externalValue);\n if (previousExternalValue !== externalValue) {\n setInputValue(externalValue);\n setPreviousExternalValue(externalValue);\n // Update initial value ref when external value changes while not in edit mode\n if (!editInput) {\n initialInputValueRef.current = externalValue;\n }\n }\n\n const handleToggleInput = () => {\n if (!editInput) {\n // Enter edit mode\n setEditInput(true);\n initialInputValueRef.current = inputValue;\n\n // open the dropdown\n setIsPickerOpen(true);\n\n onEnterEdit();\n } else {\n // Try to exit edit mode\n handleSaveAttempt();\n }\n };\n\n const handleSaveAttempt = () => {\n if (isValid) {\n // Save the value (only if valid)\n setEditInput(false);\n onValueChanged(inputValue as Moment | string, initialInputValueRef.current);\n onExitEdit(true);\n\n // close the dropdown\n setIsPickerOpen(false);\n } else {\n // Handle invalid input based on behavior setting\n if (invalidExitBehavior === 'reset-and-close') {\n handleCancelEdit();\n }\n // If 'stay-open', do nothing - keep edit mode open\n }\n };\n\n const handleCancelEdit = () => {\n setEditInput(false);\n\n // Reset to initial value\n if (isControlledCase) {\n // In controlled mode, trigger change to reset to initial value\n onInputChange(initialInputValueRef.current as Moment | string, true);\n } else {\n setInputValue(initialInputValueRef.current);\n }\n\n // Close the dropdown\n setIsPickerOpen(false);\n\n onCancel();\n onExitEdit(false);\n };\n\n const handleDateChange = (value: Moment | string, isValid: boolean) => {\n if (isControlledCase) {\n onInputChange(value, isValid);\n } else {\n setInputValue(value);\n }\n };\n\n const handleCloseDropdown = () => setIsPickerOpen(false);\n\n const wrapperClasses = classNames('form-group', !isValid && 'has-feedback has-error', className);\n\n const buttonIconClasses = classNames('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');\n\n const dateInputClasses = classNames('margin-0 width-100pct', inputClassName);\n\n // Button should be disabled if:\n // - Component is disabled, OR\n // - In edit mode and invalid input (and behavior is stay-open)\n const disableButton = disabled || (editInput && !isValid && invalidExitBehavior === 'stay-open');\n\n let inputStyle: CSSProperties = {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n };\n\n if (!isValid && hideErrorIcon) {\n // If the error icon shall not be shown, remove the input padding to avoid cutting of the date value\n inputStyle = { ...inputStyle, paddingRight: '10px' };\n }\n\n return (\n <div ref={wrapperRef} {...remainingProps} className={wrapperClasses}>\n <div className='input-group'>\n <DatePicker\n {...{ ...datePickerProps, open: isPickerOpen }}\n className={dateInputClasses}\n inputProps={{\n ...inputProps,\n placeholder,\n disabled: !editInput,\n style: inputStyle,\n }}\n value={inputValue}\n onChange={handleDateChange}\n onClose={handleCloseDropdown}\n />\n {!isValid && !hideErrorIcon && (\n <span className='right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' />\n )}\n <div className='input-group-btn'>\n <Button\n ref={buttonRef}\n bsStyle={buttonStyle}\n iconOnly\n onClick={handleToggleInput}\n disabled={disableButton}\n >\n <span className={buttonIconClasses} />\n </Button>\n </div>\n </div>\n {!isValid && errorMessage && (\n <span className='help-block z-index-max'>\n <span>{errorMessage}</span>\n </span>\n )}\n </div>\n );\n};\n\nexport default SaveableDateInput;\n"],"names":["DEFAULT_BUTTON_STYLE","SaveableDateInput","props","placeholder","externalValue","isValid","errorMessage","hideErrorIcon","onValueChanged","noop","onInputChange","onEnterEdit","onExitEdit","onCancel","buttonStyle","inputClassName","inputProps","invalidExitBehavior","datePickerProps","disabled","className","remainingProps","isControlledCase","inputValue","setInputValue","useState","editInput","setEditInput","isFocused","setIsFocused","isPickerOpen","setIsPickerOpen","wrapperRef","useRef","buttonRef","initialInputValueRef","useIsFocusWithin","useEsc","handleCancelEdit","previousExternalValue","setPreviousExternalValue","handleToggleInput","handleSaveAttempt","handleDateChange","value","handleCloseDropdown","wrapperClasses","classNames","buttonIconClasses","dateInputClasses","disableButton","inputStyle","jsxs","jsx","DatePicker","Button"],"mappings":";;;;;;;;AAUA,MAAMA,KAAuB,WAgHvBC,KAAoB,CAACC,MAAkC;AACzD,QAAM;AAAA,IACF,aAAAC;AAAA,IACA,OAAOC,IAAgB;AAAA,IACvB,SAAAC,IAAU;AAAA,IACV,cAAAC;AAAA,IACA,eAAAC,IAAgB;AAAA,IAChB,gBAAAC,IAAiBC;AAAA,IACjB,eAAAC;AAAA;AAAA,IACA,aAAAC,IAAcF;AAAA,IACd,YAAAG,IAAaH;AAAA,IACb,UAAAI,IAAWJ;AAAA,IACX,aAAAK,IAAcd;AAAA,IACd,gBAAAe;AAAA,IACA,YAAAC;AAAA,IACA,qBAAAC,IAAsB;AAAA,IACtB,iBAAAC,IAAkB,CAAA;AAAA,IAClB,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHnB,GAGEoB,IAAmBZ,MAAkB,QAErC,CAACa,GAAYC,CAAa,IAAIC,EAAiCrB,CAAa,GAE5E,CAACsB,GAAWC,CAAY,IAAIF,EAAS,EAAK,GAC1C,CAACG,GAAWC,CAAY,IAAIJ,EAAS,EAAK,GAE1C,CAACK,GAAcC,CAAe,IAAIN,EAAS,EAAK,GAEhDO,IAAaC,EAAuB,IAAI,GACxCC,IAAYD,EAA0B,IAAI,GAE1CE,IAAuBF,EAAOV,CAAU;AAE9C,EAAAa,EAAiB;AAAA,IACb,KAAKJ;AAAA,IACL,eAAe,MAAM;AACjB,MAAAH,EAAa,EAAI;AAAA,IACrB;AAAA,IACA,cAAc,MAAM;AAChB,MAAAA,EAAa,EAAK;AAAA,IACtB;AAAA,EAAA,CACH,GAGDQ,GAAO,MAAM;AACT,IAAIT,KAAaF,KACbY,EAAA;AAAA,EAER,CAAC;AAGD,QAAM,CAACC,GAAuBC,CAAwB,IAAIf,EAASrB,CAAa;AAChF,EAAImC,MAA0BnC,MAC1BoB,EAAcpB,CAAa,GAC3BoC,EAAyBpC,CAAa,GAEjCsB,MACDS,EAAqB,UAAU/B;AAIvC,QAAMqC,IAAoB,MAAM;AAC5B,IAAKf,IAWDgB,EAAA,KATAf,EAAa,EAAI,GACjBQ,EAAqB,UAAUZ,GAG/BQ,EAAgB,EAAI,GAEpBpB,EAAA;AAAA,EAKR,GAEM+B,IAAoB,MAAM;AAC5B,IAAIrC,KAEAsB,EAAa,EAAK,GAClBnB,EAAee,GAA+BY,EAAqB,OAAO,GAC1EvB,EAAW,EAAI,GAGfmB,EAAgB,EAAK,KAGjBd,MAAwB,qBACxBqB,EAAA;AAAA,EAIZ,GAEMA,IAAmB,MAAM;AAC3B,IAAAX,EAAa,EAAK,GAGdL,IAEAZ,EAAcyB,EAAqB,SAA4B,EAAI,IAEnEX,EAAcW,EAAqB,OAAO,GAI9CJ,EAAgB,EAAK,GAErBlB,EAAA,GACAD,EAAW,EAAK;AAAA,EACpB,GAEM+B,IAAmB,CAACC,GAAwBvC,MAAqB;AACnE,IAAIiB,IACAZ,EAAckC,GAAOvC,CAAO,IAE5BmB,EAAcoB,CAAK;AAAA,EAE3B,GAEMC,IAAsB,MAAMd,EAAgB,EAAK,GAEjDe,IAAiBC,EAAW,cAAc,CAAC1C,KAAW,0BAA0Be,CAAS,GAEzF4B,IAAoBD,EAAW,YAAYrB,IAAY,gBAAgB,iBAAiB,GAExFuB,IAAmBF,EAAW,yBAAyBhC,CAAc,GAKrEmC,IAAgB/B,KAAaO,KAAa,CAACrB,KAAWY,MAAwB;AAEpF,MAAIkC,IAA4B;AAAA,IAC5B,sBAAsB;AAAA,IACtB,yBAAyB;AAAA,EAAA;AAG7B,SAAI,CAAC9C,KAAWE,MAEZ4C,IAAa,EAAE,GAAGA,GAAY,cAAc,OAAA,sBAI3C,OAAA,EAAI,KAAKnB,GAAa,GAAGX,GAAgB,WAAWyB,GACjD,UAAA;AAAA,IAAA,gBAAAM,EAAC,OAAA,EAAI,WAAU,eACX,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAACC;AAAA,QAAA;AAAA,UACS,GAAGpC;AAAA,UAAiB,MAAMY;AAAA,UAChC,WAAWmB;AAAA,UACX,YAAY;AAAA,YACR,GAAGjC;AAAA,YACH,aAAAb;AAAA,YACA,UAAU,CAACuB;AAAA,YACX,OAAOyB;AAAA,UAAA;AAAA,UAEX,OAAO5B;AAAA,UACP,UAAUoB;AAAA,UACV,SAASE;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,CAACxC,KAAW,CAACE,KACV,gBAAA8C,EAAC,QAAA,EAAK,WAAU,+EAA8E;AAAA,MAElG,gBAAAA,EAAC,OAAA,EAAI,WAAU,mBACX,UAAA,gBAAAA;AAAA,QAACE;AAAA,QAAA;AAAA,UACG,KAAKrB;AAAA,UACL,SAASpB;AAAA,UACT,UAAQ;AAAA,UACR,SAAS2B;AAAA,UACT,UAAUS;AAAA,UAEV,UAAA,gBAAAG,EAAC,QAAA,EAAK,WAAWL,EAAA,CAAmB;AAAA,QAAA;AAAA,MAAA,EACxC,CACJ;AAAA,IAAA,GACJ;AAAA,IACC,CAAC3C,KAAWC,KACT,gBAAA+C,EAAC,QAAA,EAAK,WAAU,0BACZ,UAAA,gBAAAA,EAAC,QAAA,EAAM,UAAA/C,EAAA,CAAa,EAAA,CACxB;AAAA,EAAA,GAER;AAER;"}
|
|
1
|
+
{"version":3,"file":"SaveableDateInput.js","sources":["../../../src/components/saveableInput/SaveableDateInput.tsx"],"sourcesContent":["import { useRef, useState, type HTMLAttributes, type CSSProperties } from 'react';\nimport classNames from 'classnames';\nimport { noop } from 'es-toolkit/function';\nimport type { Moment } from 'moment';\n\nimport Button from '../../Button';\nimport DatePicker, { type DatePickerProps } from '../datepicker/DatePicker';\nimport useIsFocusWithin from '../../hooks/useIsFocusWithin';\nimport useEsc from '../../hooks/useEsc';\n\nconst DEFAULT_BUTTON_STYLE = 'primary';\n\nexport type SaveableDateInputProps = {\n /**\n * The input placeholder.\n */\n placeholder?: string;\n\n /**\n * The actual input value.\n */\n value?: Date | Moment | string;\n\n /**\n * Used to control the save button from the outside to disable it in case\n * the entered value is not valid.\n *\n * @default true\n */\n isValid?: boolean;\n\n /**\n * This is the error message that is shown below the input. It uses the built-in error handling,\n * and will be shown when the \"isValid\" prop is set to false.\n */\n errorMessage?: string | React.ReactNode;\n\n /**\n * Defines wether the error icon is shown or not. If enabled, it will be shown when the \"isValid\" prop\n * is set to false.\n *\n * @default false\n */\n hideErrorIcon?: boolean;\n\n /**\n * Callback function triggered when the value changes and is saved.\n *\n * @param value\n * @param previousValue\n * @returns\n */\n onValueChanged?: (value: Moment | string, previousValue: Moment | string | Date) => void;\n\n /**\n * Callback function that gets triggered on every input change. Use this to control the component\n * or when implementing key validation.\n *\n * @param keyValue the key value that has been entered\n * @returns\n */\n onInputChange?: (value: Moment | string, isValid: boolean) => void;\n\n /**\n * Callback function that gets triggered when the input is in edit mode. Use this\n * to control the component and to handle the previous value on the outside.\n *\n * @returns\n */\n onEnterEdit?: () => void;\n\n /**\n * Callback function that gets triggered when edit mode is exited (either saved or cancelled).\n *\n * @param wasSaved - true if value was saved, false if cancelled/reset\n * @returns\n */\n onExitEdit?: (wasSaved: boolean) => void;\n\n /**\n * Callback function that gets triggered when the user aborts the edit mode. Use this\n * to control the component and handle the resetting of previous value on the outside.\n *\n * @returns\n */\n onCancel?: () => void;\n\n /**\n * Behavior when trying to exit edit mode with invalid input:\n * - 'stay-open': Keep edit mode open until valid input is provided\n * - 'reset-and-close': Close edit mode and reset to initial value\n *\n * @default 'stay-open'\n */\n invalidExitBehavior?: 'stay-open' | 'reset-and-close';\n\n /**\n * Defines the button style: `default` or `primary`.\n *\n * @default 'primary'\n */\n buttonStyle?: 'primary' | 'default';\n\n /**\n * Additional HTML attributes to be set on the input element.\n */\n inputProps?: HTMLAttributes<HTMLInputElement>;\n\n /**\n * Additional props passed to the underlying DatePicker component.\n *\n * @default {}\n */\n datePickerProps?: DatePickerProps;\n\n /**\n * Disables the component so the user cannot enter the edit mode.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the input itself.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\n// Validate date outside the component (via form library) if controlled usage\n// Use as controlled component: value, is Valid, and change callback\n// - if is valid, on save, call callback \"onValueChanged\"\n// - if not valid, keep edit mode open, outside is showing error message\n// - close edit mode only if date is valid - or close edit mode and reset to initial value -> customizable via prop\n// Keep picker open until user has clicked save, otherwise he might forget to click save if the dropdown closes automatically\n\nconst SaveableDateInput = (props: SaveableDateInputProps) => {\n const {\n placeholder,\n value: externalValue = '',\n isValid = true,\n errorMessage,\n hideErrorIcon = false,\n onValueChanged = noop,\n onInputChange, // for controlled usage\n onEnterEdit = noop,\n onExitEdit = noop,\n onCancel = noop,\n buttonStyle = DEFAULT_BUTTON_STYLE,\n inputClassName,\n inputProps,\n invalidExitBehavior = 'stay-open',\n datePickerProps = {},\n disabled = false,\n className,\n ...remainingProps\n } = props;\n\n // if callback is provided, assume it is controlled case\n const isControlledCase = onInputChange !== undefined;\n\n const [inputValue, setInputValue] = useState<Date | Moment | string>(externalValue);\n\n const [editInput, setEditInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const [isPickerOpen, setIsPickerOpen] = useState(false);\n\n const wrapperRef = useRef<HTMLDivElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const initialInputValueRef = useRef(inputValue);\n\n useIsFocusWithin({\n ref: wrapperRef,\n onFocusWithin: () => {\n setIsFocused(true);\n },\n onBlurWithin: () => {\n setIsFocused(false);\n },\n });\n\n // Handle escape key to cancel edit mode\n useEsc(() => {\n if (isFocused && editInput) {\n handleCancelEdit();\n }\n });\n\n // Update internal state in a controlled environment\n const [previousExternalValue, setPreviousExternalValue] = useState(externalValue);\n if (previousExternalValue !== externalValue) {\n setInputValue(externalValue);\n setPreviousExternalValue(externalValue);\n // Update initial value ref when external value changes while not in edit mode\n if (!editInput) {\n initialInputValueRef.current = externalValue;\n }\n }\n\n const handleToggleInput = () => {\n if (!editInput) {\n // Enter edit mode\n setEditInput(true);\n initialInputValueRef.current = inputValue;\n\n // open the dropdown\n setIsPickerOpen(true);\n\n onEnterEdit();\n } else {\n // Try to exit edit mode\n handleSaveAttempt();\n }\n };\n\n const handleSaveAttempt = () => {\n if (isValid) {\n // Save the value (only if valid)\n setEditInput(false);\n onValueChanged(inputValue as Moment | string, initialInputValueRef.current);\n onExitEdit(true);\n\n // close the dropdown\n setIsPickerOpen(false);\n } else {\n // Handle invalid input based on behavior setting\n if (invalidExitBehavior === 'reset-and-close') {\n handleCancelEdit();\n }\n // If 'stay-open', do nothing - keep edit mode open\n }\n };\n\n const handleCancelEdit = () => {\n setEditInput(false);\n\n // Reset to initial value\n if (isControlledCase) {\n // In controlled mode, trigger change to reset to initial value\n onInputChange(initialInputValueRef.current as Moment | string, true);\n } else {\n setInputValue(initialInputValueRef.current);\n }\n\n // Close the dropdown\n setIsPickerOpen(false);\n\n onCancel();\n onExitEdit(false);\n };\n\n const handleDateChange = (value: Moment | string, isValid: boolean) => {\n if (isControlledCase) {\n onInputChange(value, isValid);\n } else {\n setInputValue(value);\n }\n };\n\n const handleCloseDropdown = () => setIsPickerOpen(false);\n\n const wrapperClasses = classNames('form-group', !isValid && 'has-feedback has-error', className);\n\n const buttonIconClasses = classNames('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');\n\n const dateInputClasses = classNames('margin-0 width-100pct', inputClassName);\n\n // Button should be disabled if:\n // - Component is disabled, OR\n // - In edit mode and invalid input (and behavior is stay-open)\n const disableButton = disabled || (editInput && !isValid && invalidExitBehavior === 'stay-open');\n\n let inputStyle: CSSProperties = {\n borderTopRightRadius: 0,\n borderBottomRightRadius: 0,\n };\n\n if (!isValid && hideErrorIcon) {\n // If the error icon shall not be shown, remove the input padding to avoid cutting of the date value\n inputStyle = { ...inputStyle, paddingRight: '10px' };\n }\n\n return (\n <div ref={wrapperRef} {...remainingProps} className={wrapperClasses}>\n <div className='input-group'>\n <DatePicker\n {...{ ...datePickerProps, open: isPickerOpen }}\n className={dateInputClasses}\n inputProps={{\n ...inputProps,\n placeholder,\n disabled: !editInput,\n style: inputStyle,\n }}\n value={inputValue}\n onChange={handleDateChange}\n onClose={handleCloseDropdown}\n />\n {!isValid && !hideErrorIcon && (\n <span className='right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' />\n )}\n <div className='input-group-btn'>\n <Button\n ref={buttonRef}\n bsStyle={buttonStyle}\n iconOnly\n onClick={handleToggleInput}\n disabled={disableButton}\n >\n <span className={buttonIconClasses} />\n </Button>\n </div>\n </div>\n {!isValid && errorMessage && (\n <span className='help-block z-index-max'>\n <span>{errorMessage}</span>\n </span>\n )}\n </div>\n );\n};\n\nexport default SaveableDateInput;\n"],"names":["DEFAULT_BUTTON_STYLE","SaveableDateInput","props","placeholder","externalValue","isValid","errorMessage","hideErrorIcon","onValueChanged","noop","onInputChange","onEnterEdit","onExitEdit","onCancel","buttonStyle","inputClassName","inputProps","invalidExitBehavior","datePickerProps","disabled","className","remainingProps","isControlledCase","inputValue","setInputValue","useState","editInput","setEditInput","isFocused","setIsFocused","isPickerOpen","setIsPickerOpen","wrapperRef","useRef","buttonRef","initialInputValueRef","useIsFocusWithin","useEsc","handleCancelEdit","previousExternalValue","setPreviousExternalValue","handleToggleInput","handleSaveAttempt","handleDateChange","value","handleCloseDropdown","wrapperClasses","classNames","buttonIconClasses","dateInputClasses","disableButton","inputStyle","jsxs","jsx","DatePicker","Button"],"mappings":";;;;;;;;AAUA,MAAMA,KAAuB,WAkIvBC,KAAoB,CAACC,MAAkC;AACzD,QAAM;AAAA,IACF,aAAAC;AAAA,IACA,OAAOC,IAAgB;AAAA,IACvB,SAAAC,IAAU;AAAA,IACV,cAAAC;AAAA,IACA,eAAAC,IAAgB;AAAA,IAChB,gBAAAC,IAAiBC;AAAA,IACjB,eAAAC;AAAA;AAAA,IACA,aAAAC,IAAcF;AAAA,IACd,YAAAG,IAAaH;AAAA,IACb,UAAAI,IAAWJ;AAAA,IACX,aAAAK,IAAcd;AAAA,IACd,gBAAAe;AAAA,IACA,YAAAC;AAAA,IACA,qBAAAC,IAAsB;AAAA,IACtB,iBAAAC,IAAkB,CAAA;AAAA,IAClB,UAAAC,IAAW;AAAA,IACX,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,IACHnB,GAGEoB,IAAmBZ,MAAkB,QAErC,CAACa,GAAYC,CAAa,IAAIC,EAAiCrB,CAAa,GAE5E,CAACsB,GAAWC,CAAY,IAAIF,EAAS,EAAK,GAC1C,CAACG,GAAWC,CAAY,IAAIJ,EAAS,EAAK,GAE1C,CAACK,GAAcC,CAAe,IAAIN,EAAS,EAAK,GAEhDO,IAAaC,EAAuB,IAAI,GACxCC,IAAYD,EAA0B,IAAI,GAE1CE,IAAuBF,EAAOV,CAAU;AAE9C,EAAAa,EAAiB;AAAA,IACb,KAAKJ;AAAA,IACL,eAAe,MAAM;AACjB,MAAAH,EAAa,EAAI;AAAA,IACrB;AAAA,IACA,cAAc,MAAM;AAChB,MAAAA,EAAa,EAAK;AAAA,IACtB;AAAA,EAAA,CACH,GAGDQ,GAAO,MAAM;AACT,IAAIT,KAAaF,KACbY,EAAA;AAAA,EAER,CAAC;AAGD,QAAM,CAACC,GAAuBC,CAAwB,IAAIf,EAASrB,CAAa;AAChF,EAAImC,MAA0BnC,MAC1BoB,EAAcpB,CAAa,GAC3BoC,EAAyBpC,CAAa,GAEjCsB,MACDS,EAAqB,UAAU/B;AAIvC,QAAMqC,IAAoB,MAAM;AAC5B,IAAKf,IAWDgB,EAAA,KATAf,EAAa,EAAI,GACjBQ,EAAqB,UAAUZ,GAG/BQ,EAAgB,EAAI,GAEpBpB,EAAA;AAAA,EAKR,GAEM+B,IAAoB,MAAM;AAC5B,IAAIrC,KAEAsB,EAAa,EAAK,GAClBnB,EAAee,GAA+BY,EAAqB,OAAO,GAC1EvB,EAAW,EAAI,GAGfmB,EAAgB,EAAK,KAGjBd,MAAwB,qBACxBqB,EAAA;AAAA,EAIZ,GAEMA,IAAmB,MAAM;AAC3B,IAAAX,EAAa,EAAK,GAGdL,IAEAZ,EAAcyB,EAAqB,SAA4B,EAAI,IAEnEX,EAAcW,EAAqB,OAAO,GAI9CJ,EAAgB,EAAK,GAErBlB,EAAA,GACAD,EAAW,EAAK;AAAA,EACpB,GAEM+B,IAAmB,CAACC,GAAwBvC,MAAqB;AACnE,IAAIiB,IACAZ,EAAckC,GAAOvC,CAAO,IAE5BmB,EAAcoB,CAAK;AAAA,EAE3B,GAEMC,IAAsB,MAAMd,EAAgB,EAAK,GAEjDe,IAAiBC,EAAW,cAAc,CAAC1C,KAAW,0BAA0Be,CAAS,GAEzF4B,IAAoBD,EAAW,YAAYrB,IAAY,gBAAgB,iBAAiB,GAExFuB,IAAmBF,EAAW,yBAAyBhC,CAAc,GAKrEmC,IAAgB/B,KAAaO,KAAa,CAACrB,KAAWY,MAAwB;AAEpF,MAAIkC,IAA4B;AAAA,IAC5B,sBAAsB;AAAA,IACtB,yBAAyB;AAAA,EAAA;AAG7B,SAAI,CAAC9C,KAAWE,MAEZ4C,IAAa,EAAE,GAAGA,GAAY,cAAc,OAAA,sBAI3C,OAAA,EAAI,KAAKnB,GAAa,GAAGX,GAAgB,WAAWyB,GACjD,UAAA;AAAA,IAAA,gBAAAM,EAAC,OAAA,EAAI,WAAU,eACX,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAACC;AAAA,QAAA;AAAA,UACS,GAAGpC;AAAA,UAAiB,MAAMY;AAAA,UAChC,WAAWmB;AAAA,UACX,YAAY;AAAA,YACR,GAAGjC;AAAA,YACH,aAAAb;AAAA,YACA,UAAU,CAACuB;AAAA,YACX,OAAOyB;AAAA,UAAA;AAAA,UAEX,OAAO5B;AAAA,UACP,UAAUoB;AAAA,UACV,SAASE;AAAA,QAAA;AAAA,MAAA;AAAA,MAEZ,CAACxC,KAAW,CAACE,KACV,gBAAA8C,EAAC,QAAA,EAAK,WAAU,+EAA8E;AAAA,MAElG,gBAAAA,EAAC,OAAA,EAAI,WAAU,mBACX,UAAA,gBAAAA;AAAA,QAACE;AAAA,QAAA;AAAA,UACG,KAAKrB;AAAA,UACL,SAASpB;AAAA,UACT,UAAQ;AAAA,UACR,SAAS2B;AAAA,UACT,UAAUS;AAAA,UAEV,UAAA,gBAAAG,EAAC,QAAA,EAAK,WAAWL,EAAA,CAAmB;AAAA,QAAA;AAAA,MAAA,EACxC,CACJ;AAAA,IAAA,GACJ;AAAA,IACC,CAAC3C,KAAWC,KACT,gBAAA+C,EAAC,QAAA,EAAK,WAAU,0BACZ,UAAA,gBAAAA,EAAC,QAAA,EAAM,UAAA/C,EAAA,CAAa,EAAA,CACxB;AAAA,EAAA,GAER;AAER;"}
|
|
@@ -26,11 +26,15 @@ export type SaveableInputProps = {
|
|
|
26
26
|
*/
|
|
27
27
|
isValid?: boolean;
|
|
28
28
|
/**
|
|
29
|
-
* This is the error message that is shown below the input. It uses the built-in error handling,
|
|
29
|
+
* This is the error message that is shown below the input. It uses the built-in error handling,
|
|
30
|
+
* and will be shown when the "isValid" prop is set to false.
|
|
30
31
|
*/
|
|
31
32
|
errorMessage?: string | React.ReactNode;
|
|
32
33
|
/**
|
|
33
|
-
* Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop
|
|
34
|
+
* Defines wether the error icon is shown or not. If enabled, it will be shown when the "isValid" prop
|
|
35
|
+
* is set to false.
|
|
36
|
+
*
|
|
37
|
+
* @default false
|
|
34
38
|
*/
|
|
35
39
|
hideErrorIcon?: boolean;
|
|
36
40
|
/**
|
|
@@ -62,6 +66,8 @@ export type SaveableInputProps = {
|
|
|
62
66
|
onEnterEdit?: () => void;
|
|
63
67
|
/**
|
|
64
68
|
* Defines the button style: `default` or `primary`.
|
|
69
|
+
*
|
|
70
|
+
* @default 'primary'
|
|
65
71
|
*/
|
|
66
72
|
buttonStyle?: 'primary' | 'default';
|
|
67
73
|
/**
|
|
@@ -79,6 +85,8 @@ export type SaveableInputProps = {
|
|
|
79
85
|
icon?: string;
|
|
80
86
|
/**
|
|
81
87
|
* Disables the component so the user cannot enter the edit mode.
|
|
88
|
+
*
|
|
89
|
+
* @default false
|
|
82
90
|
*/
|
|
83
91
|
disabled?: boolean;
|
|
84
92
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SaveableInput.js","sources":["../../../src/components/saveableInput/SaveableInput.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, type ChangeEvent, type HTMLAttributes } from 'react';\nimport classNames from 'classnames';\nimport { isEmpty } from 'es-toolkit/compat';\nimport { noop } from 'es-toolkit/function';\n\n// @ts-ignore\nimport Button from '../../Button';\nimport useKey from '../../hooks/useKey';\nimport useEsc from '../../hooks/useEsc';\n\nconst DEFAULT_BUTTON_STYLE = 'primary';\n\nconst useFocus = (isEditable: boolean) => {\n const inputRef = useRef<HTMLInputElement>(null);\n useEffect(() => {\n if (inputRef.current && isEditable) {\n inputRef.current.focus();\n }\n }, [inputRef.current, isEditable]);\n\n return inputRef;\n};\n\nexport type SaveableInputProps = {\n /**\n * The input placeholder.\n */\n placeholder?: string;\n\n /**\n * The previous or old value shown above the input value.\n * This value will *not* be changed for new input values.\n */\n fixedPreviousValue?: string;\n\n /**\n * The previous or old value shown above the input value.\n * This value *changes* when a new input value is accepted.\n */\n previousValue?: string;\n\n /**\n * The actual input value.\n */\n value?: string;\n\n /**\n * Used to control the save button from the outside to disable it in case\n * the entered value is not valid.\n *\n * @default true\n */\n isValid?: boolean;\n\n /**\n * This is the error message that is shown below the input. It uses the built-in error handling, and will be shown when the \"isValid\" prop is set to false.\n */\n errorMessage?: string | React.ReactNode;\n\n /**\n * Defines wether the error icon is shown or not. If enabled, it will be shown when the \"isValid\" prop is set to false.\n */\n hideErrorIcon?: boolean;\n\n /**\n * Callback function triggered when the value changes.\n * @param value\n * @param previousValue\n * @returns\n */\n onValueChanged?: (value: string, previousValue: string) => void;\n\n /**\n * Callback function that gets triggered on every input change. Use this to control the component\n * or when implementing key validation.\n * @param keyValue the key value that has been entered\n * @param inputValue the current complete value of the input\n * @returns\n */\n onInputChange?: (keyValue: string, inputValue: string) => void;\n\n /**\n * Callback function that gets triggered when the user aborts the edit mode. Use this\n * to control the component and handle the resetting of previous value on the outside.\n * @returns\n */\n onEsc?: () => void;\n\n /**\n * Callback function that gets triggered when the input is in edit mode. Use this\n * to control the component dna to handle the previous value on the outside.\n * @returns\n */\n onEnterEdit?: () => void;\n\n /**\n * Defines the button style: `default` or `primary`.\n */\n buttonStyle?: 'primary' | 'default';\n\n /**\n * Additional HTML attributes to be set on the input element.\n */\n inputProps?: HTMLAttributes<HTMLInputElement>;\n\n /**\n * Adds a given unit to the input.\n */\n unit?: string | React.ReactNode;\n\n /**\n * Icon class name that shall be used. If defined, the input element is wrapped in an input-group\n * and the icon will be set in an input-addon. Example: `rioglyph-search`.\n */\n icon?: string;\n\n /**\n * Disables the component so the user cannot enter the edit mode.\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the input itself.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\n// Features:\n// [ ] what shall happen when user leaves component while in edit mode (click outside or tab) - close on blur?\n// [x] avoid save without change\n// [x] use fixed previous value\n// [x] enter = save\n// [x] esc key to abort and leave edit mode\n// [x] tab focus + enter = go into edit mode\n// [x] validate after each key, i.e for number inputs - use onInputChange callback\n// [x] support form feedback error - wrap it with form-group and feedback classes\n// [x] allow for unit and icon\n// [x] disabled input\n\nconst SaveableInput = (props: SaveableInputProps) => {\n const {\n placeholder,\n fixedPreviousValue = '',\n previousValue = '',\n value: externalValue = '',\n isValid = true,\n errorMessage,\n hideErrorIcon = false,\n onValueChanged = noop,\n onInputChange,\n onEsc = noop,\n onEnterEdit = noop,\n buttonStyle = DEFAULT_BUTTON_STYLE,\n inputClassName,\n inputProps,\n icon,\n unit,\n disabled = false,\n className,\n ...remainingProps\n } = props;\n\n const externalOldValue = previousValue || fixedPreviousValue;\n\n const [inputValue, setInputValue] = useState(externalValue);\n const [oldInputValue, setOldInputValue] = useState(externalOldValue);\n\n const [editInput, setEditInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const initialInputValueRef = useRef(inputValue);\n const initialOldInputValueRef = useRef(oldInputValue);\n\n // Update internal state in a controlled environment\n const [previousExternalValue, setPreviousExternalValue] = useState(externalValue);\n if (previousExternalValue !== externalValue) {\n setInputValue(externalValue);\n setPreviousExternalValue(externalValue);\n }\n\n // Update internal state in a controlled environment\n const [previousExternalOldValue, setPreviousExternalOldValue] = useState(externalOldValue);\n if (previousExternalOldValue !== externalOldValue) {\n setOldInputValue(externalOldValue);\n setPreviousExternalOldValue(externalOldValue);\n }\n\n // Set focus on input when being in edit mode\n const inputRef = useFocus(editInput);\n\n // Allow to exit \"edit\" mode with \"Enter\" to accept changes\n useKey((event: KeyboardEvent) => {\n if (isFocused && editInput && isValid && event.key === 'Enter') {\n handleToggleInput();\n }\n });\n\n // Allow to exit \"edit\" mode with \"Esc\" to ignore changes\n useEsc(() => {\n if (isFocused) {\n // Restore local state to initial vales as it was when entering edit mode\n setInputValue(initialInputValueRef.current);\n setOldInputValue(initialOldInputValueRef.current);\n setEditInput(false);\n onEsc();\n }\n });\n\n const handleToggleInput = () => {\n if (editInput === false) {\n setEditInput(true);\n\n // Temporarily store values of input and oldInput to be used when\n // discarding changes on \"esc\" or to avoid saving without changes\n if (!fixedPreviousValue) {\n initialOldInputValueRef.current = oldInputValue;\n }\n initialInputValueRef.current = inputValue;\n\n onEnterEdit();\n } else {\n setEditInput(false);\n\n // In case the new input value has not changed to the initial value\n // reset the internal old value to the initial\n if (initialInputValueRef.current !== inputValue) {\n setOldInputValue(fixedPreviousValue || initialInputValueRef.current);\n onValueChanged(inputValue, oldInputValue);\n }\n }\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n // Only update internal value if the external \"onInputChange\" callback function is not defined\n // as it will be used in a controlled way\n if (onInputChange) {\n // Use type assertion to access nativeEvent.data\n const nativeEventData = (event.nativeEvent as InputEvent)?.data;\n\n // Whe \"backspace\" is used to remove a value, the nativeEventData is undefined. In this case\n // we need to use the target value for the callback otherwise the user will not be able to\n // remove a character from the input\n const currentInputValue = event.target.value;\n\n onInputChange(nativeEventData ?? currentInputValue, event.currentTarget.value);\n return;\n }\n\n setInputValue(event.target.value);\n };\n\n const handleFocus = () => setIsFocused(true);\n const handleBlur = () => setIsFocused(false);\n\n const showOldValue = !isEmpty(oldInputValue) && oldInputValue !== inputValue && !editInput;\n\n const wrapperClasses = classNames('form-group', !isValid && 'has-feedback has-error', className);\n\n const inputClasses = classNames(\n 'form-control',\n showOldValue && 'padding-bottom-0 padding-top-10 text-size-12',\n unit && 'padding-right-50', // This value is not perfect as with longer units it might conflict with the value\n !unit && !isValid && hideErrorIcon && 'padding-right-10', // remove the padding for the error icon if not needed\n inputClassName\n );\n\n const oldValueClasses = classNames(\n 'position-absolute',\n 'top-2',\n 'left-10',\n 'margin-left-3',\n 'text-size-10',\n 'text-decoration-line-through',\n icon && 'padding-left-20'\n );\n\n const buttonIconClasses = classNames('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');\n\n const disableButton = (editInput && !isValid) || disabled;\n\n return (\n <div {...remainingProps} className={wrapperClasses}>\n <div className='input-group'>\n {icon && (\n <span className='input-group-addon'>\n <span className={`rioglyph ${icon}`} aria-hidden='true' aria-label='input icon' />\n </span>\n )}\n <input\n type='text'\n ref={inputRef}\n placeholder={placeholder}\n className={inputClasses}\n value={inputValue}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={!editInput}\n {...inputProps}\n />\n {unit && (\n <div className='position-absolute right-0 margin-right-50' aria-label='unit'>\n {unit}\n </div>\n )}\n {showOldValue && (\n <div className={oldValueClasses} aria-label='previous value'>\n {oldInputValue}\n </div>\n )}\n <div className='input-group-btn'>\n <Button bsStyle={buttonStyle} iconOnly onClick={handleToggleInput} disabled={disableButton}>\n <span className={buttonIconClasses} />\n </Button>\n </div>\n </div>\n {!isValid && !hideErrorIcon && !unit && (\n <span className='right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' />\n )}\n {!isValid && errorMessage && (\n <span className='help-block z-index-max'>\n <span>{errorMessage}</span>\n </span>\n )}\n </div>\n );\n};\n\nexport default SaveableInput;\n"],"names":["DEFAULT_BUTTON_STYLE","useFocus","isEditable","inputRef","useRef","useEffect","SaveableInput","props","placeholder","fixedPreviousValue","previousValue","externalValue","isValid","errorMessage","hideErrorIcon","onValueChanged","noop","onInputChange","onEsc","onEnterEdit","buttonStyle","inputClassName","inputProps","icon","unit","disabled","className","remainingProps","externalOldValue","inputValue","setInputValue","useState","oldInputValue","setOldInputValue","editInput","setEditInput","isFocused","setIsFocused","initialInputValueRef","initialOldInputValueRef","previousExternalValue","setPreviousExternalValue","previousExternalOldValue","setPreviousExternalOldValue","useKey","event","handleToggleInput","useEsc","handleInputChange","nativeEventData","currentInputValue","handleFocus","handleBlur","showOldValue","isEmpty","wrapperClasses","classNames","inputClasses","oldValueClasses","buttonIconClasses","disableButton","jsxs","jsx","Button"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SaveableInput.js","sources":["../../../src/components/saveableInput/SaveableInput.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, type ChangeEvent, type HTMLAttributes } from 'react';\nimport classNames from 'classnames';\nimport { isEmpty } from 'es-toolkit/compat';\nimport { noop } from 'es-toolkit/function';\n\nimport Button from '../../Button';\nimport useKey from '../../hooks/useKey';\nimport useEsc from '../../hooks/useEsc';\n\nconst DEFAULT_BUTTON_STYLE = 'primary';\n\nconst useFocus = (isEditable: boolean) => {\n const inputRef = useRef<HTMLInputElement>(null);\n useEffect(() => {\n if (inputRef.current && isEditable) {\n inputRef.current.focus();\n }\n }, [inputRef.current, isEditable]);\n\n return inputRef;\n};\n\nexport type SaveableInputProps = {\n /**\n * The input placeholder.\n */\n placeholder?: string;\n\n /**\n * The previous or old value shown above the input value.\n * This value will *not* be changed for new input values.\n */\n fixedPreviousValue?: string;\n\n /**\n * The previous or old value shown above the input value.\n * This value *changes* when a new input value is accepted.\n */\n previousValue?: string;\n\n /**\n * The actual input value.\n */\n value?: string;\n\n /**\n * Used to control the save button from the outside to disable it in case\n * the entered value is not valid.\n *\n * @default true\n */\n isValid?: boolean;\n\n /**\n * This is the error message that is shown below the input. It uses the built-in error handling,\n * and will be shown when the \"isValid\" prop is set to false.\n */\n errorMessage?: string | React.ReactNode;\n\n /**\n * Defines wether the error icon is shown or not. If enabled, it will be shown when the \"isValid\" prop\n * is set to false.\n *\n * @default false\n */\n hideErrorIcon?: boolean;\n\n /**\n * Callback function triggered when the value changes.\n * @param value\n * @param previousValue\n * @returns\n */\n onValueChanged?: (value: string, previousValue: string) => void;\n\n /**\n * Callback function that gets triggered on every input change. Use this to control the component\n * or when implementing key validation.\n * @param keyValue the key value that has been entered\n * @param inputValue the current complete value of the input\n * @returns\n */\n onInputChange?: (keyValue: string, inputValue: string) => void;\n\n /**\n * Callback function that gets triggered when the user aborts the edit mode. Use this\n * to control the component and handle the resetting of previous value on the outside.\n * @returns\n */\n onEsc?: () => void;\n\n /**\n * Callback function that gets triggered when the input is in edit mode. Use this\n * to control the component dna to handle the previous value on the outside.\n * @returns\n */\n onEnterEdit?: () => void;\n\n /**\n * Defines the button style: `default` or `primary`.\n *\n * @default 'primary'\n */\n buttonStyle?: 'primary' | 'default';\n\n /**\n * Additional HTML attributes to be set on the input element.\n */\n inputProps?: HTMLAttributes<HTMLInputElement>;\n\n /**\n * Adds a given unit to the input.\n */\n unit?: string | React.ReactNode;\n\n /**\n * Icon class name that shall be used. If defined, the input element is wrapped in an input-group\n * and the icon will be set in an input-addon. Example: `rioglyph-search`.\n */\n icon?: string;\n\n /**\n * Disables the component so the user cannot enter the edit mode.\n *\n * @default false\n */\n disabled?: boolean;\n\n /**\n * Additional classes to be set on the input itself.\n */\n inputClassName?: string;\n\n /**\n * Additional classes to be set on the wrapper element.\n */\n className?: string;\n};\n\n// Features:\n// [ ] what shall happen when user leaves component while in edit mode (click outside or tab) - close on blur?\n// [x] avoid save without change\n// [x] use fixed previous value\n// [x] enter = save\n// [x] esc key to abort and leave edit mode\n// [x] tab focus + enter = go into edit mode\n// [x] validate after each key, i.e for number inputs - use onInputChange callback\n// [x] support form feedback error - wrap it with form-group and feedback classes\n// [x] allow for unit and icon\n// [x] disabled input\n\nconst SaveableInput = (props: SaveableInputProps) => {\n const {\n placeholder,\n fixedPreviousValue = '',\n previousValue = '',\n value: externalValue = '',\n isValid = true,\n errorMessage,\n hideErrorIcon = false,\n onValueChanged = noop,\n onInputChange,\n onEsc = noop,\n onEnterEdit = noop,\n buttonStyle = DEFAULT_BUTTON_STYLE,\n inputClassName,\n inputProps,\n icon,\n unit,\n disabled = false,\n className,\n ...remainingProps\n } = props;\n\n const externalOldValue = previousValue || fixedPreviousValue;\n\n const [inputValue, setInputValue] = useState(externalValue);\n const [oldInputValue, setOldInputValue] = useState(externalOldValue);\n\n const [editInput, setEditInput] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const initialInputValueRef = useRef(inputValue);\n const initialOldInputValueRef = useRef(oldInputValue);\n\n // Update internal state in a controlled environment\n const [previousExternalValue, setPreviousExternalValue] = useState(externalValue);\n if (previousExternalValue !== externalValue) {\n setInputValue(externalValue);\n setPreviousExternalValue(externalValue);\n }\n\n // Update internal state in a controlled environment\n const [previousExternalOldValue, setPreviousExternalOldValue] = useState(externalOldValue);\n if (previousExternalOldValue !== externalOldValue) {\n setOldInputValue(externalOldValue);\n setPreviousExternalOldValue(externalOldValue);\n }\n\n // Set focus on input when being in edit mode\n const inputRef = useFocus(editInput);\n\n // Allow to exit \"edit\" mode with \"Enter\" to accept changes\n useKey((event: KeyboardEvent) => {\n if (isFocused && editInput && isValid && event.key === 'Enter') {\n handleToggleInput();\n }\n });\n\n // Allow to exit \"edit\" mode with \"Esc\" to ignore changes\n useEsc(() => {\n if (isFocused) {\n // Restore local state to initial vales as it was when entering edit mode\n setInputValue(initialInputValueRef.current);\n setOldInputValue(initialOldInputValueRef.current);\n setEditInput(false);\n onEsc();\n }\n });\n\n const handleToggleInput = () => {\n if (editInput === false) {\n setEditInput(true);\n\n // Temporarily store values of input and oldInput to be used when\n // discarding changes on \"esc\" or to avoid saving without changes\n if (!fixedPreviousValue) {\n initialOldInputValueRef.current = oldInputValue;\n }\n initialInputValueRef.current = inputValue;\n\n onEnterEdit();\n } else {\n setEditInput(false);\n\n // In case the new input value has not changed to the initial value\n // reset the internal old value to the initial\n if (initialInputValueRef.current !== inputValue) {\n setOldInputValue(fixedPreviousValue || initialInputValueRef.current);\n onValueChanged(inputValue, oldInputValue);\n }\n }\n };\n\n const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {\n // Only update internal value if the external \"onInputChange\" callback function is not defined\n // as it will be used in a controlled way\n if (onInputChange) {\n // Use type assertion to access nativeEvent.data\n const nativeEventData = (event.nativeEvent as InputEvent)?.data;\n\n // Whe \"backspace\" is used to remove a value, the nativeEventData is undefined. In this case\n // we need to use the target value for the callback otherwise the user will not be able to\n // remove a character from the input\n const currentInputValue = event.target.value;\n\n onInputChange(nativeEventData ?? currentInputValue, event.currentTarget.value);\n return;\n }\n\n setInputValue(event.target.value);\n };\n\n const handleFocus = () => setIsFocused(true);\n const handleBlur = () => setIsFocused(false);\n\n const showOldValue = !isEmpty(oldInputValue) && oldInputValue !== inputValue && !editInput;\n\n const wrapperClasses = classNames('form-group', !isValid && 'has-feedback has-error', className);\n\n const inputClasses = classNames(\n 'form-control',\n showOldValue && 'padding-bottom-0 padding-top-10 text-size-12',\n unit && 'padding-right-50', // This value is not perfect as with longer units it might conflict with the value\n !unit && !isValid && hideErrorIcon && 'padding-right-10', // remove the padding for the error icon if not needed\n inputClassName\n );\n\n const oldValueClasses = classNames(\n 'position-absolute',\n 'top-2',\n 'left-10',\n 'margin-left-3',\n 'text-size-10',\n 'text-decoration-line-through',\n icon && 'padding-left-20'\n );\n\n const buttonIconClasses = classNames('rioglyph', editInput ? 'rioglyph-ok' : 'rioglyph-pencil');\n\n const disableButton = (editInput && !isValid) || disabled;\n\n return (\n <div {...remainingProps} className={wrapperClasses}>\n <div className='input-group'>\n {icon && (\n <span className='input-group-addon'>\n <span className={`rioglyph ${icon}`} aria-hidden='true' aria-label='input icon' />\n </span>\n )}\n <input\n type='text'\n ref={inputRef}\n placeholder={placeholder}\n className={inputClasses}\n value={inputValue}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n disabled={!editInput}\n {...inputProps}\n />\n {unit && (\n <div className='position-absolute right-0 margin-right-50' aria-label='unit'>\n {unit}\n </div>\n )}\n {showOldValue && (\n <div className={oldValueClasses} aria-label='previous value'>\n {oldInputValue}\n </div>\n )}\n <div className='input-group-btn'>\n <Button bsStyle={buttonStyle} iconOnly onClick={handleToggleInput} disabled={disableButton}>\n <span className={buttonIconClasses} />\n </Button>\n </div>\n </div>\n {!isValid && !hideErrorIcon && !unit && (\n <span className='right-25 margin-right-10 form-control-feedback rioglyph rioglyph-error-sign' />\n )}\n {!isValid && errorMessage && (\n <span className='help-block z-index-max'>\n <span>{errorMessage}</span>\n </span>\n )}\n </div>\n );\n};\n\nexport default SaveableInput;\n"],"names":["DEFAULT_BUTTON_STYLE","useFocus","isEditable","inputRef","useRef","useEffect","SaveableInput","props","placeholder","fixedPreviousValue","previousValue","externalValue","isValid","errorMessage","hideErrorIcon","onValueChanged","noop","onInputChange","onEsc","onEnterEdit","buttonStyle","inputClassName","inputProps","icon","unit","disabled","className","remainingProps","externalOldValue","inputValue","setInputValue","useState","oldInputValue","setOldInputValue","editInput","setEditInput","isFocused","setIsFocused","initialInputValueRef","initialOldInputValueRef","previousExternalValue","setPreviousExternalValue","previousExternalOldValue","setPreviousExternalOldValue","useKey","event","handleToggleInput","useEsc","handleInputChange","nativeEventData","currentInputValue","handleFocus","handleBlur","showOldValue","isEmpty","wrapperClasses","classNames","inputClasses","oldValueClasses","buttonIconClasses","disableButton","jsxs","jsx","Button"],"mappings":"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"}
|