@up42/up-components 9.0.0 → 9.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/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Fade, Slide, Grow, createTheme, SvgIcon, Alert as Alert$1, AlertTitle, capitalize as capitalize$1, Box, Snackbar, CssBaseline, CircularProgress, Avatar as Avatar$1, Grid, Container, Checkbox as Checkbox$1, FormLabel as FormLabel$1, FormControl, FormGroup, FormControlLabel, FormHelperText, InputAdornment, IconButton, Button as Button$1, Radio as Radio$1, RadioGroup, Switch as Switch$1, Select as Select$1, MenuItem, TextField, Slider as Slider$1, Link as Link$1, Tab as Tab$1, Tabs as Tabs$1, Divider as Divider$1, Card, CardContent, Modal, Tooltip, Popover as Popover$1, Typography as Typography$1, Stack, Badge as Badge$1, Chip, Menu, styled, Autocomplete, Dialog, alpha } from '@mui/material';
1
+ import { Fade, Slide, Grow, createTheme, SvgIcon, Alert as Alert$1, AlertTitle, capitalize as capitalize$1, Box, Snackbar, CssBaseline, CircularProgress, Avatar as Avatar$1, Grid, Container, Checkbox as Checkbox$1, FormLabel as FormLabel$1, FormControl, FormGroup, FormControlLabel, FormHelperText, InputAdornment, IconButton, Button as Button$1, Radio as Radio$1, RadioGroup, Switch as Switch$1, Select as Select$1, MenuItem, TextField, Slider as Slider$1, Link as Link$1, Tab as Tab$1, Tabs as Tabs$1, Divider as Divider$1, Card, CardContent, Modal, Tooltip, Popover as Popover$1, Chip, Autocomplete, Typography as Typography$1, Stack, Badge as Badge$1, Menu, styled, Dialog, alpha } from '@mui/material';
2
2
  export * from '@mui/material';
3
3
  import { ThemeProvider } from '@mui/material/styles';
4
4
  import * as React from 'react';
