@gooddata/sdk-ui-filters 11.39.0-alpha.3 → 11.39.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/esm/FilterGroup/FilterGroup.js +1 -1
- package/esm/MeasureValueFilter/Dropdown.d.ts +3 -0
- package/esm/MeasureValueFilter/Dropdown.js +12 -4
- package/esm/MeasureValueFilter/DropdownBody.d.ts +1 -0
- package/esm/MeasureValueFilter/DropdownBody.js +18 -9
- package/esm/MeasureValueFilter/MeasureValueFilter.js +17 -2
- package/esm/MeasureValueFilter/MeasureValueFilterDropdown.d.ts +11 -0
- package/esm/MeasureValueFilter/MeasureValueFilterDropdown.js +2 -2
- package/esm/MeasureValueFilter/OperatorDropdown.d.ts +1 -0
- package/esm/MeasureValueFilter/OperatorDropdown.js +1 -1
- package/esm/MeasureValueFilter/OperatorDropdownBody.d.ts +1 -0
- package/esm/MeasureValueFilter/OperatorDropdownBody.js +47 -7
- package/esm/MeasureValueFilter/OperatorDropdownItem.d.ts +1 -0
- package/esm/MeasureValueFilter/OperatorDropdownItem.js +2 -3
- package/esm/MeasureValueFilter/TreatNullValuesAsZeroCheckbox.d.ts +2 -1
- package/esm/MeasureValueFilter/TreatNullValuesAsZeroCheckbox.js +3 -4
- package/esm/MeasureValueFilter/typings.d.ts +12 -0
- package/esm/internal.d.ts +2 -0
- package/esm/internal.js +1 -0
- package/esm/sdk-ui-filters.d.ts +22 -0
- package/package.json +12 -12
- package/styles/css/filterGroup.css +1 -0
- package/styles/css/filterGroup.css.map +1 -1
- package/styles/css/main.css +192 -0
- package/styles/css/main.css.map +1 -1
- package/styles/css/measureValueFilter.css +191 -0
- package/styles/css/measureValueFilter.css.map +1 -1
- package/styles/scss/filterGroup.scss +1 -0
- package/styles/scss/measureValueFilter.scss +245 -0
|
@@ -203,7 +203,7 @@ export function FilterGroup(props) {
|
|
|
203
203
|
ariaLabel: groupAriaLabel,
|
|
204
204
|
}, renderItem: renderItem, onKeyDownSelect: handleItemKeyboardAction, closeDropdown: closeDropdown, isMobile: isMobile }) })), [filters, renderItem, handleKeyDown, handleKeyDownCapture, handleItemKeyboardAction, groupAriaLabel]);
|
|
205
205
|
const isMobile = useMediaQuery("mobileDevice");
|
|
206
|
-
const renderButton = useCallback(({ toggleDropdown, isOpen, buttonRef, dropdownId }) => (_jsx("div", { className: cx({ "gd-is-mobile": isMobile && isOpen }), children: _jsx(AttributeFilterDropdownButton, { title: title, subtitle: subtitle, isLoaded: !isAnyFilterError, isOpen: isOpen, selectedItemsCount: selectedItemsCount, totalItemsCount: totalItemsCount, showSelectionCount: selectedItemsCount !== undefined || totalItemsCount !== undefined, icon: _jsx(UiIcon, { type: "
|
|
206
|
+
const renderButton = useCallback(({ toggleDropdown, isOpen, buttonRef, dropdownId }) => (_jsx("div", { className: cx({ "gd-is-mobile": isMobile && isOpen }), children: _jsx(AttributeFilterDropdownButton, { title: title, subtitle: subtitle, isLoaded: !isAnyFilterError, isOpen: isOpen, selectedItemsCount: selectedItemsCount, totalItemsCount: totalItemsCount, showSelectionCount: selectedItemsCount !== undefined || totalItemsCount !== undefined, icon: _jsx(UiIcon, { type: "folderSmall", size: 12, color: "complementary-6" }), dropdownId: dropdownId, buttonRef: buttonRef, onClick: toggleDropdown, isError: isAnyFilterError, ariaLabel: groupAriaLabelWithState }) })), [
|
|
207
207
|
title,
|
|
208
208
|
subtitle,
|
|
209
209
|
isAnyFilterError,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
1
2
|
import { type IMeasureMetadataObject, type MeasureValueFilterCondition, type ObjRefInScope } from "@gooddata/sdk-model";
|
|
2
3
|
import { type ISeparators } from "@gooddata/sdk-ui";
|
|
3
4
|
import { type IAlignPoint } from "@gooddata/sdk-ui-kit";
|
|
@@ -35,6 +36,8 @@ interface IDropdownProps extends IMeasureValueFilterCustomComponentProps {
|
|
|
35
36
|
loadMetricDetails?: () => Promise<IMeasureMetadataObject | undefined>;
|
|
36
37
|
isHeaderEnabled?: boolean;
|
|
37
38
|
alignPoints?: IAlignPoint[];
|
|
39
|
+
fullscreenOnMobile?: boolean;
|
|
40
|
+
mobileHeader?: ReactNode;
|
|
38
41
|
}
|
|
39
42
|
export declare function Dropdown(props: IDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
40
43
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2019-2026 GoodData Corporation
|
|
3
3
|
import { memo, useCallback } from "react";
|
|
4
4
|
import { IntlWrapper } from "@gooddata/sdk-ui";
|
|
5
|
-
import { Overlay, UiFocusManager } from "@gooddata/sdk-ui-kit";
|
|
5
|
+
import { FullScreenOverlay, Overlay, UiFocusManager, useMediaQuery, } from "@gooddata/sdk-ui-kit";
|
|
6
6
|
import { DropdownBody } from "./DropdownBody.js";
|
|
7
7
|
const alignPoints = ["bl tl", "tl bl", "br tr", "tr br"];
|
|
8
8
|
/*
|
|
@@ -11,13 +11,21 @@ const alignPoints = ["bl tl", "tl bl", "br tr", "tr br"];
|
|
|
11
11
|
* thin layer on top of goodstrap (?)
|
|
12
12
|
*/
|
|
13
13
|
const DROPDOWN_ALIGNMENTS = alignPoints.map((align) => ({ align, offset: { x: 1, y: 0 } }));
|
|
14
|
+
const MOBILE_DROPDOWN_ALIGN_POINTS = [{ align: "tl tl" }];
|
|
14
15
|
const DropdownWithIntl = memo(function DropdownWithIntl(props) {
|
|
15
|
-
const { operator = "ALL", usePercentage, warningMessage, locale, onCancel, anchorEl, separators, format, useShortFormat, measureTitle, displayTreatNullAsZeroOption = false, treatNullAsZeroValue = false, enableOperatorSelection, onApply: onApplyProp, onChange: onChangeProp, withoutApply, BodyComponent, DropdownActionsComponent, dimensionality, insightDimensionality, isDimensionalityEnabled, isFilterSummaryEnabled = true, catalogDimensionality, loadCatalogDimensionality, onDimensionalityChange, isLoadingCatalogDimensionality, conditions = [], enableMultipleConditions = false, enableRankingWithMvf, applyOnResult, loadMetricDetails, isHeaderEnabled, alignPoints, } = props;
|
|
16
|
+
const { operator = "ALL", usePercentage, warningMessage, locale, onCancel, anchorEl, separators, format, useShortFormat, measureTitle, displayTreatNullAsZeroOption = false, treatNullAsZeroValue = false, enableOperatorSelection, onApply: onApplyProp, onChange: onChangeProp, withoutApply, BodyComponent, DropdownActionsComponent, dimensionality, insightDimensionality, isDimensionalityEnabled, isFilterSummaryEnabled = true, catalogDimensionality, loadCatalogDimensionality, onDimensionalityChange, isLoadingCatalogDimensionality, conditions = [], enableMultipleConditions = false, enableRankingWithMvf, applyOnResult, loadMetricDetails, isHeaderEnabled, alignPoints, fullscreenOnMobile, mobileHeader, } = props;
|
|
17
|
+
const isMobile = useMediaQuery("mobileDevice");
|
|
18
|
+
const useFullScreen = !!fullscreenOnMobile && isMobile;
|
|
16
19
|
const onApply = useCallback((conditions, newDimensionality, applyOnResult) => {
|
|
17
20
|
onApplyProp(conditions, newDimensionality, applyOnResult);
|
|
18
21
|
}, [onApplyProp]);
|
|
19
22
|
const selectedOperator = operator === null ? "ALL" : operator;
|
|
20
|
-
|
|
23
|
+
const body = (_jsx(UiFocusManager, { enableFocusTrap: true, enableAutofocus: true, enableReturnFocusOnUnmount: true, children: _jsx(DropdownBody, { operator: selectedOperator, conditions: conditions, enableMultipleConditions: enableMultipleConditions, usePercentage: usePercentage, warningMessage: warningMessage, locale: locale, onChange: onChangeProp, withoutApply: withoutApply, BodyComponent: BodyComponent, DropdownActionsComponent: DropdownActionsComponent, onCancel: onCancel, onApply: onApply, separators: separators, format: format, useShortFormat: useShortFormat, measureTitle: measureTitle, displayTreatNullAsZeroOption: displayTreatNullAsZeroOption, treatNullAsZeroValue: treatNullAsZeroValue, enableOperatorSelection: enableOperatorSelection, dimensionality: dimensionality, insightDimensionality: insightDimensionality, isDimensionalityEnabled: isDimensionalityEnabled, isFilterSummaryEnabled: isFilterSummaryEnabled, catalogDimensionality: catalogDimensionality, loadCatalogDimensionality: loadCatalogDimensionality, onDimensionalityChange: onDimensionalityChange, isLoadingCatalogDimensionality: isLoadingCatalogDimensionality, enableRankingWithMvf: enableRankingWithMvf, applyOnResult: applyOnResult, loadMetricDetails: loadMetricDetails, isHeaderEnabled: isHeaderEnabled, isMobile: useFullScreen }) }));
|
|
24
|
+
if (useFullScreen) {
|
|
25
|
+
return (_jsx(FullScreenOverlay, { alignTo: "body", alignPoints: MOBILE_DROPDOWN_ALIGN_POINTS, onClose: onCancel, children: _jsxs("div", { className: "gd-mobile-dropdown-overlay overlay gd-flex-row-container gd-mvf-mobile-dropdown", children: [mobileHeader ? (_jsx("div", { className: "gd-mobile-dropdown-header gd-flex-item gd-mvf-mobile-dropdown-header gd-is-mobile", children: mobileHeader })) : null, _jsx("div", { className: "gd-mobile-dropdown-content gd-flex-item-stretch gd-flex-row-container gd-mvf-mobile-dropdown-content", children: body })
|
|
26
|
+
] }) }));
|
|
27
|
+
}
|
|
28
|
+
return (_jsx(Overlay, { alignTo: anchorEl, alignPoints: alignPoints ?? DROPDOWN_ALIGNMENTS, closeOnOutsideClick: true, closeOnParentScroll: true, closeOnMouseDrag: true, onClose: onCancel, children: body }));
|
|
21
29
|
});
|
|
22
30
|
export function Dropdown(props) {
|
|
23
31
|
return (_jsx(IntlWrapper, { locale: props.locale, children: _jsx(DropdownWithIntl, { ...props }) }));
|
|
@@ -33,6 +33,7 @@ interface IDropdownBodyProps extends IMeasureValueFilterCustomComponentProps {
|
|
|
33
33
|
isLoadingCatalogDimensionality?: boolean;
|
|
34
34
|
loadMetricDetails?: () => Promise<IMeasureMetadataObject | undefined>;
|
|
35
35
|
isHeaderEnabled?: boolean;
|
|
36
|
+
isMobile?: boolean;
|
|
36
37
|
}
|
|
37
38
|
export declare const DropdownBodyWithIntl: import("react").NamedExoticComponent<IDropdownBodyProps>;
|
|
38
39
|
export declare const DropdownBody: import("react").NamedExoticComponent<IDropdownBodyProps>;
|
|
@@ -18,6 +18,19 @@ import { TreatNullValuesAsZeroCheckbox } from "./TreatNullValuesAsZeroCheckbox.j
|
|
|
18
18
|
import { WarningMessageComponent } from "./WarningMessage.js";
|
|
19
19
|
const DefaultValuePrecision = 6;
|
|
20
20
|
const ALIGN_POINTS = [{ align: "cr cl" }];
|
|
21
|
+
/**
|
|
22
|
+
* Plus / cross button next to a condition row. On mobile, skip the hover tooltip wrapper —
|
|
23
|
+
* tooltips aren't usable on touch and the Bubble's internal Overlay caused a re-positioning
|
|
24
|
+
* feedback loop when a new condition row was inserted into the fullscreen overlay.
|
|
25
|
+
*/
|
|
26
|
+
function ConditionActionButton({ icon, isMobile, isDisabled, isDestructive, onClick, dataTestId, label, tooltip, }) {
|
|
27
|
+
const button = (_jsx(UiIconButton, { icon: icon, size: isMobile ? "medium" : "small", variant: "tertiary", isDisabled: isDisabled, isDesctructive: isDestructive, onClick: onClick, dataTestId: dataTestId, label: label }));
|
|
28
|
+
if (isMobile) {
|
|
29
|
+
return button;
|
|
30
|
+
}
|
|
31
|
+
return (_jsxs(BubbleHoverTrigger, { children: [button, _jsx(Bubble, { alignPoints: ALIGN_POINTS, children: tooltip })
|
|
32
|
+
] }));
|
|
33
|
+
}
|
|
21
34
|
const toFormCondition = (condition) => {
|
|
22
35
|
if (isComparisonCondition(condition)) {
|
|
23
36
|
return {
|
|
@@ -539,21 +552,17 @@ export const DropdownBodyWithIntl = memo(function DropdownBodyWithIntl(props) {
|
|
|
539
552
|
isCommitPending.current = true;
|
|
540
553
|
setApplyOnResult(event.target.checked);
|
|
541
554
|
}, [setApplyOnResult]);
|
|
542
|
-
return (_jsxs("div", { className:
|
|
555
|
+
return (_jsxs("div", { className: cx(MEASURE_VALUE_FILTER_DROPDOWN_BODY_CLASS, "gd-dialog gd-dropdown overlay s-mvf-dropdown-body", { "gd-is-mobile": props.isMobile }), "data-testid": "mvf-dropdown-body", children: [props.isHeaderEnabled && props.measureTitle && !props.isMobile ? (_jsx(MeasureValueFilterDropdownHeader, { title: props.measureTitle, loadMetricDetails: props.loadMetricDetails })) : null, _jsx("div", { className: "gd-mvf-dropdown-content", children: BodyComponent ? (_jsx(BodyComponent, { onApplyButtonClick: onApply, onCancelButtonClick: onCancel ?? (() => undefined) })) : (_jsxs(_Fragment, { children: [warningMessage ? (_jsx("div", { className: "gd-mvf-dropdown-section", children: _jsx(WarningMessageComponent, { warningMessage: warningMessage }) })) : null, _jsxs("div", { className: "gd-mvf-conditions-scroll-container", children: [(enableMultipleConditions ? state.conditions : state.conditions.slice(0, 1)).map((c, idx) => (_jsxs("div", { className: cx("gd-mvf-dropdown-section", "gd-mvf-condition-section", {
|
|
543
556
|
"gd-mvf-condition-section--multi": enableMultipleConditions,
|
|
544
557
|
}), children: [
|
|
545
558
|
_jsxs("div", { className: "gd-mvf-condition-header", "data-testid": `mvf-condition-${idx}`, children: [
|
|
546
|
-
_jsx("div", { className: "gd-mvf-condition-operator", children: _jsx(OperatorDropdown, { onSelect: (op) => handleOperatorSelection(idx, op), operator: c.operator, isDisabled: !enableOperatorSelection, isAllOperatorDisabled: isAllOperatorDisabled }) }), enableMultipleConditions ? (_jsx("div", { className: "gd-mvf-condition-action", children: idx === 0 ? (
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
: addConditionTooltip })
|
|
550
|
-
] })) : (_jsxs(BubbleHoverTrigger, { children: [
|
|
551
|
-
_jsx(UiIconButton, { icon: "cross", size: "small", variant: "tertiary", isDesctructive: true, onClick: () => handleRemoveCondition(idx), dataTestId: `mvf-remove-condition-${idx}`, label: removeConditionTooltip }), _jsx(Bubble, { alignPoints: ALIGN_POINTS, children: removeConditionTooltip })
|
|
552
|
-
] })) })) : null] }), c.operator === "ALL" ? null : (_jsxs("div", { className: "gd-mvf-condition-inputs", children: [
|
|
559
|
+
_jsx("div", { className: "gd-mvf-condition-operator", children: _jsx(OperatorDropdown, { onSelect: (op) => handleOperatorSelection(idx, op), operator: c.operator, isDisabled: !enableOperatorSelection, isAllOperatorDisabled: isAllOperatorDisabled, isMobile: props.isMobile }) }), enableMultipleConditions ? (_jsx("div", { className: "gd-mvf-condition-action", children: idx === 0 ? (_jsx(ConditionActionButton, { icon: "plus", isMobile: props.isMobile, isDisabled: isAddConditionDisabled, onClick: handleAddCondition, dataTestId: "mvf-add-condition", label: addConditionTooltip, tooltip: isAddConditionDisabled
|
|
560
|
+
? addConditionDisabledTooltip
|
|
561
|
+
: addConditionTooltip })) : (_jsx(ConditionActionButton, { icon: "cross", isMobile: props.isMobile, isDestructive: true, onClick: () => handleRemoveCondition(idx), dataTestId: `mvf-remove-condition-${idx}`, label: removeConditionTooltip, tooltip: removeConditionTooltip })) })) : null] }), c.operator === "ALL" ? null : (_jsxs("div", { className: "gd-mvf-condition-inputs", children: [
|
|
553
562
|
_jsx(ConditionInputSection, { index: idx, condition: c, usePercentage: props.usePercentage ?? false, baseDisableAutofocus: props.disableAutofocus, separators: props.separators, onValueChange: handleValueChange, onFromChange: handleFromChange, onToChange: handleToChange, onValueBlur: handleValueBlur, onFromBlur: handleFromBlur, onToBlur: handleToBlur, onApply: onApply }), idx ===
|
|
554
563
|
(enableMultipleConditions
|
|
555
564
|
? state.conditions.length - 1
|
|
556
|
-
: 0) && shouldShowTreatNullAsZeroCheckbox ? (_jsx(TreatNullValuesAsZeroCheckbox, { onChange: handleTreatNullAsZeroClicked, checked: enabledTreatNullValuesAsZero, intl: intl })) : null, idx ===
|
|
565
|
+
: 0) && shouldShowTreatNullAsZeroCheckbox ? (_jsx(TreatNullValuesAsZeroCheckbox, { onChange: handleTreatNullAsZeroClicked, checked: enabledTreatNullValuesAsZero, isMobile: props.isMobile, intl: intl })) : null, idx ===
|
|
557
566
|
(enableMultipleConditions
|
|
558
567
|
? state.conditions.length - 1
|
|
559
568
|
: 0) && enableRankingWithMvf ? (_jsxs("label", { className: "input-checkbox-label gd-mvf-apply-on-result-checkbox", "data-testid": "mvf-apply-on-result", children: [
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2020-2026 GoodData Corporation
|
|
3
3
|
import { Fragment, memo, useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { useMediaQuery } from "@gooddata/sdk-ui-kit";
|
|
4
5
|
import { DropdownButton } from "./MeasureValueFilterButton.js";
|
|
5
6
|
import { MeasureValueFilterDropdown } from "./MeasureValueFilterDropdown.js";
|
|
6
7
|
/**
|
|
7
8
|
* @beta
|
|
8
9
|
*/
|
|
9
|
-
export const MeasureValueFilter = memo(function MeasureValueFilter({ onCancel = () => { }, filter, measureIdentifier, buttonTitle, buttonSubtitle, buttonTitleExtension, buttonDisabled, measureTitle, usePercentage, warningMessage, locale, separators, format, useShortFormat, displayTreatNullAsZeroOption, treatNullAsZeroDefaultValue, enableOperatorSelection, dimensionality, insightDimensionality, isDimensionalityEnabled, isFilterSummaryEnabled, catalogDimensionality, loadCatalogDimensionality, onDimensionalityChange, isLoadingCatalogDimensionality, withoutApply, BodyComponent, DropdownActionsComponent, enableMultipleConditions = false, enableRankingWithMvf, onApply, DropdownButtonComponent = DropdownButton, autoOpen, loadMetricDetails, isHeaderEnabled, onChange, alignPoints, }) {
|
|
10
|
+
export const MeasureValueFilter = memo(function MeasureValueFilter({ onCancel = () => { }, filter, measureIdentifier, buttonTitle, buttonSubtitle, buttonTitleExtension, buttonDisabled, measureTitle, usePercentage, warningMessage, locale, separators, format, useShortFormat, displayTreatNullAsZeroOption, treatNullAsZeroDefaultValue, enableOperatorSelection, dimensionality, insightDimensionality, isDimensionalityEnabled, isFilterSummaryEnabled, catalogDimensionality, loadCatalogDimensionality, onDimensionalityChange, isLoadingCatalogDimensionality, withoutApply, BodyComponent, DropdownActionsComponent, enableMultipleConditions = false, enableRankingWithMvf, onApply, DropdownButtonComponent = DropdownButton, autoOpen, loadMetricDetails, isHeaderEnabled, onChange, alignPoints, fullscreenOnMobile, }) {
|
|
10
11
|
const [displayDropdown, setDisplayDropdown] = useState(false);
|
|
11
12
|
const buttonRef = useRef(null);
|
|
12
13
|
const autoOpenedRef = useRef(false);
|
|
14
|
+
const isMobile = useMediaQuery("mobileDevice");
|
|
15
|
+
const useFullScreen = !!fullscreenOnMobile && isMobile;
|
|
13
16
|
useEffect(() => {
|
|
14
17
|
if (autoOpen && !autoOpenedRef.current) {
|
|
15
18
|
autoOpenedRef.current = true;
|
|
@@ -30,6 +33,18 @@ export const MeasureValueFilter = memo(function MeasureValueFilter({ onCancel =
|
|
|
30
33
|
const toggleDropdown = useCallback(() => {
|
|
31
34
|
setDisplayDropdown((state) => !state);
|
|
32
35
|
}, []);
|
|
36
|
+
const renderDropdownButton = useCallback((onClickHandler) => (_jsx(DropdownButtonComponent, { onClick: onClickHandler, isActive: displayDropdown, buttonTitle: buttonTitle, buttonSubtitle: buttonSubtitle, buttonTitleExtension: buttonTitleExtension, disabled: buttonDisabled })), [
|
|
37
|
+
DropdownButtonComponent,
|
|
38
|
+
buttonDisabled,
|
|
39
|
+
buttonSubtitle,
|
|
40
|
+
buttonTitle,
|
|
41
|
+
buttonTitleExtension,
|
|
42
|
+
displayDropdown,
|
|
43
|
+
]);
|
|
33
44
|
return (_jsxs(Fragment, { children: [
|
|
34
|
-
_jsx("div", { ref: buttonRef, children:
|
|
45
|
+
_jsx("div", { ref: buttonRef, children: renderDropdownButton(toggleDropdown) }), displayDropdown ? (_jsx(MeasureValueFilterDropdown, { onApply: handleApply, onChange: onChange, withoutApply: withoutApply, BodyComponent: BodyComponent, DropdownActionsComponent: DropdownActionsComponent, onCancel: handleCancel, filter: filter, measureIdentifier: measureIdentifier, measureTitle: measureTitle, usePercentage: usePercentage, warningMessage: warningMessage, locale: locale, separators: separators, format: format, useShortFormat: useShortFormat, displayTreatNullAsZeroOption: displayTreatNullAsZeroOption, treatNullAsZeroDefaultValue: treatNullAsZeroDefaultValue, enableOperatorSelection: enableOperatorSelection, dimensionality: dimensionality, insightDimensionality: insightDimensionality, isDimensionalityEnabled: isDimensionalityEnabled, isFilterSummaryEnabled: isFilterSummaryEnabled, catalogDimensionality: catalogDimensionality, loadCatalogDimensionality: loadCatalogDimensionality, onDimensionalityChange: onDimensionalityChange, isLoadingCatalogDimensionality: isLoadingCatalogDimensionality, enableMultipleConditions: enableMultipleConditions, enableRankingWithMvf: enableRankingWithMvf, anchorEl: buttonRef.current ?? undefined, loadMetricDetails: loadMetricDetails, isHeaderEnabled: isHeaderEnabled, alignPoints: alignPoints, fullscreenOnMobile: fullscreenOnMobile,
|
|
46
|
+
// Mobile header is the same visual button but dismisses via handleCancel
|
|
47
|
+
// so host onCancel cleanup (e.g. closing the configuration panel,
|
|
48
|
+
// clearing autoOpen) runs — toggleDropdown would skip that path.
|
|
49
|
+
mobileHeader: useFullScreen ? renderDropdownButton(handleCancel) : undefined })) : null] }));
|
|
35
50
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
1
2
|
import { type IMeasureValueFilterCommonProps } from "./typings.js";
|
|
2
3
|
/**
|
|
3
4
|
* @beta
|
|
@@ -5,6 +6,16 @@ import { type IMeasureValueFilterCommonProps } from "./typings.js";
|
|
|
5
6
|
export interface IMeasureValueFilterDropdownProps extends IMeasureValueFilterCommonProps {
|
|
6
7
|
onCancel: () => void;
|
|
7
8
|
anchorEl?: HTMLElement | string;
|
|
9
|
+
/**
|
|
10
|
+
* Element rendered at the top of the dropdown overlay when displayed in fullscreen mobile mode.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Typically the host's dropdown button — composed by the parent {@link MeasureValueFilter}
|
|
14
|
+
* so the trigger appears as the overlay header on small viewports.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
mobileHeader?: ReactNode;
|
|
8
19
|
}
|
|
9
20
|
/**
|
|
10
21
|
* @beta
|
|
@@ -21,7 +21,7 @@ const getTreatNullAsZeroValue = (filter, treatNullAsZeroDefaultValue, enableMult
|
|
|
21
21
|
/**
|
|
22
22
|
* @beta
|
|
23
23
|
*/
|
|
24
|
-
export const MeasureValueFilterDropdown = memo(function MeasureValueFilterDropdown({ filter, onCancel, onApply, onChange, withoutApply, BodyComponent, DropdownActionsComponent, measureIdentifier, measureTitle, usePercentage, warningMessage, locale, anchorEl, separators, format, useShortFormat, displayTreatNullAsZeroOption = false, treatNullAsZeroDefaultValue = false, enableOperatorSelection = true, dimensionality, insightDimensionality, isDimensionalityEnabled, isFilterSummaryEnabled, catalogDimensionality, loadCatalogDimensionality, onDimensionalityChange, isLoadingCatalogDimensionality, enableMultipleConditions = false, enableRankingWithMvf, loadMetricDetails, isHeaderEnabled, alignPoints, }) {
|
|
24
|
+
export const MeasureValueFilterDropdown = memo(function MeasureValueFilterDropdown({ filter, onCancel, onApply, onChange, withoutApply, BodyComponent, DropdownActionsComponent, measureIdentifier, measureTitle, usePercentage, warningMessage, locale, anchorEl, separators, format, useShortFormat, displayTreatNullAsZeroOption = false, treatNullAsZeroDefaultValue = false, enableOperatorSelection = true, dimensionality, insightDimensionality, isDimensionalityEnabled, isFilterSummaryEnabled, catalogDimensionality, loadCatalogDimensionality, onDimensionalityChange, isLoadingCatalogDimensionality, enableMultipleConditions = false, enableRankingWithMvf, loadMetricDetails, isHeaderEnabled, alignPoints, fullscreenOnMobile, mobileHeader, }) {
|
|
25
25
|
const applyOnResult = filter?.measureValueFilter.applyOnResult;
|
|
26
26
|
const buildFilter = useCallback((conditions, newDimensionality, applyOnResult) => {
|
|
27
27
|
const effectiveConditions = enableMultipleConditions ? conditions : conditions?.slice(0, 1);
|
|
@@ -79,5 +79,5 @@ export const MeasureValueFilterDropdown = memo(function MeasureValueFilterDropdo
|
|
|
79
79
|
const handleChange = useCallback((conditions, newDimensionality, applyOnResult) => {
|
|
80
80
|
onChange?.(buildFilter(conditions, newDimensionality, applyOnResult));
|
|
81
81
|
}, [onChange, buildFilter]);
|
|
82
|
-
return (_jsx(Dropdown, { onApply: handleApply, onChange: onChange ? handleChange : undefined, withoutApply: withoutApply, BodyComponent: BodyComponent, DropdownActionsComponent: DropdownActionsComponent, onCancel: onCancel, operator: (filter && measureValueFilterOperator(filter)) || null, conditions: getConditionsFromFilter(filter, enableMultipleConditions), usePercentage: usePercentage, warningMessage: warningMessage, locale: locale, anchorEl: anchorEl, separators: separators, format: format, useShortFormat: useShortFormat, measureTitle: measureTitle, displayTreatNullAsZeroOption: displayTreatNullAsZeroOption, treatNullAsZeroValue: getTreatNullAsZeroValue(filter, treatNullAsZeroDefaultValue, enableMultipleConditions), enableOperatorSelection: enableOperatorSelection, dimensionality: dimensionality, insightDimensionality: insightDimensionality, isDimensionalityEnabled: isDimensionalityEnabled, isFilterSummaryEnabled: isFilterSummaryEnabled, catalogDimensionality: catalogDimensionality, loadCatalogDimensionality: loadCatalogDimensionality, onDimensionalityChange: onDimensionalityChange, isLoadingCatalogDimensionality: isLoadingCatalogDimensionality, enableMultipleConditions: enableMultipleConditions, enableRankingWithMvf: enableRankingWithMvf, applyOnResult: applyOnResult, loadMetricDetails: loadMetricDetails, isHeaderEnabled: isHeaderEnabled, alignPoints: alignPoints }));
|
|
82
|
+
return (_jsx(Dropdown, { onApply: handleApply, onChange: onChange ? handleChange : undefined, withoutApply: withoutApply, BodyComponent: BodyComponent, DropdownActionsComponent: DropdownActionsComponent, onCancel: onCancel, operator: (filter && measureValueFilterOperator(filter)) || null, conditions: getConditionsFromFilter(filter, enableMultipleConditions), usePercentage: usePercentage, warningMessage: warningMessage, locale: locale, anchorEl: anchorEl, separators: separators, format: format, useShortFormat: useShortFormat, measureTitle: measureTitle, displayTreatNullAsZeroOption: displayTreatNullAsZeroOption, treatNullAsZeroValue: getTreatNullAsZeroValue(filter, treatNullAsZeroDefaultValue, enableMultipleConditions), enableOperatorSelection: enableOperatorSelection, dimensionality: dimensionality, insightDimensionality: insightDimensionality, isDimensionalityEnabled: isDimensionalityEnabled, isFilterSummaryEnabled: isFilterSummaryEnabled, catalogDimensionality: catalogDimensionality, loadCatalogDimensionality: loadCatalogDimensionality, onDimensionalityChange: onDimensionalityChange, isLoadingCatalogDimensionality: isLoadingCatalogDimensionality, enableMultipleConditions: enableMultipleConditions, enableRankingWithMvf: enableRankingWithMvf, applyOnResult: applyOnResult, loadMetricDetails: loadMetricDetails, isHeaderEnabled: isHeaderEnabled, alignPoints: alignPoints, fullscreenOnMobile: fullscreenOnMobile, mobileHeader: mobileHeader }));
|
|
83
83
|
});
|
|
@@ -4,6 +4,7 @@ interface IOperatorDropdownProps {
|
|
|
4
4
|
operator: MeasureValueFilterOperator;
|
|
5
5
|
isDisabled?: boolean;
|
|
6
6
|
isAllOperatorDisabled?: boolean;
|
|
7
|
+
isMobile?: boolean;
|
|
7
8
|
}
|
|
8
9
|
export declare const OperatorDropdown: import("react").NamedExoticComponent<IOperatorDropdownProps>;
|
|
9
10
|
export {};
|
|
@@ -32,5 +32,5 @@ export const OperatorDropdown = memo(function OperatorDropdown(props) {
|
|
|
32
32
|
const handleOperatorDropdownButtonClick = () => setOpened((state) => !state);
|
|
33
33
|
return (_jsxs(_Fragment, { children: [
|
|
34
34
|
_jsxs("div", { className: "gd-mvf-operator-dropdown", "data-testid": "mvf-operator-section", children: [
|
|
35
|
-
_jsx("div", { className: "gd-mvf-operator-dropdown-label", children: intl.formatMessage({ id: "mvf.condition" }) }), renderDropdownButton()] }), opened ? (_jsx(OperatorDropdownBody, { alignTo: ".gd-mvf-operator-dropdown-button", onSelect: handleOperatorSelected, selectedOperator: props.operator, onClose: closeOperatorDropdown, isAllOperatorDisabled: props.isAllOperatorDisabled })) : null] }));
|
|
35
|
+
_jsx("div", { className: "gd-mvf-operator-dropdown-label", children: intl.formatMessage({ id: "mvf.condition" }) }), renderDropdownButton()] }), opened ? (_jsx(OperatorDropdownBody, { alignTo: ".gd-mvf-operator-dropdown-button", onSelect: handleOperatorSelected, selectedOperator: props.operator, onClose: closeOperatorDropdown, isAllOperatorDisabled: props.isAllOperatorDisabled, isMobile: props.isMobile })) : null] }));
|
|
36
36
|
});
|
|
@@ -1,16 +1,56 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2019-2026 GoodData Corporation
|
|
3
|
-
import { memo } from "react";
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import { Fragment, memo } from "react";
|
|
4
|
+
import cx from "classnames";
|
|
5
|
+
import { capitalize } from "lodash-es";
|
|
6
|
+
import { defineMessages, useIntl } from "react-intl";
|
|
7
|
+
import { FullScreenOverlay, Overlay, Separator } from "@gooddata/sdk-ui-kit";
|
|
6
8
|
import { MEASURE_VALUE_FILTER_OPERATOR_DROPDOWN_BODY_CLASS } from "./constants.js";
|
|
9
|
+
import { getOperatorTranslationKey } from "./helpers/measureValueFilterOperator.js";
|
|
7
10
|
import { OperatorDropdownItem } from "./OperatorDropdownItem.js";
|
|
8
|
-
|
|
11
|
+
const MOBILE_DROPDOWN_ALIGN_POINTS = [{ align: "tl tl" }];
|
|
12
|
+
// Operators grouped as they appear in the picker; a Separator is rendered between groups
|
|
13
|
+
// (desktop only — mobile rows already carry a bottom divider).
|
|
14
|
+
const OPERATOR_GROUPS = [
|
|
15
|
+
["ALL"],
|
|
16
|
+
["GREATER_THAN", "GREATER_THAN_OR_EQUAL_TO"],
|
|
17
|
+
["LESS_THAN", "LESS_THAN_OR_EQUAL_TO"],
|
|
18
|
+
["BETWEEN", "NOT_BETWEEN"],
|
|
19
|
+
["EQUAL_TO", "NOT_EQUAL_TO"],
|
|
20
|
+
];
|
|
21
|
+
// Operators that surface an explanatory hover bubble next to their label.
|
|
22
|
+
// Declared via `defineMessages` so static i18n analysis (e.g. i18n-toolkit) sees these IDs
|
|
23
|
+
// as referenced and validates their presence in translation bundles — a plain `string` map
|
|
24
|
+
// is invisible to the extractor because it never reaches an `intl.formatMessage({ id })` call site.
|
|
25
|
+
const bubbleMessages = defineMessages({
|
|
26
|
+
BETWEEN: { id: "mvf.operator.between.tooltip.bubble" },
|
|
27
|
+
NOT_BETWEEN: { id: "mvf.operator.notBetween.tooltip.bubble" },
|
|
28
|
+
});
|
|
29
|
+
const OPERATOR_BUBBLE_MESSAGES = {
|
|
30
|
+
BETWEEN: bubbleMessages.BETWEEN,
|
|
31
|
+
NOT_BETWEEN: bubbleMessages.NOT_BETWEEN,
|
|
32
|
+
};
|
|
33
|
+
export const OperatorDropdownBody = memo(function OperatorDropdownBody({ onSelect, onClose, selectedOperator, alignTo, isAllOperatorDisabled = false, isMobile = false, }) {
|
|
9
34
|
const intl = useIntl();
|
|
10
35
|
const allOperatorDisabledTooltip = isAllOperatorDisabled
|
|
11
36
|
? intl.formatMessage({ id: "mvf.operator.all.disabled.tooltip" })
|
|
12
37
|
: undefined;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
38
|
+
const selectedOperatorTranslationKey = getOperatorTranslationKey(selectedOperator);
|
|
39
|
+
const selectedOperatorTitle = capitalize(selectedOperatorTranslationKey === undefined
|
|
40
|
+
? selectedOperator
|
|
41
|
+
: intl.formatMessage({ id: selectedOperatorTranslationKey }));
|
|
42
|
+
const items = (_jsx("div", { className: cx(MEASURE_VALUE_FILTER_OPERATOR_DROPDOWN_BODY_CLASS, "s-mvf-operator-dropdown-body", {
|
|
43
|
+
"gd-is-mobile": isMobile,
|
|
44
|
+
}), "data-testid": "mvf-operator-dropdown-body", children: OPERATOR_GROUPS.map((group, groupIdx) => (_jsxs(Fragment, { children: [groupIdx > 0 && !isMobile ? _jsx(Separator, {}) : null, group.map((operator) => {
|
|
45
|
+
const bubbleMessage = OPERATOR_BUBBLE_MESSAGES[operator];
|
|
46
|
+
return (_jsx(OperatorDropdownItem, { operator: operator, selectedOperator: selectedOperator, onClick: onSelect, bubbleText: bubbleMessage ? intl.formatMessage(bubbleMessage) : undefined, isDisabled: operator === "ALL" ? isAllOperatorDisabled : undefined, disabledTooltip: operator === "ALL" ? allOperatorDisabledTooltip : undefined, isMobile: isMobile }, operator));
|
|
47
|
+
})] }, groupIdx))) }));
|
|
48
|
+
if (isMobile) {
|
|
49
|
+
return (_jsx(FullScreenOverlay, { alignTo: "body", alignPoints: MOBILE_DROPDOWN_ALIGN_POINTS, onClose: onClose, children: _jsxs("div", { className: "gd-mobile-dropdown-overlay overlay gd-flex-row-container gd-mvf-mobile-dropdown", children: [
|
|
50
|
+
_jsx("div", { className: "gd-mobile-dropdown-header gd-flex-item gd-mvf-mobile-dropdown-header", children: _jsxs("button", { type: "button", className: "gd-mvf-operator-mobile-header s-mvf-operator-mobile-header", onClick: onClose, children: [
|
|
51
|
+
_jsx("span", { className: "gd-mvf-operator-mobile-header__label", children: intl.formatMessage({ id: "mvf.condition" }) }), _jsx("span", { className: "gd-mvf-operator-mobile-header__value", children: selectedOperatorTitle }), _jsx("span", { className: "gd-mvf-operator-mobile-header__chevron gd-icon-navigateup" })
|
|
52
|
+
] }) }), _jsx("div", { className: "gd-mobile-dropdown-content gd-flex-item-stretch gd-mvf-mobile-dropdown-content", children: items })
|
|
53
|
+
] }) }));
|
|
54
|
+
}
|
|
55
|
+
return (_jsx(Overlay, { closeOnOutsideClick: true, alignTo: alignTo, alignPoints: [{ align: "bl tl" }], onClose: onClose, children: _jsx("div", { className: "gd-dropdown overlay", children: items }) }));
|
|
16
56
|
});
|
|
@@ -6,6 +6,7 @@ interface IOperatorDropdownItemOwnProps {
|
|
|
6
6
|
isDisabled?: boolean;
|
|
7
7
|
disabledTooltip?: string;
|
|
8
8
|
onClick: (identifier: MeasureValueFilterOperator) => void;
|
|
9
|
+
isMobile?: boolean;
|
|
9
10
|
}
|
|
10
11
|
export declare const OperatorDropdownItem: import("react").NamedExoticComponent<IOperatorDropdownItemOwnProps>;
|
|
11
12
|
export {};
|
|
@@ -8,7 +8,7 @@ import { Bubble, BubbleHoverTrigger } from "@gooddata/sdk-ui-kit";
|
|
|
8
8
|
import { simplifyText } from "@gooddata/util";
|
|
9
9
|
import { getOperatorIcon, getOperatorTranslationKey } from "./helpers/measureValueFilterOperator.js";
|
|
10
10
|
const BUBBLE_ALIGN_POINTS = [{ align: "cr cl" }, { align: "cl cr" }];
|
|
11
|
-
export const OperatorDropdownItem = memo(function OperatorDropdownItem({ operator, selectedOperator, bubbleText, isDisabled = false, disabledTooltip, onClick = () => { }, }) {
|
|
11
|
+
export const OperatorDropdownItem = memo(function OperatorDropdownItem({ operator, selectedOperator, bubbleText, isDisabled = false, disabledTooltip, onClick = () => { }, isMobile = false, }) {
|
|
12
12
|
const intl = useIntl();
|
|
13
13
|
const handleOnClick = (e) => {
|
|
14
14
|
if (isDisabled) {
|
|
@@ -29,8 +29,7 @@ export const OperatorDropdownItem = memo(function OperatorDropdownItem({ operato
|
|
|
29
29
|
});
|
|
30
30
|
const operatorTranslationKey = getOperatorTranslationKey(operator);
|
|
31
31
|
const title = operatorTranslationKey === undefined ? operator : intl.formatMessage({ id: operatorTranslationKey });
|
|
32
|
-
const itemContent = (_jsxs("div", { className: className, onClick: handleOnClick, "aria-disabled": isDisabled, "data-testid": `mvf-operator-${simplifyText(operator)}`, children: [
|
|
33
|
-
_jsx("div", { className: `gd-icon-${getOperatorIcon(operator)}`, title: title }), _jsx("span", { title: title, children: capitalize(title) }), bubbleText ? renderBubble(bubbleText) : null] }));
|
|
32
|
+
const itemContent = (_jsxs("div", { className: className, onClick: handleOnClick, "aria-disabled": isDisabled, "data-testid": `mvf-operator-${simplifyText(operator)}`, children: [isMobile ? null : _jsx("div", { className: `gd-icon-${getOperatorIcon(operator)}`, title: title }), _jsx("span", { title: title, children: capitalize(title) }), bubbleText && !isMobile ? renderBubble(bubbleText) : null] }));
|
|
34
33
|
// Wrap disabled item with tooltip if provided
|
|
35
34
|
if (isDisabled && disabledTooltip) {
|
|
36
35
|
return (_jsxs(BubbleHoverTrigger, { tagName: "div", showDelay: 400, hideDelay: 200, children: [itemContent, _jsx(Bubble, { className: "bubble-primary", alignPoints: BUBBLE_ALIGN_POINTS, children: disabledTooltip })
|
|
@@ -3,6 +3,7 @@ import { type WrappedComponentProps } from "react-intl";
|
|
|
3
3
|
interface ITreatNullValuesAsZeroCheckboxProps {
|
|
4
4
|
checked?: boolean;
|
|
5
5
|
onChange: (checked: boolean) => void;
|
|
6
|
+
isMobile?: boolean;
|
|
6
7
|
}
|
|
7
|
-
export declare function TreatNullValuesAsZeroCheckbox({ checked, onChange, intl }: ITreatNullValuesAsZeroCheckboxProps & WrappedComponentProps): ReactElement;
|
|
8
|
+
export declare function TreatNullValuesAsZeroCheckbox({ checked, onChange, isMobile, intl }: ITreatNullValuesAsZeroCheckboxProps & WrappedComponentProps): ReactElement;
|
|
8
9
|
export {};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Bubble, BubbleHoverTrigger } from "@gooddata/sdk-ui-kit";
|
|
3
|
-
export function TreatNullValuesAsZeroCheckbox({ checked = false, onChange, intl, }) {
|
|
3
|
+
export function TreatNullValuesAsZeroCheckbox({ checked = false, onChange, isMobile = false, intl, }) {
|
|
4
4
|
const handleOnChange = (e) => onChange(e.target.checked);
|
|
5
5
|
return (_jsxs("label", { className: "input-checkbox-label gd-mvf-treat-null-values-as-zero s-treat-null-values-as-zero", "data-testid": "mvf-treat-null-values-as-zero", children: [
|
|
6
|
-
_jsx("input", { type: "checkbox", name: "treat-null-values-as", className: "input-checkbox", checked: checked, onChange: handleOnChange }), _jsxs("span", { className: "input-label-text", children: [intl.formatMessage({ id: "mvf.treatNullValuesAsZeroLabel" }), _jsxs(BubbleHoverTrigger, { showDelay: 400, hideDelay: 200, children: [
|
|
6
|
+
_jsx("input", { type: "checkbox", name: "treat-null-values-as", className: "input-checkbox", checked: checked, onChange: handleOnChange }), _jsxs("span", { className: "input-label-text", children: [intl.formatMessage({ id: "mvf.treatNullValuesAsZeroLabel" }), isMobile ? null : (_jsxs(BubbleHoverTrigger, { showDelay: 400, hideDelay: 200, children: [
|
|
7
7
|
_jsx("span", { className: "inlineBubbleHelp" }), _jsx(Bubble, { className: "bubble-primary", alignPoints: [{ align: "tc bl" }], children: intl.formatMessage({ id: "mvf.treatNullValuesAsZeroTooltip" }) })
|
|
8
|
-
] })
|
|
9
|
-
] })
|
|
8
|
+
] }))] })
|
|
10
9
|
] }));
|
|
11
10
|
}
|
|
@@ -285,6 +285,18 @@ export interface IMeasureValueFilterCommonProps extends IMeasureValueFilterCusto
|
|
|
285
285
|
* @beta
|
|
286
286
|
*/
|
|
287
287
|
alignPoints?: IAlignPoint[];
|
|
288
|
+
/**
|
|
289
|
+
* When `true`, the dropdown takes the entire screen on mobile devices.
|
|
290
|
+
*
|
|
291
|
+
* @remarks
|
|
292
|
+
* Hosts that render the MVF inside responsive surfaces (e.g. dashboards) opt in to
|
|
293
|
+
* switch the overlay to a full-screen presentation on mobile viewports.
|
|
294
|
+
*
|
|
295
|
+
* Defaults to `false`.
|
|
296
|
+
*
|
|
297
|
+
* @beta
|
|
298
|
+
*/
|
|
299
|
+
fullscreenOnMobile?: boolean;
|
|
288
300
|
}
|
|
289
301
|
/**
|
|
290
302
|
* These customization properties allow you to specify custom components that the MeasureValueFilter
|
package/esm/internal.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export { CalendarTypeTabs } from "./DateFilter/DateFilterBody/CalendarTypeTabs.j
|
|
|
7
7
|
export { normalizeSelectedFilterOption } from "./DateFilter/utils/FilterOptionNormalization.js";
|
|
8
8
|
export { ListItem } from "./DateFilter/ListItem/ListItem.js";
|
|
9
9
|
export { ListItemTooltip } from "./DateFilter/ListItemTooltip/ListItemTooltip.js";
|
|
10
|
+
export { DimensionalitySection } from "./MeasureValueFilter/DimensionalitySection.js";
|
|
10
11
|
export { MeasureValueFilterDetailsBubble } from "./MeasureValueFilter/MeasureValueFilterDetailsBubble.js";
|
|
12
|
+
export type { IDimensionalityItem } from "./MeasureValueFilter/typings.js";
|
package/esm/internal.js
CHANGED
|
@@ -9,4 +9,5 @@ export { CalendarTypeTabs } from "./DateFilter/DateFilterBody/CalendarTypeTabs.j
|
|
|
9
9
|
export { normalizeSelectedFilterOption } from "./DateFilter/utils/FilterOptionNormalization.js";
|
|
10
10
|
export { ListItem } from "./DateFilter/ListItem/ListItem.js";
|
|
11
11
|
export { ListItemTooltip } from "./DateFilter/ListItemTooltip/ListItemTooltip.js";
|
|
12
|
+
export { DimensionalitySection } from "./MeasureValueFilter/DimensionalitySection.js";
|
|
12
13
|
export { MeasureValueFilterDetailsBubble } from "./MeasureValueFilter/MeasureValueFilterDetailsBubble.js";
|
package/esm/sdk-ui-filters.d.ts
CHANGED
|
@@ -3759,6 +3759,18 @@ export declare interface IMeasureValueFilterCommonProps extends IMeasureValueFil
|
|
|
3759
3759
|
* @beta
|
|
3760
3760
|
*/
|
|
3761
3761
|
alignPoints?: IAlignPoint[];
|
|
3762
|
+
/**
|
|
3763
|
+
* When `true`, the dropdown takes the entire screen on mobile devices.
|
|
3764
|
+
*
|
|
3765
|
+
* @remarks
|
|
3766
|
+
* Hosts that render the MVF inside responsive surfaces (e.g. dashboards) opt in to
|
|
3767
|
+
* switch the overlay to a full-screen presentation on mobile viewports.
|
|
3768
|
+
*
|
|
3769
|
+
* Defaults to `false`.
|
|
3770
|
+
*
|
|
3771
|
+
* @beta
|
|
3772
|
+
*/
|
|
3773
|
+
fullscreenOnMobile?: boolean;
|
|
3762
3774
|
}
|
|
3763
3775
|
|
|
3764
3776
|
/**
|
|
@@ -3890,6 +3902,16 @@ export declare interface IMeasureValueFilterDropdownButtonProps {
|
|
|
3890
3902
|
export declare interface IMeasureValueFilterDropdownProps extends IMeasureValueFilterCommonProps {
|
|
3891
3903
|
onCancel: () => void;
|
|
3892
3904
|
anchorEl?: HTMLElement | string;
|
|
3905
|
+
/**
|
|
3906
|
+
* Element rendered at the top of the dropdown overlay when displayed in fullscreen mobile mode.
|
|
3907
|
+
*
|
|
3908
|
+
* @remarks
|
|
3909
|
+
* Typically the host's dropdown button — composed by the parent {@link MeasureValueFilter}
|
|
3910
|
+
* so the trigger appears as the overlay header on small viewports.
|
|
3911
|
+
*
|
|
3912
|
+
* @internal
|
|
3913
|
+
*/
|
|
3914
|
+
mobileHeader?: ReactNode;
|
|
3893
3915
|
}
|
|
3894
3916
|
|
|
3895
3917
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gooddata/sdk-ui-filters",
|
|
3
|
-
"version": "11.39.0
|
|
3
|
+
"version": "11.39.0",
|
|
4
4
|
"description": "GoodData.UI SDK - Filter Components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "GoodData Corporation",
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
"ts-invariant": "0.10.3",
|
|
48
48
|
"tslib": "2.8.1",
|
|
49
49
|
"uuid": "11.1.0",
|
|
50
|
-
"@gooddata/sdk-
|
|
51
|
-
"@gooddata/sdk-model": "11.39.0
|
|
52
|
-
"@gooddata/sdk-
|
|
53
|
-
"@gooddata/sdk-ui-kit": "11.39.0
|
|
54
|
-
"@gooddata/util": "11.39.0
|
|
50
|
+
"@gooddata/sdk-ui": "11.39.0",
|
|
51
|
+
"@gooddata/sdk-model": "11.39.0",
|
|
52
|
+
"@gooddata/sdk-backend-spi": "11.39.0",
|
|
53
|
+
"@gooddata/sdk-ui-kit": "11.39.0",
|
|
54
|
+
"@gooddata/util": "11.39.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@microsoft/api-documenter": "^7.17.0",
|
|
@@ -93,12 +93,12 @@
|
|
|
93
93
|
"typescript": "5.9.3",
|
|
94
94
|
"vitest": "4.1.0",
|
|
95
95
|
"vitest-dom": "0.1.1",
|
|
96
|
-
"@gooddata/eslint-config": "11.39.0
|
|
97
|
-
"@gooddata/oxlint-config": "11.39.0
|
|
98
|
-
"@gooddata/reference-workspace": "11.39.0
|
|
99
|
-
"@gooddata/sdk-
|
|
100
|
-
"@gooddata/
|
|
101
|
-
"@gooddata/
|
|
96
|
+
"@gooddata/eslint-config": "11.39.0",
|
|
97
|
+
"@gooddata/oxlint-config": "11.39.0",
|
|
98
|
+
"@gooddata/reference-workspace": "11.39.0",
|
|
99
|
+
"@gooddata/sdk-ui-theme-provider": "11.39.0",
|
|
100
|
+
"@gooddata/stylelint-config": "11.39.0",
|
|
101
|
+
"@gooddata/sdk-backend-mockingbird": "11.39.0"
|
|
102
102
|
},
|
|
103
103
|
"peerDependencies": {
|
|
104
104
|
"react": "^18.0.0 || ^19.0.0",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
}
|
|
23
23
|
.dropdown-body .gd-infinite-list.gd-filter-group-body .gd-ui-kit-paged-virtual-list__item:last-child .gd-filter-group-item,
|
|
24
24
|
.gd-mobile-dropdown-content .gd-infinite-list.gd-filter-group-body .gd-ui-kit-paged-virtual-list__item:last-child .gd-filter-group-item {
|
|
25
|
+
height: 53px;
|
|
25
26
|
border-bottom: none;
|
|
26
27
|
}
|
|
27
28
|
.dropdown-body .gd-infinite-list.gd-filter-group-body .gd-attribute-filter__next,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sourceRoot":"","sources":["../scss/filterGroup.scss"],"names":[],"mappings":"AAGA;EACI;EACA;;;AAGJ;AAAA;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGI;AAAA;EACI;;AAGJ;AAAA;EACI;;AAIR;AAAA;EACI;;AAGJ;AAAA;EACI;;AAGJ;AAAA;EACI;;;AAIR;EACI","file":"filterGroup.css"}
|
|
1
|
+
{"version":3,"sourceRoot":"","sources":["../scss/filterGroup.scss"],"names":[],"mappings":"AAGA;EACI;EACA;;;AAGJ;AAAA;EAEI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGI;AAAA;EACI;;AAGJ;AAAA;EACI;EACA;;AAIR;AAAA;EACI;;AAGJ;AAAA;EACI;;AAGJ;AAAA;EACI;;;AAIR;EACI","file":"filterGroup.css"}
|