@@ -804,6 +804,20 @@ const MuiSwitch = {
804
804
 
805
805
  const MuiSlider = {
806
806
  styleOverrides: {
807
+ root: {
808
+ '& .MuiSlider-markLabel': {
809
+ fontWeight: tokens.typography.fontWeight.regular,
810
+ fontSize: tokens.typography.fontSize400,
811
+ // Target the FIRST element with this specific class and remove the transform
812
+ '&:nth-child(1 of .MuiSlider-markLabel)': {
813
+ transform: 'none',
814
+ },
815
+ // Target the LAST element with this specific class and reset the transform
816
+ '&:nth-last-child(1 of .MuiSlider-markLabel)': {
817
+ transform: 'translateX(-100%)',
818
+ },
819
+ },
820
+ },
807
821
  rail: {
808
822
  height: tokens.size.spacingXS,
809
823
  backgroundColor: tokens.color.gray100,
@@ -7000,14 +7014,26 @@ const DEFAULT_HEADER = 'Filters';
7000
7014
  *
7001
7015
  * Documentation: https://up-components.up42.com/?path=/docs-patterns-popovers-filterpopover--docs
7002
7016
  */
7003
- const FilterPopover = ({ anchorEl, onClose, header = DEFAULT_HEADER, content, applyButtonLabel = DEFAULT_APPLY_LABEL, clearButtonLabel = DEFAULT_CLEAR_LABEL, disableApplyButton = false, isLoadingCount = false, onApply, onClear, ...popoverProps }) => {
7017
+ const FilterPopover = ({ anchorEl, onClose, header = DEFAULT_HEADER, content, applyButtonLabel = DEFAULT_APPLY_LABEL, clearButtonLabel = DEFAULT_CLEAR_LABEL, disableApplyButton = false, isLoadingCount = false, maxContentWidth = '384px', onApply, onClear, ...popoverProps }) => {
7004
7018
  const handleApply = async () => {
7005
7019
  await onApply?.();
7006
7020
  };
7007
7021
  const handleClear = async () => {
7008
7022
  await onClear?.();
7009
7023
  };
7010
- return (React__default.createElement(Popover, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: onClose, header: header, content: content != null ? React__default.createElement(React__default.Fragment, null, content) : undefined, showDividers: true, hideBackdrop: true, disableEnforceFocus: true, disableScrollLock: true, sx: {
7024
+ return (React__default.createElement(Popover, { open: Boolean(anchorEl), anchorEl: anchorEl, onClose: onClose, header: header, content: content && content.length > 0 ? (React__default.createElement(Box, { sx: {
7025
+ display: 'flex',
7026
+ flexDirection: 'column',
7027
+ gap: tokens.size.spacing.scale16,
7028
+ maxWidth: maxContentWidth,
7029
+ '& .MuiSlider-root': {
7030
+ display: 'flex',
7031
+ width: '90%',
7032
+ mx: 'auto',
7033
+ },
7034
+ } }, content.map((item, index) => (React__default.createElement(React__default.Fragment, { key: index },
7035
+ item,
7036
+ index < content.length - 1 && React__default.createElement(Divider$1, { sx: { mx: 0 } })))))) : undefined, showDividers: true, hideBackdrop: true, disableEnforceFocus: true, disableScrollLock: true, sx: {
7011
7037
  // Allows to interact with other elements outside the popover when the popover is open
7012
7038
  pointerEvents: 'none',
7013
7039
  '& > .MuiPaper-root': {
@@ -7024,6 +7050,216 @@ const FilterPopover = ({ anchorEl, onClose, header = DEFAULT_HEADER, content, ap
7024
7050
  }, ...popoverProps }));
7025
7051
  };
7026
7052
 
7053
+ /**
7054
+ * Documentation: https://up-components.up42.com/?path=/docs/data-display-tag--docs
7055
+ */
7056
+ const Tag = ({ color = 'primary', ...props }) => {
7057
+ return React__default.createElement(Chip, { size: "small", color: color, deleteIcon: React__default.createElement(Icon, { name: "Close", "data-testid": "CloseIcon" }), ...props });
7058
+ };
7059
+
7060
+ const DELIMITERS = [',', ';'];
7061
+ const SPLIT_REGEXP = new RegExp(DELIMITERS.join('|'), 'g');
7062
+ /**
7063
+ * Autocomplete-based single or multi-select form input. Selected values are displayed
7064
+ * as chips inside the input field.
7065
+ * Supports adding custom values by typing and pressing Enter (comma/semicolon delimiters).
7066
+ *
7067
+ * Documentation: https://up-components.up42.com/?path=/docs/patterns-form-formautocomplete--docs
7068
+ */
7069
+ const FormAutocomplete = ({ id, component = 'div', title, label, valuesMap = {}, values = [], onChange, placeholder, multiple = false, limitTags = -1, // -1 means no limit
7070
+ addCustom = false, allOptionsSelectedPlaceholder, required, disabled, error, helperText, sx, groupBy, }) => {
7071
+ const [inputValue, setInputValue] = useState('');
7072
+ /**
7073
+ * Used to show the allOptionsSelectedPlaceholder when the input is not focused.
7074
+ * @default false
7075
+ */
7076
+ const [isFocused, setIsFocused] = useState(false);
7077
+ /**
7078
+ * Options to display in the autocomplete.
7079
+ */
7080
+ const options = useMemo(() => generateOptions(valuesMap), [valuesMap]);
7081
+ /**
7082
+ * Value for the autocomplete.
7083
+ */
7084
+ const valueForAutocomplete = useMemo(() => {
7085
+ const inputValues = values.map((id) => ({
7086
+ label: valuesMap[id]?.title ?? id,
7087
+ id,
7088
+ }));
7089
+ return multiple ? inputValues : inputValues[0] ?? null;
7090
+ }, [values, valuesMap]);
7091
+ const allOptionsSelected = options.length > 0 && values.length === options.length;
7092
+ const showAllOptionsSelectedPlaceholder = multiple && !addCustom && Boolean(allOptionsSelectedPlaceholder) && allOptionsSelected && !isFocused;
7093
+ /** Converts typed string to options. With addCustom: split by comma/semicolon. Otherwise: match valuesMap by title. */
7094
+ const expandStringToOptions = (input) => {
7095
+ if (input.trim() === '')
7096
+ return [];
7097
+ if (addCustom) {
7098
+ return splitInput(input).map((p) => ({ label: p, id: p }));
7099
+ }
7100
+ const matchingIds = Object.values(valuesMap)
7101
+ .filter(({ title }) => isSubstring(title, input))
7102
+ .map(({ name }) => name);
7103
+ return matchingIds.map((id) => ({ label: valuesMap[id]?.title ?? id, id }));
7104
+ };
7105
+ /** Converts a selected option to options. With addCustom: id may contain "x, y" delimiters to split. */
7106
+ const expandOptionToOptions = (option) => {
7107
+ if (addCustom) {
7108
+ const inputValues = splitInput(option.id);
7109
+ if (inputValues.length > 1) {
7110
+ return inputValues.map((value) => ({ label: value, id: value }));
7111
+ }
7112
+ }
7113
+ return [option];
7114
+ };
7115
+ /** Expands a single input item (string or option) into an array of options. */
7116
+ const expandInputItem = (item) => {
7117
+ return typeof item === 'string' ? expandStringToOptions(item) : expandOptionToOptions(toOption(item));
7118
+ };
7119
+ /**
7120
+ * Handles the change event for the autocomplete input.
7121
+ * @param _event - The event object.
7122
+ * @param newValue{AutocompleteValue | AutocompleteValue[]} - The new value(s) for the input. Can be a single value or an array of values(string or FormAutocompleteOption).
7123
+ */
7124
+ const handleChange = (_event, newValue) => {
7125
+ setInputValue('');
7126
+ if (newValue == null) {
7127
+ onChange([]);
7128
+ return;
7129
+ }
7130
+ const items = Array.isArray(newValue) ? newValue : [newValue];
7131
+ const expandedOptions = items.flatMap(expandInputItem);
7132
+ const uniqueOptionsById = expandedOptions.filter((option, index) => expandedOptions.findIndex((o) => o.id === option.id) === index);
7133
+ const optionIds = uniqueOptionsById.map((option) => option.id);
7134
+ onChange(multiple ? optionIds : optionIds.slice(0, 1));
7135
+ };
7136
+ const handleInputChange = (_event, newInputValue) => {
7137
+ setInputValue(newInputValue);
7138
+ };
7139
+ const getOptionLabel = (option) => {
7140
+ if (typeof option === 'string')
7141
+ return option;
7142
+ return option.label;
7143
+ };
7144
+ const filterOptions = (options, { inputValue }) => {
7145
+ const filteredOptions = options.filter((option) => {
7146
+ const alreadySelected = values.includes(option.id);
7147
+ const matchesInput = inputValue === '' || isSubstring(option.label, inputValue);
7148
+ return !alreadySelected && matchesInput;
7149
+ });
7150
+ // When addCustom, suggest "Add X, Y, Z" for typed input (supports ; or , delimiters)
7151
+ const inputValues = splitInput(inputValue);
7152
+ const isExisting = filteredOptions.some((opt) => inputValue === opt.id);
7153
+ if (addCustom && !isExisting && inputValues.length > 0) {
7154
+ filteredOptions.push({
7155
+ label: `Add ${inputValues.join(', ')}`,
7156
+ id: inputValue,
7157
+ });
7158
+ }
7159
+ return filteredOptions;
7160
+ };
7161
+ const getInputPlaceholder = () => {
7162
+ if (showAllOptionsSelectedPlaceholder)
7163
+ return allOptionsSelectedPlaceholder;
7164
+ if (placeholder)
7165
+ return placeholder;
7166
+ if (title)
7167
+ return `Search by ${title.toLowerCase()}`;
7168
+ };
7169
+ const renderTags = (tagValue, getTagProps) => {
7170
+ if (showAllOptionsSelectedPlaceholder)
7171
+ return null;
7172
+ return tagValue.map((option, index) => {
7173
+ const opt = toOption(option);
7174
+ return React__default.createElement(Tag, { key: opt.id, label: opt.label, ...getTagProps({ index }) });
7175
+ });
7176
+ };
7177
+ return (React__default.createElement(FormControl, { component: component, error: error, disabled: disabled, sx: sx },
7178
+ React__default.createElement(FormLabel, { label: title, required: required, htmlFor: id }),
7179
+ React__default.createElement(Autocomplete, { freeSolo: true, fullWidth: true, multiple: multiple, options: options, "aria-label": `Filter ${title || label}`, value: valueForAutocomplete, clearOnBlur: true, limitTags: limitTags, inputValue: inputValue, onInputChange: handleInputChange, onChange: handleChange, getOptionLabel: getOptionLabel, renderInput: (params) => (React__default.createElement(TextField, { ...params, label: label, placeholder: getInputPlaceholder(), InputLabelProps: { shrink: true }, InputProps: {
7180
+ ...params.InputProps,
7181
+ // TODO: Remove when upgrading to MUI v6.
7182
+ // With limitTags set, the root's onClick fires after the input's mousedown,causing the dropdown to open then
7183
+ // immediately close on first click. Overriding with undefined fixes it; the input's onMouseDown still opens the dropdown.
7184
+ // PR fix for this on MUI v6: https://github.com/mui/material-ui/pull/42494
7185
+ onClick: undefined,
7186
+ }, inputProps: {
7187
+ ...params.inputProps,
7188
+ onFocus: (e) => {
7189
+ setIsFocused(true);
7190
+ params.inputProps?.onFocus?.(e);
7191
+ },
7192
+ onBlur: (e) => {
7193
+ setIsFocused(false);
7194
+ params.inputProps?.onBlur?.(e);
7195
+ },
7196
+ } })), renderTags: multiple ? renderTags : undefined, disableCloseOnSelect: multiple, filterOptions: filterOptions, groupBy: groupBy, sx: { my: 1, mt: label ? 2 : 1 } }),
7197
+ error && helperText && React__default.createElement(FormHelperText, { error: error }, helperText)));
7198
+ };
7199
+ /** ===============================================================
7200
+ * Internal Helper functions
7201
+ * These are not exported and are used only within this component.
7202
+ * ================================================================
7203
+ */
7204
+ /**
7205
+ * Generate options from a mapped object.
7206
+ * @param mappedObject - The mapped object to generate options from.
7207
+ * @returns An array of FormAutocompleteOption.
7208
+ */
7209
+ function generateOptions(mappedObject = {}) {
7210
+ return Object.values(mappedObject)
7211
+ .map(({ title, name }) => ({ label: title, id: name }))
7212
+ .sort((a, b) => a.label.localeCompare(b.label));
7213
+ }
7214
+ /**
7215
+ * Split an input string into an array of strings based on delimiters (comma or semicolon).
7216
+ * @param str - The string to split.
7217
+ * @returns An array of strings.
7218
+ */
7219
+ function splitInput(str) {
7220
+ return str
7221
+ .split(SPLIT_REGEXP)
7222
+ .map((s) => s.trim())
7223
+ .filter(Boolean);
7224
+ }
7225
+ /**
7226
+ * Check if a string is a substring of another string.
7227
+ * @param str - The string to check.
7228
+ * @param sub - The substring to check.
7229
+ * @returns True if the string is a substring of the other string, false otherwise.
7230
+ */
7231
+ function isSubstring(str, sub) {
7232
+ const normalized = str
7233
+ .normalize('NFD')
7234
+ .replace(/[\u0300-\u036f]/g, '')
7235
+ .toLowerCase();
7236
+ return normalized.includes(sub.toLowerCase());
7237
+ }
7238
+ /**
7239
+ * Convert an AutocompleteValue to a FormAutocompleteOption.
7240
+ * @param val - The AutocompleteValue to convert.
7241
+ * @returns The FormAutocompleteOption.
7242
+ */
7243
+ function toOption(val) {
7244
+ if (typeof val === 'string') {
7245
+ return { label: val, id: val };
7246
+ }
7247
+ return val;
7248
+ }
7249
+
7250
+ const BaseFormSlider = ({ id, component = 'div', required, disabled, label, error, helperText, sx, inputRef, ...props }) => {
7251
+ return (React__default.createElement(FormControl, { component: component, error: error, disabled: disabled, sx: sx },
7252
+ React__default.createElement(FormLabel, { label: label, required: required, htmlFor: id }),
7253
+ React__default.createElement(Slider, { ref: inputRef, ...props }),
7254
+ error && helperText && React__default.createElement(FormHelperText, { error: error }, helperText)));
7255
+ };
7256
+ /**
7257
+ * Form wrapper for Slider. Use with useGsdSlider for GSD (Ground Sampling Distance) range sliders.
7258
+ *
7259
+ * Documentation: https://up-components.up42.com/?path=/docs/patterns-form-formslider--docs
7260
+ */
7261
+ const FormSlider = React__default.forwardRef((props, ref) => (React__default.createElement(BaseFormSlider, { inputRef: ref, ...props })));
7262
+
7027
7263
  const { spacing } = tokens.size;
7028
7264
  /**
7029
7265
  * Documentation: https://up-components.up42.com/?path=/docs/patterns-pageheader--docs
@@ -7339,13 +7575,6 @@ const Badge = ({ children, color = 'info', ...props }) => {
7339
7575
  return (React__default.createElement(Badge$1, { color: color, ...props }, children));
7340
7576
  };
7341
7577
 
7342
- /**
7343
- * Documentation: https://up-components.up42.com/?path=/docs/data-display-tag--docs
7344
- */
7345
- const Tag = ({ color = 'primary', ...props }) => {
7346
- return React__default.createElement(Chip, { size: "small", color: color, deleteIcon: React__default.createElement(Icon, { name: "Close", "data-testid": "CloseIcon" }), ...props });
7347
- };
7348
-
7349
7578
  dayjs.extend(utc);
7350
7579
  dayjs.extend(relativeTime);
7351
7580
  /**
@@ -11815,6 +12044,51 @@ const useDebounce = (value, delay = 500) => {
11815
12044
  return debouncedValue;
11816
12045
  };
11817
12046
 
12047
+ const DEFAULT_MARK_VALUES = [0, 2.5, 10, 30];
12048
+ /**
12049
+ * Hook for GSD (Ground Sampling Distance) range slider with logarithmic scale.
12050
+ * Handles conversion between linear slider values and logarithmic GSD values.
12051
+ */
12052
+ function useGsdSlider({ minValue, maxValue, onChange, markValues = DEFAULT_MARK_VALUES }) {
12053
+ const minGsd = markValues.length > 0 ? Math.min(...markValues) : DEFAULT_MARK_VALUES[0];
12054
+ const maxGsd = markValues.length > 0 ? Math.max(...markValues) : DEFAULT_MARK_VALUES[DEFAULT_MARK_VALUES.length - 1];
12055
+ const sliderValue = useMemo(() => [getSliderValueFromGsd(minValue, minGsd, maxGsd), getSliderValueFromGsd(maxValue, minGsd, maxGsd)], [minValue, maxValue, minGsd, maxGsd]);
12056
+ const marks = useMemo(() => markValues.map((mark) => ({
12057
+ value: getSliderValueFromGsd(mark, minGsd, maxGsd),
12058
+ label: `${mark} m`,
12059
+ })), [markValues, minGsd, maxGsd]);
12060
+ const handleSliderChange = (_event, newValue) => {
12061
+ if (newValue === undefined)
12062
+ return;
12063
+ const values = Array.isArray(newValue) ? newValue : [newValue, newValue];
12064
+ const [min, max] = values.map((v) => getGsdFromSliderValue(v, minGsd, maxGsd));
12065
+ onChange(min, max);
12066
+ };
12067
+ const scale = (n) => getGsdFromSliderValue(n, minGsd, maxGsd);
12068
+ return {
12069
+ sliderValue,
12070
+ marks,
12071
+ handleSliderChange,
12072
+ scale,
12073
+ minGsd,
12074
+ maxGsd,
12075
+ };
12076
+ }
12077
+ /**
12078
+ * Convert the value from the slider to a GSD value using a logarithm.
12079
+ */
12080
+ function getGsdFromSliderValue(value, minGsd, maxGsd) {
12081
+ const scaledValue = Math.pow(2, (value * Math.log2(maxGsd + 1)) / (maxGsd - minGsd)) - 1;
12082
+ return Number(scaledValue.toFixed(2));
12083
+ }
12084
+ /**
12085
+ * Convert the GSD value to a value for the slider using a reverse logarithm.
12086
+ */
12087
+ function getSliderValueFromGsd(scaledValue, minGsd, maxGsd) {
12088
+ const value = ((Math.log(scaledValue + 1) / Math.log(2)) * (maxGsd - minGsd)) / Math.log2(maxGsd + 1);
12089
+ return Number(value.toFixed(2));
12090
+ }
12091
+
11818
12092
  /**
11819
12093
  * There could be many ways to parse URLSearchParams to an object.
11820
12094
  * For example, how should `a` be treated in `a=1&b=2&a=3`?
@@ -11921,4 +12195,4 @@ function useUrlParams(options = {}) {
11921
12195
  };
11922
12196
  }
11923
12197
 
11924
- export { ActionToolbar, Alert, Avatar, Badge, Banner, Button, Checkbox, CodeBlock, CodeInline, CodeSnippet, ContactBox, ControlButton, CopyButton, DataGrid, DateTime, Divider, DocumentationPopover, EditTagsButton, EmptyState, FeatureCard, FeatureCardHeader, FeatureCardHeaderActions, FeatureFlagCheckbox, FilterPopover, FindUsersButton, FormCheckbox, FormDatePicker, FormDateRangePicker, FormDateRangePickerList, FormDateTimePicker, FormInput, FormRadio, FormSelect, FormSwitch, GridContainer, GridItem, Icon, Illustration, InfoCard, InfoModal, InfoPopover, Input, LearnMoreButton, Link, Loading, Logo, NotFound, PageContainer, PageHeader, PageHeaderV2, Popover, Radio, RoleBanner, Select, Slider, StatusLight, Switch, Tab, TabGroup, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TablePagination, TableRow, TableSortLabel, Tabs, Tag, TagsList, ToggleButton, Typography, UpComponentsProvider, analytics, capitalize, copyToClipboard, formatDate, formatFileSize, formatNumber, generateQueryKey, objectToSearchParams, searchParamsToObject, theme, tokens, useAlert, useCursorPagination, useDebounce, useQueryParams, useRemotePagination, useToggle, useUrlParams, valueToString };
12198
+ export { ActionToolbar, Alert, Avatar, Badge, Banner, Button, Checkbox, CodeBlock, CodeInline, CodeSnippet, ContactBox, ControlButton, CopyButton, DataGrid, DateTime, Divider, DocumentationPopover, EditTagsButton, EmptyState, FeatureCard, FeatureCardHeader, FeatureCardHeaderActions, FeatureFlagCheckbox, FilterPopover, FindUsersButton, FormAutocomplete, FormCheckbox, FormDatePicker, FormDateRangePicker, FormDateRangePickerList, FormDateTimePicker, FormInput, FormRadio, FormSelect, FormSlider, FormSwitch, GridContainer, GridItem, Icon, Illustration, InfoCard, InfoModal, InfoPopover, Input, LearnMoreButton, Link, Loading, Logo, NotFound, PageContainer, PageHeader, PageHeaderV2, Popover, Radio, RoleBanner, Select, Slider, StatusLight, Switch, Tab, TabGroup, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TablePagination, TableRow, TableSortLabel, Tabs, Tag, TagsList, ToggleButton, Typography, UpComponentsProvider, analytics, capitalize, copyToClipboard, formatDate, formatFileSize, formatNumber, generateQueryKey, objectToSearchParams, searchParamsToObject, theme, tokens, useAlert, useCursorPagination, useDebounce, useGsdSlider, useQueryParams, useRemotePagination, useToggle, useUrlParams, valueToString };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { default as tokens } from '@up42/design-system-tokens/dist/json/tokens.json';
2
2
  import * as _mui_material from '@mui/material';
3
- import { BoxProps, TextFieldProps, AvatarProps as AvatarProps$1, GridProps, ContainerProps, CheckboxProps as CheckboxProps$1, RadioProps as RadioProps$1, RadioGroupProps, SwitchProps as SwitchProps$1, SelectProps as SelectProps$1, SliderProps as SliderProps$1, LinkProps as LinkProps$1, TabProps as TabProps$1, TabsProps as TabsProps$1, CardProps, ModalProps, AlertProps as AlertProps$1, SxProps, Theme, IconButtonProps, SvgIconProps, PopoverProps as PopoverProps$1, BadgeProps as BadgeProps$1, ChipProps, DividerProps as DividerProps$1, ButtonProps as ButtonProps$2, SnackbarProps } from '@mui/material';
3
+ import { BoxProps, TextFieldProps, AvatarProps as AvatarProps$1, GridProps, ContainerProps, CheckboxProps as CheckboxProps$1, RadioProps as RadioProps$1, RadioGroupProps, SwitchProps as SwitchProps$1, SelectProps as SelectProps$1, SliderProps as SliderProps$2, LinkProps as LinkProps$1, TabProps as TabProps$1, TabsProps as TabsProps$1, CardProps, ModalProps, AlertProps as AlertProps$1, SxProps, Theme, IconButtonProps, SvgIconProps, PopoverProps as PopoverProps$1, BadgeProps as BadgeProps$1, ChipProps, DividerProps as DividerProps$1, ButtonProps as ButtonProps$2, SnackbarProps } from '@mui/material';
4
4
  export * from '@mui/material';
5
5
  import { ThemeProviderProps } from '@mui/material/styles/ThemeProvider';
6
6
  import * as React from 'react';
@@ -282,11 +282,11 @@ type FormInputProps = FormBaseProps & InputProps;
282
282
  */
283
283
  declare const FormInput: React__default.ForwardRefExoticComponent<Omit<FormInputProps, "ref"> & React__default.RefAttributes<HTMLInputElement>>;
284
284
 
285
- type SliderProps = MUIGlobalOmit<Omit<SliderProps$1, 'variant' | 'label'>>;
285
+ type SliderProps$1 = MUIGlobalOmit<Omit<SliderProps$2, 'variant' | 'label'>>;
286
286
  /**
287
287
  * Documentation: https://up-components.up42.com/?path=/docs/data-entry-slider--default--docs
288
288
  */
289
- declare const Slider: (props: SliderProps) => React__default.JSX.Element;
289
+ declare const Slider: (props: SliderProps$1) => React__default.JSX.Element;
290
290
 
291
291
  type LinkProps<C extends React__default.ElementType> = LinkProps$1<C, {
292
292
  component?: C;
@@ -4742,9 +4742,10 @@ declare const Popover: React__default.ForwardRefExoticComponent<Omit<PopoverProp
4742
4742
 
4743
4743
  type FilterPopoverProps = Pick<PopoverProps, 'anchorEl' | 'onClose' | 'header' | 'sx' | 'size'> & {
4744
4744
  /**
4745
- * Filter area content (placeholder node for now).
4745
+ * Array of filter input components to display. Each item is rendered in a vertical stack with spacing.
4746
+ * Use FormInput, FormDateRangePicker, FormSlider, FormAutocomplete, etc.
4746
4747
  */
4747
- content?: React__default.ReactNode;
4748
+ content?: React__default.ReactNode[];
4748
4749
  /**
4749
4750
  * Apply button text.
4750
4751
  * @default 'Apply filters'
@@ -4765,6 +4766,11 @@ type FilterPopoverProps = Pick<PopoverProps, 'anchorEl' | 'onClose' | 'header' |
4765
4766
  * @default false
4766
4767
  */
4767
4768
  disableApplyButton?: boolean;
4769
+ /**
4770
+ * Maximum width of the content.
4771
+ * @default '384px'
4772
+ */
4773
+ maxContentWidth?: string;
4768
4774
  /**
4769
4775
  * Called when Apply is clicked; popover closes after.
4770
4776
  */
@@ -4780,7 +4786,115 @@ type FilterPopoverProps = Pick<PopoverProps, 'anchorEl' | 'onClose' | 'header' |
4780
4786
  *
4781
4787
  * Documentation: https://up-components.up42.com/?path=/docs-patterns-popovers-filterpopover--docs
4782
4788
  */
4783
- declare const FilterPopover: ({ anchorEl, onClose, header, content, applyButtonLabel, clearButtonLabel, disableApplyButton, isLoadingCount, onApply, onClear, ...popoverProps }: FilterPopoverProps) => React__default.JSX.Element;
4789
+ declare const FilterPopover: ({ anchorEl, onClose, header, content, applyButtonLabel, clearButtonLabel, disableApplyButton, isLoadingCount, maxContentWidth, onApply, onClear, ...popoverProps }: FilterPopoverProps) => React__default.JSX.Element;
4790
+
4791
+ type FormAutocompleteMapper = Record<string, {
4792
+ title: string;
4793
+ name: string;
4794
+ }>;
4795
+ type FormAutocompleteOption = {
4796
+ label: string;
4797
+ id: string;
4798
+ };
4799
+ type FormAutocompleteProps = {
4800
+ /**
4801
+ * ID of the input.
4802
+ */
4803
+ id?: string;
4804
+ /**
4805
+ * Component to wrap the input.
4806
+ */
4807
+ component?: React__default.ElementType;
4808
+ /**
4809
+ * Title of the input.
4810
+ */
4811
+ title?: string;
4812
+ /**
4813
+ * Label of the input.
4814
+ */
4815
+ label?: string;
4816
+ /**
4817
+ * Selected values.
4818
+ */
4819
+ values?: string[];
4820
+ /**
4821
+ * Map of values to options.
4822
+ */
4823
+ valuesMap?: FormAutocompleteMapper;
4824
+ /**
4825
+ * Callback when selection changes.
4826
+ */
4827
+ onChange: (values: string[]) => void;
4828
+ /**
4829
+ * Placeholder text when no selection.
4830
+ */
4831
+ placeholder?: string;
4832
+ /**
4833
+ * When true, allows multiple selections. Selected values are displayed as chips inside the input.
4834
+ * @default false
4835
+ */
4836
+ multiple?: boolean;
4837
+ /**
4838
+ * Maximum number of tags to display. -1 means no limit.
4839
+ * @default -1
4840
+ */
4841
+ limitTags?: number;
4842
+ /**
4843
+ * When true, allows adding custom text as values. Shows "Add X, Y, Z" in the dropdown when typing.
4844
+ * Supports multiple values separated by comma or semicolon.
4845
+ * @default false
4846
+ */
4847
+ addCustom?: boolean;
4848
+ /**
4849
+ * Text to display when all options are selected (multiple=true, addCustom=false).
4850
+ * Shown when input is not focused; selected chips are shown when focused.
4851
+ */
4852
+ allOptionsSelectedPlaceholder?: string;
4853
+ /**
4854
+ * Whether the input is required.
4855
+ */
4856
+ required?: boolean;
4857
+ /**
4858
+ * Whether the input is disabled.
4859
+ */
4860
+ disabled?: boolean;
4861
+ /**
4862
+ * Error message to display.
4863
+ */
4864
+ error?: boolean;
4865
+ /**
4866
+ * Helper text to display.
4867
+ */
4868
+ helperText?: string;
4869
+ /**
4870
+ * Styles to apply to the input.
4871
+ */
4872
+ sx?: SxProps<Theme>;
4873
+ /**
4874
+ * Function that returns the group key for each option. Groups options in the dropdown.
4875
+ */
4876
+ groupBy?: (option: FormAutocompleteOption) => string;
4877
+ };
4878
+ /**
4879
+ * Autocomplete-based single or multi-select form input. Selected values are displayed
4880
+ * as chips inside the input field.
4881
+ * Supports adding custom values by typing and pressing Enter (comma/semicolon delimiters).
4882
+ *
4883
+ * Documentation: https://up-components.up42.com/?path=/docs/patterns-form-formautocomplete--docs
4884
+ */
4885
+ declare const FormAutocomplete: ({ id, component, title, label, valuesMap, values, onChange, placeholder, multiple, limitTags, addCustom, allOptionsSelectedPlaceholder, required, disabled, error, helperText, sx, groupBy, }: FormAutocompleteProps) => React__default.JSX.Element;
4886
+
4887
+ type SliderProps = MUIGlobalOmit<Omit<SliderProps$2, 'variant' | 'label'>>
4888
+
4889
+ type FormSliderProps = Omit<FormBaseProps, 'onChange'> & SliderProps & {
4890
+ inputRef?: SliderProps['ref'];
4891
+ };
4892
+ /**
4893
+ * Form wrapper for Slider. Use with useGsdSlider for GSD (Ground Sampling Distance) range sliders.
4894
+ *
4895
+ * Documentation: https://up-components.up42.com/?path=/docs/patterns-form-formslider--docs
4896
+ */
4897
+ declare const FormSlider: React__default.ForwardRefExoticComponent<Omit<FormSliderProps, "ref"> & React__default.RefAttributes<HTMLSpanElement>>;
4784
4898
 
4785
4899
  type PageHeaderProps = {
4786
4900
  title: string;
@@ -11709,6 +11823,41 @@ declare function useToggle(initialState: boolean | (() => boolean)): UseToggleRe
11709
11823
  */
11710
11824
  declare const useDebounce: <T>(value: T, delay?: number) => T;
11711
11825
 
11826
+ type UseGsdSliderProps = {
11827
+ /**
11828
+ * Minimum GSD value (meters). Controlled by parent.
11829
+ */
11830
+ minValue: number;
11831
+ /**
11832
+ * Maximum GSD value (meters). Controlled by parent.
11833
+ */
11834
+ maxValue: number;
11835
+ /**
11836
+ * Callback when the range changes.
11837
+ */
11838
+ onChange: (minValue: number, maxValue: number) => void;
11839
+ /**
11840
+ * GSD values for the slider marks.
11841
+ * @default [0, 2.5, 10, 30]
11842
+ */
11843
+ markValues?: number[];
11844
+ };
11845
+ /**
11846
+ * Hook for GSD (Ground Sampling Distance) range slider with logarithmic scale.
11847
+ * Handles conversion between linear slider values and logarithmic GSD values.
11848
+ */
11849
+ declare function useGsdSlider({ minValue, maxValue, onChange, markValues }: UseGsdSliderProps): {
11850
+ sliderValue: [number, number];
11851
+ marks: {
11852
+ value: number;
11853
+ label: string;
11854
+ }[];
11855
+ handleSliderChange: (_event: unknown, newValue?: number | number[]) => void;
11856
+ scale: (n: number) => number;
11857
+ minGsd: number;
11858
+ maxGsd: number;
11859
+ };
11860
+
11712
11861
  type CreateAlertProps = {
11713
11862
  title?: string;
11714
11863
  message: string | ElementType;
@@ -11814,5 +11963,5 @@ declare function valueToString(value: unknown): string;
11814
11963
  */
11815
11964
  declare function objectToSearchParams<T extends ParamsObject = ParamsObject>(object: T): string;
11816
11965
 
11817
- export { ActionToolbar, Alert, Avatar, Badge, Banner, Button, Checkbox, CodeBlock, CodeInline, CodeSnippet, ContactBox, ControlButton, CopyButton, DataGrid, DateTime, Divider, DocumentationPopover, EditTagsButton, EmptyState, FeatureCard, FeatureCardHeader, FeatureCardHeaderActions, FeatureFlagCheckbox, FilterPopover, FindUsersButton, FormCheckbox, FormDatePicker, FormDateRangePicker, FormDateRangePickerList, FormDateTimePicker, FormInput, FormRadio, FormSelect, FormSwitch, GridContainer, GridItem, Icon, Illustration, InfoCard, InfoModal, InfoPopover, Input, LearnMoreButton, Link, Loading, Logo, NotFound, PageContainer, PageHeader, PageHeaderV2, Popover, Radio, RoleBanner, Select, Slider, StatusLight, Switch, Tab, TabGroup, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TablePagination, TableRow, TableSortLabel, Tabs, Tag, TagsList, ToggleButton, Typography, UpComponentsProvider, analytics, capitalize, copyToClipboard, formatDate, formatFileSize, formatNumber, generateQueryKey, objectToSearchParams, searchParamsToObject, theme, useAlert, useCursorPagination, useDebounce, useQueryParams, useRemotePagination, useToggle, useUrlParams, valueToString };
11818
- export type { ActionToolbarProps, AlertProps, AnalyticsConfig, AvatarProps, BadgeProps, BannerProps, ButtonProps, CheckboxProps, CodeBlockProps, CodeInlineProps, CodeSnippetItemProps, CodeSnippetProps, ContactBoxProps, ControlButtonProps, CopyButtonProps, CreateAlertProps, CreateSnackbarProps, CursorPaginatedResponse, DateRange, DateTimeProps, DividerProps, DocumentationPopoverProps, EditTagsButtonProps, EmptyStateProps, FeatureCardHeaderActionsProps, FeatureCardHeaderProps, FeatureCardProps, FeatureFlagCheckboxProps, FilterPopoverProps, FindUsersButtonProps, FormCheckboxProps, FormDatePickerDateType, FormDatePickerProps, FormDateRangePickerListProps, FormDateRangePickerProps, FormDateTimePickerProps, FormInputProps, FormRadioProps, FormSelectProps, FormSwitchProps, GridContainerProps, GridItemProps, IconAction, IconProps$1 as IconProps, IllustrationProps, InfoCardProps, InfoModalProps, InfoPopoverProps, InputProps, LearnMoreButtonProps, LinkProps, LoadingProps, LogoProps, MenuAction, NotFoundProps, PageContainerProps, PageHeaderProps, PageHeaderV2Props, PaginatedResponse, ParamsObject, PopoverProps, RadioProps, RemoveParamRules, RoleBannerProps, SearchParamObject, SelectProps, SliderProps, StatusLightProps, SwitchProps, TabGroupProps, TabProps, TableBodyProps, TableCellProps, TableContainerProps, TableFooterProps, TableHeadProps, TablePaginationProps, TableProps, TableRowProps, TableSortLabelProps, TabsProps, TagItem, TagProps, TagsListProps, ToggleButtonProps, TypographyProps, UseToggleResult };
11966
+ export { ActionToolbar, Alert, Avatar, Badge, Banner, Button, Checkbox, CodeBlock, CodeInline, CodeSnippet, ContactBox, ControlButton, CopyButton, DataGrid, DateTime, Divider, DocumentationPopover, EditTagsButton, EmptyState, FeatureCard, FeatureCardHeader, FeatureCardHeaderActions, FeatureFlagCheckbox, FilterPopover, FindUsersButton, FormAutocomplete, FormCheckbox, FormDatePicker, FormDateRangePicker, FormDateRangePickerList, FormDateTimePicker, FormInput, FormRadio, FormSelect, FormSlider, FormSwitch, GridContainer, GridItem, Icon, Illustration, InfoCard, InfoModal, InfoPopover, Input, LearnMoreButton, Link, Loading, Logo, NotFound, PageContainer, PageHeader, PageHeaderV2, Popover, Radio, RoleBanner, Select, Slider, StatusLight, Switch, Tab, TabGroup, Table, TableBody, TableCell, TableContainer, TableFooter, TableHead, TablePagination, TableRow, TableSortLabel, Tabs, Tag, TagsList, ToggleButton, Typography, UpComponentsProvider, analytics, capitalize, copyToClipboard, formatDate, formatFileSize, formatNumber, generateQueryKey, objectToSearchParams, searchParamsToObject, theme, useAlert, useCursorPagination, useDebounce, useGsdSlider, useQueryParams, useRemotePagination, useToggle, useUrlParams, valueToString };
11967
+ export type { ActionToolbarProps, AlertProps, AnalyticsConfig, AvatarProps, BadgeProps, BannerProps, ButtonProps, CheckboxProps, CodeBlockProps, CodeInlineProps, CodeSnippetItemProps, CodeSnippetProps, ContactBoxProps, ControlButtonProps, CopyButtonProps, CreateAlertProps, CreateSnackbarProps, CursorPaginatedResponse, DateRange, DateTimeProps, DividerProps, DocumentationPopoverProps, EditTagsButtonProps, EmptyStateProps, FeatureCardHeaderActionsProps, FeatureCardHeaderProps, FeatureCardProps, FeatureFlagCheckboxProps, FilterPopoverProps, FindUsersButtonProps, FormAutocompleteMapper, FormAutocompleteProps, FormCheckboxProps, FormDatePickerDateType, FormDatePickerProps, FormDateRangePickerListProps, FormDateRangePickerProps, FormDateTimePickerProps, FormInputProps, FormRadioProps, FormSelectProps, FormSliderProps, FormSwitchProps, GridContainerProps, GridItemProps, IconAction, IconProps$1 as IconProps, IllustrationProps, InfoCardProps, InfoModalProps, InfoPopoverProps, InputProps, LearnMoreButtonProps, LinkProps, LoadingProps, LogoProps, MenuAction, NotFoundProps, PageContainerProps, PageHeaderProps, PageHeaderV2Props, PaginatedResponse, ParamsObject, PopoverProps, RadioProps, RemoveParamRules, RoleBannerProps, SearchParamObject, SelectProps, SliderProps$1 as SliderProps, StatusLightProps, SwitchProps, TabGroupProps, TabProps, TableBodyProps, TableCellProps, TableContainerProps, TableFooterProps, TableHeadProps, TablePaginationProps, TableProps, TableRowProps, TableSortLabelProps, TabsProps, TagItem, TagProps, TagsListProps, ToggleButtonProps, TypographyProps, UseGsdSliderProps, UseToggleResult };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@up42/up-components",
3
- "version": "9.0.0",
3
+ "version": "9.1.0",
4
4
  "description": "UP42 Component Library",
5
5
  "author": "Axel Fuhrmann axel.fuhrmann@up42.com",
6
6
  "license": "ISC",
@@ -124,7 +124,8 @@
124
124
  "lodash@>=4.0.0 <=4.17.22": ">=4.17.23",
125
125
  "serialize-javascript@<=7.0.2": ">=7.0.3",
126
126
  "csstype@>=3.0.0": "3.1.3",
127
- "@tootallnate/once@<3.0.1": ">=3.0.1"
127
+ "@tootallnate/once@<3.0.1": ">=3.0.1",
128
+ "flatted": "^3.4.2"
128
129
  }
129
130
  }
130
131
  }