@gravity-ui/blog-constructor 10.1.1-alpha.0 → 10.1.1-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,6 +11,7 @@ const SavedOnlyFilter_1 = require("../SavedOnlyFilter/SavedOnlyFilter.js");
11
11
  const SearchFilter_1 = require("../SearchFilter/SearchFilter.js");
12
12
  const SelectFilter_1 = require("../SelectFilter/SelectFilter.js");
13
13
  const b = (0, cn_1.block)('filter-control');
14
+ const resolveAnalyticsEvents = (analyticsEvents, data) => typeof analyticsEvents === 'function' ? analyticsEvents(data) : analyticsEvents;
14
15
  const FilterControl = ({ filter, initialValue, onChange }) => {
15
16
  const handleAnalytics = (0, page_constructor_1.useAnalytics)();
16
17
  const { hasLikes } = React.useContext(LikesContext_1.LikesContext);
@@ -21,22 +22,28 @@ const FilterControl = ({ filter, initialValue, onChange }) => {
21
22
  onChange(query);
22
23
  }, [filter.analyticsEvents, handleAnalytics, onChange]);
23
24
  if (filter.type === 'search') {
24
- const { queryParamName, placeholder, onClick } = filter;
25
- return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SearchFilter_1.SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: onClick }) }));
25
+ const { queryParamName, placeholder, clickAnalyticsEvents } = filter;
26
+ return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SearchFilter_1.SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: clickAnalyticsEvents
27
+ ? () => handleAnalytics(clickAnalyticsEvents)
28
+ : undefined }) }));
26
29
  }
27
30
  if (filter.type === 'savedOnly') {
28
- const { queryParamName, onClick } = filter;
31
+ const { queryParamName, clickAnalyticsEvents } = filter;
29
32
  if (!hasLikes) {
30
33
  return null;
31
34
  }
32
35
  const handleSavedOnlyChange = (value) => {
33
- onClick === null || onClick === void 0 ? void 0 : onClick(value);
36
+ if (clickAnalyticsEvents) {
37
+ handleAnalytics(resolveAnalyticsEvents(clickAnalyticsEvents, value));
38
+ }
34
39
  handleChange({ [queryParamName]: value ? 'true' : '', search: '' });
35
40
  };
36
41
  return ((0, jsx_runtime_1.jsx)("div", { className: b({ 'width-auto': true }), children: (0, jsx_runtime_1.jsx)(SavedOnlyFilter_1.SavedOnlyFilter, { initialValue: initialValue === 'true', onChange: handleSavedOnlyChange }) }));
37
42
  }
38
- const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, onOpen, onClose, } = filter;
39
- return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SelectFilter_1.SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: onOpen, onClose: onClose }) }));
43
+ const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, openAnalyticsEvents, closeAnalyticsEvents, } = filter;
44
+ return ((0, jsx_runtime_1.jsx)("div", { className: b(), children: (0, jsx_runtime_1.jsx)(SelectFilter_1.SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined, onClose: closeAnalyticsEvents
45
+ ? (data) => handleAnalytics(resolveAnalyticsEvents(closeAnalyticsEvents, data))
46
+ : undefined }) }));
40
47
  };
41
48
  exports.FilterControl = FilterControl;
42
49
  //# sourceMappingURL=FilterControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":";;;;;AAAA,qDAA+B;AAE/B,mEAA0D;AAE1D,uEAA+D;AAQ/D,gDAA2C;AAC3C,2EAAmE;AACnE,kEAA0D;AAC1D,kEAA0D;AAI1D,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,gBAAgB,CAAC,CAAC;AAQ3B,MAAM,aAAa,GAAG,CAAC,EAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAqB,EAAE,EAAE;IAClF,MAAM,eAAe,GAAG,IAAA,+BAAY,GAAE,CAAC;IACvC,MAAM,EAAC,QAAQ,EAAC,GAAG,KAAK,CAAC,UAAU,CAAC,2BAAY,CAAC,CAAC;IAElD,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAClC,CAAC,KAAY,EAAE,EAAE;QACb,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YACzB,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE,QAAQ,CAAC,CACtD,CAAC;IAEF,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAC,cAAc,EAAE,WAAW,EAAE,OAAO,EAAC,GAAG,MAA4B,CAAC;QAE5E,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,EAAE,YACf,uBAAC,2BAAY,IACT,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAkC,EAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAU,CAAC,EACrE,OAAO,EAAE,OAAO,GAClB,GACA,CACT,CAAC;IACN,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,MAAM,EAAC,cAAc,EAAE,OAAO,EAAC,GAAG,MAA+B,CAAC;QAElE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAE,EAAE;YAC7C,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAG,KAAK,CAAC,CAAC;YACjB,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAU,CAAC,CAAC;QAC/E,CAAC,CAAC;QAEF,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,CAAC,EAAC,YAAY,EAAE,IAAI,EAAC,CAAC,YACnC,uBAAC,iCAAe,IACZ,YAAY,EAAE,YAAY,KAAK,MAAM,EACrC,QAAQ,EAAE,qBAAqB,GACjC,GACA,CACT,CAAC;IACN,CAAC;IAED,MAAM,EACF,cAAc,EACd,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,WAAW,EACX,OAAO,EACP,QAAQ,EACR,EAAE,EACF,MAAM,EACN,OAAO,GACV,GAAG,MAA4B,CAAC;IAEjC,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,EAAE,YACf,uBAAC,2BAAY,IACT,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAiC,EAC9C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,EAAE,EACN,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAU,CAAC,EACrE,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,OAAO,GAClB,GACA,CACT,CAAC;AACN,CAAC,CAAC;AAjFW,QAAA,aAAa,iBAiFxB","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, onClick} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={onClick}\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, onClick} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n onClick?.(value);\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n onOpen,\n onClose,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={onOpen}\n onClose={onClose}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":";;;;;AAAA,qDAA+B;AAE/B,mEAA0D;AAE1D,uEAA+D;AAS/D,gDAA2C;AAC3C,2EAAmE;AACnE,kEAA0D;AAC1D,kEAA0D;AAI1D,MAAM,CAAC,GAAG,IAAA,UAAK,EAAC,gBAAgB,CAAC,CAAC;AAElC,MAAM,sBAAsB,GAAG,CAAK,eAA8C,EAAE,IAAO,EAAE,EAAE,CAC3F,OAAO,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;AAQ7E,MAAM,aAAa,GAAG,CAAC,EAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAqB,EAAE,EAAE;IAClF,MAAM,eAAe,GAAG,IAAA,+BAAY,GAAE,CAAC;IACvC,MAAM,EAAC,QAAQ,EAAC,GAAG,KAAK,CAAC,UAAU,CAAC,2BAAY,CAAC,CAAC;IAElD,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAClC,CAAC,KAAY,EAAE,EAAE;QACb,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YACzB,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE,QAAQ,CAAC,CACtD,CAAC;IAEF,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAC,cAAc,EAAE,WAAW,EAAE,oBAAoB,EAAC,GAAG,MAA4B,CAAC;QAEzF,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,EAAE,YACf,uBAAC,2BAAY,IACT,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAkC,EAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAU,CAAC,EACrE,OAAO,EACH,oBAAoB;oBAChB,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,oBAAoB,CAAC;oBAC7C,CAAC,CAAC,SAAS,GAErB,GACA,CACT,CAAC;IACN,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,MAAM,EAAC,cAAc,EAAE,oBAAoB,EAAC,GAAG,MAA+B,CAAC;QAE/E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAE,EAAE;YAC7C,IAAI,oBAAoB,EAAE,CAAC;gBACvB,eAAe,CAAC,sBAAsB,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAU,CAAC,CAAC;QAC/E,CAAC,CAAC;QAEF,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,CAAC,EAAC,YAAY,EAAE,IAAI,EAAC,CAAC,YACnC,uBAAC,iCAAe,IACZ,YAAY,EAAE,YAAY,KAAK,MAAM,EACrC,QAAQ,EAAE,qBAAqB,GACjC,GACA,CACT,CAAC;IACN,CAAC;IAED,MAAM,EACF,cAAc,EACd,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,WAAW,EACX,OAAO,EACP,QAAQ,EACR,EAAE,EACF,mBAAmB,EACnB,oBAAoB,GACvB,GAAG,MAA4B,CAAC;IAEjC,OAAO,CACH,gCAAK,SAAS,EAAE,CAAC,EAAE,YACf,uBAAC,2BAAY,IACT,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAiC,EAC9C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,EAAE,EACN,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAU,CAAC,EACrE,MAAM,EACF,mBAAmB,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,EAEhF,OAAO,EACH,oBAAoB;gBAChB,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CACL,eAAe,CAAC,sBAAsB,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;gBACzE,CAAC,CAAC,SAAS,GAErB,GACA,CACT,CAAC;AACN,CAAC,CAAC;AA9FW,QAAA,aAAa,iBA8FxB","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n DynamicAnalyticsEventsProp,\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nconst resolveAnalyticsEvents = <T,>(analyticsEvents: DynamicAnalyticsEventsProp<T>, data: T) =>\n typeof analyticsEvents === 'function' ? analyticsEvents(data) : analyticsEvents;\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, clickAnalyticsEvents} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={\n clickAnalyticsEvents\n ? () => handleAnalytics(clickAnalyticsEvents)\n : undefined\n }\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, clickAnalyticsEvents} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n if (clickAnalyticsEvents) {\n handleAnalytics(resolveAnalyticsEvents(clickAnalyticsEvents, value));\n }\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n openAnalyticsEvents,\n closeAnalyticsEvents,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={\n openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined\n }\n onClose={\n closeAnalyticsEvents\n ? (data) =>\n handleAnalytics(resolveAnalyticsEvents(closeAnalyticsEvents, data))\n : undefined\n }\n />\n </div>\n );\n};\n"]}
@@ -10,6 +10,13 @@ const cn_1 = require("../../../../utils/cn.js");
10
10
  const customRenders_1 = require("./customRenders.js");
11
11
  const b = (0, cn_1.block)('feed-filter');
12
12
  const VIRTUALIZATION_THRESHOLD = 1000;
13
+ const getSelectedValuesChangesCount = (initial, current) => {
14
+ const initialValues = new Set(initial);
15
+ const currentValues = new Set(current);
16
+ const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;
17
+ const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;
18
+ return removedValuesCount + addedValuesCount;
19
+ };
13
20
  const SelectFilter = ({ multiple, filterable, hasClear, placeholder, options, allLabel, qa, initialValue, onChange, onOpen, onClose, className, }) => {
14
21
  const isMobile = React.useContext(MobileContext_1.MobileContext);
15
22
  let defaultValue;
@@ -48,7 +55,7 @@ const SelectFilter = ({ multiple, filterable, hasClear, placeholder, options, al
48
55
  const selectedValues = [...selectedValuesRef.current];
49
56
  onClose === null || onClose === void 0 ? void 0 : onClose({
50
57
  selectedValues,
51
- selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],
58
+ changesCount: getSelectedValuesChangesCount(selectedValuesOnOpenRef.current, selectedValues),
52
59
  });
53
60
  }
54
61
  isOpenRef.current = false;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nconst getSelectedValuesChangesCount = (initial: string[], current: string[]) => {\n const initialValues = new Set(initial);\n const currentValues = new Set(current);\n\n const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;\n const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;\n\n return removedValuesCount + addedValuesCount;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n changesCount: getSelectedValuesChangesCount(\n selectedValuesOnOpenRef.current,\n selectedValues,\n ),\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
@@ -171,8 +171,9 @@ type FilterConfigBase = {
171
171
  };
172
172
  export type SelectFilterCloseData = {
173
173
  selectedValues: string[];
174
- selectedValuesOnOpen: string[];
174
+ changesCount: number;
175
175
  };
176
+ export type DynamicAnalyticsEventsProp<T> = AnalyticsEventsProp | ((data: T) => AnalyticsEventsProp);
176
177
  export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {
177
178
  type?: 'select';
178
179
  /** The selectable items for this filter */
@@ -181,22 +182,22 @@ export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple'
181
182
  allLabel: string;
182
183
  /** Optional QA attribute forwarded to the switcher */
183
184
  qa?: string;
184
- /** Optional callback fired when the select opens */
185
- onOpen?: () => void;
186
- /** Optional callback fired when the select closes */
187
- onClose?: (data: SelectFilterCloseData) => void;
185
+ /** Optional analytics events fired when the select opens */
186
+ openAnalyticsEvents?: AnalyticsEventsProp;
187
+ /** Optional analytics events fired when the select closes */
188
+ closeAnalyticsEvents?: DynamicAnalyticsEventsProp<SelectFilterCloseData>;
188
189
  };
189
190
  export type SearchFilterConfig = FilterConfigBase & {
190
191
  type: 'search';
191
192
  /** Placeholder text for the search input */
192
193
  placeholder?: string;
193
- /** Optional callback fired when the search input is clicked */
194
- onClick?: () => void;
194
+ /** Optional analytics events fired when the search input is clicked */
195
+ clickAnalyticsEvents?: AnalyticsEventsProp;
195
196
  };
196
197
  export type SavedOnlyFilterConfig = FilterConfigBase & {
197
198
  type: 'savedOnly';
198
- /** Optional callback fired with the next saved-only state */
199
- onClick?: (state: boolean) => void;
199
+ /** Optional analytics events fired with the next saved-only state */
200
+ clickAnalyticsEvents?: DynamicAnalyticsEventsProp<boolean>;
200
201
  };
201
202
  export type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;
202
203
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":";;;AA6PA,wDAWC;AA3PD,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,qBAAL,KAAK,QAGhB;AAmFD,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,yBAAT,SAAS,QAgBpB;AA8DD,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,iCAAjB,iBAAiB,QAU5B;AAkED,SAAgB,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB;AAED,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,yCAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n selectedValuesOnOpen: string[];\n};\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional callback fired when the select opens */\n onOpen?: () => void;\n /** Optional callback fired when the select closes */\n onClose?: (data: SelectFilterCloseData) => void;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional callback fired when the search input is clicked */\n onClick?: () => void;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional callback fired with the next saved-only state */\n onClick?: (state: boolean) => void;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":";;;AAiQA,wDAWC;AA/PD,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,qBAAL,KAAK,QAGhB;AAmFD,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,yBAAT,SAAS,QAgBpB;AA8DD,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,iCAAjB,iBAAiB,QAU5B;AAsED,SAAgB,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,4BAAZ,YAAY,QAGvB;AAED,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,yCAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n changesCount: number;\n};\n\nexport type DynamicAnalyticsEventsProp<T> =\n | AnalyticsEventsProp\n | ((data: T) => AnalyticsEventsProp);\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional analytics events fired when the select opens */\n openAnalyticsEvents?: AnalyticsEventsProp;\n /** Optional analytics events fired when the select closes */\n closeAnalyticsEvents?: DynamicAnalyticsEventsProp<SelectFilterCloseData>;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional analytics events fired when the search input is clicked */\n clickAnalyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional analytics events fired with the next saved-only state */\n clickAnalyticsEvents?: DynamicAnalyticsEventsProp<boolean>;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
@@ -8,6 +8,7 @@ import { SearchFilter } from "../SearchFilter/SearchFilter.js";
8
8
  import { SelectFilter } from "../SelectFilter/SelectFilter.js";
9
9
  import './FilterControl.css';
10
10
  const b = block('filter-control');
11
+ const resolveAnalyticsEvents = (analyticsEvents, data) => typeof analyticsEvents === 'function' ? analyticsEvents(data) : analyticsEvents;
11
12
  export const FilterControl = ({ filter, initialValue, onChange }) => {
12
13
  const handleAnalytics = useAnalytics();
13
14
  const { hasLikes } = React.useContext(LikesContext);
@@ -18,21 +19,27 @@ export const FilterControl = ({ filter, initialValue, onChange }) => {
18
19
  onChange(query);
19
20
  }, [filter.analyticsEvents, handleAnalytics, onChange]);
20
21
  if (filter.type === 'search') {
21
- const { queryParamName, placeholder, onClick } = filter;
22
- return (_jsx("div", { className: b(), children: _jsx(SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: onClick }) }));
22
+ const { queryParamName, placeholder, clickAnalyticsEvents } = filter;
23
+ return (_jsx("div", { className: b(), children: _jsx(SearchFilter, { placeholder: placeholder, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onClick: clickAnalyticsEvents
24
+ ? () => handleAnalytics(clickAnalyticsEvents)
25
+ : undefined }) }));
23
26
  }
24
27
  if (filter.type === 'savedOnly') {
25
- const { queryParamName, onClick } = filter;
28
+ const { queryParamName, clickAnalyticsEvents } = filter;
26
29
  if (!hasLikes) {
27
30
  return null;
28
31
  }
29
32
  const handleSavedOnlyChange = (value) => {
30
- onClick === null || onClick === void 0 ? void 0 : onClick(value);
33
+ if (clickAnalyticsEvents) {
34
+ handleAnalytics(resolveAnalyticsEvents(clickAnalyticsEvents, value));
35
+ }
31
36
  handleChange({ [queryParamName]: value ? 'true' : '', search: '' });
32
37
  };
33
38
  return (_jsx("div", { className: b({ 'width-auto': true }), children: _jsx(SavedOnlyFilter, { initialValue: initialValue === 'true', onChange: handleSavedOnlyChange }) }));
34
39
  }
35
- const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, onOpen, onClose, } = filter;
36
- return (_jsx("div", { className: b(), children: _jsx(SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: onOpen, onClose: onClose }) }));
40
+ const { queryParamName, multiple, filterable, hasClear, placeholder, options, allLabel, qa, openAnalyticsEvents, closeAnalyticsEvents, } = filter;
41
+ return (_jsx("div", { className: b(), children: _jsx(SelectFilter, { multiple: multiple, filterable: filterable, hasClear: hasClear, placeholder: placeholder, options: options, allLabel: allLabel, qa: qa, initialValue: initialValue, onChange: (value) => handleChange({ [queryParamName]: value }), onOpen: openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined, onClose: closeAnalyticsEvents
42
+ ? (data) => handleAnalytics(resolveAnalyticsEvents(closeAnalyticsEvents, data))
43
+ : undefined }) }));
37
44
  };
38
45
  //# sourceMappingURL=FilterControl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, onClick} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={onClick}\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, onClick} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n onClick?.(value);\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n onOpen,\n onClose,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={onOpen}\n onClose={onClose}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"FilterControl.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/FilterControl/FilterControl.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAC,YAAY,EAAC,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAC,YAAY,EAAC,6CAA0C;AAS/D,OAAO,EAAC,KAAK,EAAC,gCAA6B;AAC3C,OAAO,EAAC,eAAe,EAAC,8CAA2C;AACnE,OAAO,EAAC,YAAY,EAAC,wCAAqC;AAC1D,OAAO,EAAC,YAAY,EAAC,wCAAqC;AAE1D,OAAO,qBAAqB,CAAC;AAE7B,MAAM,CAAC,GAAG,KAAK,CAAC,gBAAgB,CAAC,CAAC;AAElC,MAAM,sBAAsB,GAAG,CAAK,eAA8C,EAAE,IAAO,EAAE,EAAE,CAC3F,OAAO,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;AAQpF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAqB,EAAE,EAAE;IAClF,MAAM,eAAe,GAAG,YAAY,EAAE,CAAC;IACvC,MAAM,EAAC,QAAQ,EAAC,GAAG,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAElD,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAClC,CAAC,KAAY,EAAE,EAAE;QACb,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YACzB,eAAe,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAC5C,CAAC;QACD,QAAQ,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,EACD,CAAC,MAAM,CAAC,eAAe,EAAE,eAAe,EAAE,QAAQ,CAAC,CACtD,CAAC;IAEF,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,EAAC,cAAc,EAAE,WAAW,EAAE,oBAAoB,EAAC,GAAG,MAA4B,CAAC;QAEzF,OAAO,CACH,cAAK,SAAS,EAAE,CAAC,EAAE,YACf,KAAC,YAAY,IACT,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAkC,EAChD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAU,CAAC,EACrE,OAAO,EACH,oBAAoB;oBAChB,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,oBAAoB,CAAC;oBAC7C,CAAC,CAAC,SAAS,GAErB,GACA,CACT,CAAC;IACN,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,MAAM,EAAC,cAAc,EAAE,oBAAoB,EAAC,GAAG,MAA+B,CAAC;QAE/E,IAAI,CAAC,QAAQ,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,qBAAqB,GAAG,CAAC,KAAc,EAAE,EAAE;YAC7C,IAAI,oBAAoB,EAAE,CAAC;gBACvB,eAAe,CAAC,sBAAsB,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC,CAAC;YACzE,CAAC;YACD,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAU,CAAC,CAAC;QAC/E,CAAC,CAAC;QAEF,OAAO,CACH,cAAK,SAAS,EAAE,CAAC,CAAC,EAAC,YAAY,EAAE,IAAI,EAAC,CAAC,YACnC,KAAC,eAAe,IACZ,YAAY,EAAE,YAAY,KAAK,MAAM,EACrC,QAAQ,EAAE,qBAAqB,GACjC,GACA,CACT,CAAC;IACN,CAAC;IAED,MAAM,EACF,cAAc,EACd,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,WAAW,EACX,OAAO,EACP,QAAQ,EACR,EAAE,EACF,mBAAmB,EACnB,oBAAoB,GACvB,GAAG,MAA4B,CAAC;IAEjC,OAAO,CACH,cAAK,SAAS,EAAE,CAAC,EAAE,YACf,KAAC,YAAY,IACT,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAiC,EAC9C,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,EAAE,EACN,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,EAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAU,CAAC,EACrE,MAAM,EACF,mBAAmB,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,SAAS,EAEhF,OAAO,EACH,oBAAoB;gBAChB,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CACL,eAAe,CAAC,sBAAsB,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;gBACzE,CAAC,CAAC,SAAS,GAErB,GACA,CACT,CAAC;AACN,CAAC,CAAC","sourcesContent":["import * as React from 'react';\n\nimport {useAnalytics} from '@gravity-ui/page-constructor';\n\nimport {LikesContext} from '../../../../contexts/LikesContext';\nimport {\n DynamicAnalyticsEventsProp,\n FilterConfig,\n Query,\n SavedOnlyFilterConfig,\n SearchFilterConfig,\n SelectFilterConfig,\n} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\nimport {SavedOnlyFilter} from '../SavedOnlyFilter/SavedOnlyFilter';\nimport {SearchFilter} from '../SearchFilter/SearchFilter';\nimport {SelectFilter} from '../SelectFilter/SelectFilter';\n\nimport './FilterControl.scss';\n\nconst b = block('filter-control');\n\nconst resolveAnalyticsEvents = <T,>(analyticsEvents: DynamicAnalyticsEventsProp<T>, data: T) =>\n typeof analyticsEvents === 'function' ? analyticsEvents(data) : analyticsEvents;\n\nexport type FilterControlProps = {\n filter: FilterConfig;\n initialValue: string | number | null | undefined;\n onChange: (query: Query) => void;\n};\n\nexport const FilterControl = ({filter, initialValue, onChange}: FilterControlProps) => {\n const handleAnalytics = useAnalytics();\n const {hasLikes} = React.useContext(LikesContext);\n\n const handleChange = React.useCallback(\n (query: Query) => {\n if (filter.analyticsEvents) {\n handleAnalytics(filter.analyticsEvents);\n }\n onChange(query);\n },\n [filter.analyticsEvents, handleAnalytics, onChange],\n );\n\n if (filter.type === 'search') {\n const {queryParamName, placeholder, clickAnalyticsEvents} = filter as SearchFilterConfig;\n\n return (\n <div className={b()}>\n <SearchFilter\n placeholder={placeholder}\n initialValue={initialValue as string | undefined}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onClick={\n clickAnalyticsEvents\n ? () => handleAnalytics(clickAnalyticsEvents)\n : undefined\n }\n />\n </div>\n );\n }\n\n if (filter.type === 'savedOnly') {\n const {queryParamName, clickAnalyticsEvents} = filter as SavedOnlyFilterConfig;\n\n if (!hasLikes) {\n return null;\n }\n\n const handleSavedOnlyChange = (value: boolean) => {\n if (clickAnalyticsEvents) {\n handleAnalytics(resolveAnalyticsEvents(clickAnalyticsEvents, value));\n }\n handleChange({[queryParamName]: value ? 'true' : '', search: ''} as Query);\n };\n\n return (\n <div className={b({'width-auto': true})}>\n <SavedOnlyFilter\n initialValue={initialValue === 'true'}\n onChange={handleSavedOnlyChange}\n />\n </div>\n );\n }\n\n const {\n queryParamName,\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n openAnalyticsEvents,\n closeAnalyticsEvents,\n } = filter as SelectFilterConfig;\n\n return (\n <div className={b()}>\n <SelectFilter\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear}\n placeholder={placeholder as string | undefined}\n options={options}\n allLabel={allLabel}\n qa={qa}\n initialValue={initialValue}\n onChange={(value) => handleChange({[queryParamName]: value} as Query)}\n onOpen={\n openAnalyticsEvents ? () => handleAnalytics(openAnalyticsEvents) : undefined\n }\n onClose={\n closeAnalyticsEvents\n ? (data) =>\n handleAnalytics(resolveAnalyticsEvents(closeAnalyticsEvents, data))\n : undefined\n }\n />\n </div>\n );\n};\n"]}
@@ -7,6 +7,13 @@ import { renderFilter, renderOption, renderSwitcher } from "./customRenders.js";
7
7
  import './SelectFilter.css';
8
8
  const b = block('feed-filter');
9
9
  const VIRTUALIZATION_THRESHOLD = 1000;
10
+ const getSelectedValuesChangesCount = (initial, current) => {
11
+ const initialValues = new Set(initial);
12
+ const currentValues = new Set(current);
13
+ const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;
14
+ const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;
15
+ return removedValuesCount + addedValuesCount;
16
+ };
10
17
  export const SelectFilter = ({ multiple, filterable, hasClear, placeholder, options, allLabel, qa, initialValue, onChange, onOpen, onClose, className, }) => {
11
18
  const isMobile = React.useContext(MobileContext);
12
19
  let defaultValue;
@@ -45,7 +52,7 @@ export const SelectFilter = ({ multiple, filterable, hasClear, placeholder, opti
45
52
  const selectedValues = [...selectedValuesRef.current];
46
53
  onClose === null || onClose === void 0 ? void 0 : onClose({
47
54
  selectedValues,
48
- selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],
55
+ changesCount: getSelectedValuesChangesCount(selectedValuesOnOpenRef.current, selectedValues),
49
56
  });
50
57
  }
51
58
  isOpenRef.current = false;
@@ -1 +1 @@
1
- {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n selectedValuesOnOpen: [...selectedValuesOnOpenRef.current],\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
1
+ {"version":3,"file":"SelectFilter.js","sourceRoot":"../../../../../../src","sources":["components/FeedHeader/components/SelectFilter/SelectFilter.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\n\nimport {Select, SelectOption} from '@gravity-ui/uikit';\n\nimport {MobileContext} from '../../../../contexts/MobileContext';\nimport {SelectFilterCloseData} from '../../../../models/common';\nimport {block} from '../../../../utils/cn';\n\nimport {renderFilter, renderOption, renderSwitcher} from './customRenders';\n\nimport './SelectFilter.scss';\n\nconst b = block('feed-filter');\n\nconst VIRTUALIZATION_THRESHOLD = 1000;\n\nexport type SelectFilterProps = {\n multiple?: boolean;\n filterable?: boolean;\n hasClear?: boolean;\n placeholder?: string;\n options: SelectOption[];\n allLabel: string;\n qa?: string;\n initialValue: string | number | null | undefined;\n onChange: (value: string) => void;\n onOpen?: () => void;\n onClose?: (data: SelectFilterCloseData) => void;\n className?: string;\n};\n\nconst getSelectedValuesChangesCount = (initial: string[], current: string[]) => {\n const initialValues = new Set(initial);\n const currentValues = new Set(current);\n\n const removedValuesCount = initial.filter((value) => !currentValues.has(value)).length;\n const addedValuesCount = current.filter((value) => !initialValues.has(value)).length;\n\n return removedValuesCount + addedValuesCount;\n};\n\nexport const SelectFilter = ({\n multiple,\n filterable,\n hasClear,\n placeholder,\n options,\n allLabel,\n qa,\n initialValue,\n onChange,\n onOpen,\n onClose,\n className,\n}: SelectFilterProps) => {\n const isMobile = React.useContext(MobileContext);\n\n let defaultValue: string[];\n if (multiple) {\n defaultValue = initialValue ? (initialValue as string).split(',') : [];\n } else {\n defaultValue =\n initialValue === null || initialValue === undefined ? [] : [`${initialValue}`];\n }\n\n const selectedValuesRef = React.useRef(defaultValue);\n const selectedValuesOnOpenRef = React.useRef(defaultValue);\n const isOpenRef = React.useRef(false);\n\n const optionsWithEmpty: SelectOption[] = multiple\n ? options\n : [{value: 'empty', content: allLabel}, ...options];\n\n const handleChange = (selectedValues: string[]) => {\n if (multiple) {\n selectedValuesRef.current = selectedValues;\n onChange(selectedValues.join(','));\n } else {\n const isEmpty = selectedValues.some((v) => v === 'empty');\n selectedValuesRef.current = isEmpty ? [] : selectedValues;\n onChange(isEmpty ? '' : selectedValues[0]);\n }\n };\n\n const handleOpenChange = (isOpen: boolean) => {\n if (isOpen) {\n selectedValuesOnOpenRef.current = [...selectedValuesRef.current];\n isOpenRef.current = true;\n onOpen?.();\n return;\n }\n\n if (isOpenRef.current) {\n const selectedValues = [...selectedValuesRef.current];\n onClose?.({\n selectedValues,\n changesCount: getSelectedValuesChangesCount(\n selectedValuesOnOpenRef.current,\n selectedValues,\n ),\n });\n }\n\n isOpenRef.current = false;\n };\n\n return (\n <div className={className}>\n <Select\n className={b('select')}\n size=\"xl\"\n multiple={multiple}\n filterable={filterable}\n hasClear={hasClear ?? multiple}\n disablePortal\n options={optionsWithEmpty}\n defaultValue={defaultValue}\n popupClassName={b('popup', {isMobile})}\n onUpdate={handleChange}\n onOpenChange={handleOpenChange}\n placeholder={placeholder ?? allLabel}\n renderControl={renderSwitcher({\n initial: defaultValue,\n list: optionsWithEmpty,\n defaultLabel: allLabel,\n qa,\n })}\n virtualizationThreshold={VIRTUALIZATION_THRESHOLD}\n renderOption={renderOption}\n renderFilter={filterable ? renderFilter({className: b('popup-filter')}) : undefined}\n />\n </div>\n );\n};\n"]}
@@ -171,8 +171,9 @@ type FilterConfigBase = {
171
171
  };
172
172
  export type SelectFilterCloseData = {
173
173
  selectedValues: string[];
174
- selectedValuesOnOpen: string[];
174
+ changesCount: number;
175
175
  };
176
+ export type DynamicAnalyticsEventsProp<T> = AnalyticsEventsProp | ((data: T) => AnalyticsEventsProp);
176
177
  export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {
177
178
  type?: 'select';
178
179
  /** The selectable items for this filter */
@@ -181,22 +182,22 @@ export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple'
181
182
  allLabel: string;
182
183
  /** Optional QA attribute forwarded to the switcher */
183
184
  qa?: string;
184
- /** Optional callback fired when the select opens */
185
- onOpen?: () => void;
186
- /** Optional callback fired when the select closes */
187
- onClose?: (data: SelectFilterCloseData) => void;
185
+ /** Optional analytics events fired when the select opens */
186
+ openAnalyticsEvents?: AnalyticsEventsProp;
187
+ /** Optional analytics events fired when the select closes */
188
+ closeAnalyticsEvents?: DynamicAnalyticsEventsProp<SelectFilterCloseData>;
188
189
  };
189
190
  export type SearchFilterConfig = FilterConfigBase & {
190
191
  type: 'search';
191
192
  /** Placeholder text for the search input */
192
193
  placeholder?: string;
193
- /** Optional callback fired when the search input is clicked */
194
- onClick?: () => void;
194
+ /** Optional analytics events fired when the search input is clicked */
195
+ clickAnalyticsEvents?: AnalyticsEventsProp;
195
196
  };
196
197
  export type SavedOnlyFilterConfig = FilterConfigBase & {
197
198
  type: 'savedOnly';
198
- /** Optional callback fired with the next saved-only state */
199
- onClick?: (state: boolean) => void;
199
+ /** Optional analytics events fired with the next saved-only state */
200
+ clickAnalyticsEvents?: DynamicAnalyticsEventsProp<boolean>;
200
201
  };
201
202
  export type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;
202
203
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":"AAaA,MAAM,CAAN,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,KAAL,KAAK,QAGhB;AAmFD,MAAM,CAAN,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,KAAT,SAAS,QAgBpB;AA8DD,MAAM,CAAN,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,KAAjB,iBAAiB,QAU5B;AAkED,MAAM,UAAU,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAED,MAAM,CAAN,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,KAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n selectedValuesOnOpen: string[];\n};\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional callback fired when the select opens */\n onOpen?: () => void;\n /** Optional callback fired when the select closes */\n onClose?: (data: SelectFilterCloseData) => void;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional callback fired when the search input is clicked */\n onClick?: () => void;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional callback fired with the next saved-only state */\n onClick?: (state: boolean) => void;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"../../../src","sources":["models/common.ts"],"names":[],"mappings":"AAaA,MAAM,CAAN,IAAY,KAGX;AAHD,WAAY,KAAK;IACb,wBAAe,CAAA;IACf,sBAAa,CAAA;AACjB,CAAC,EAHW,KAAK,KAAL,KAAK,QAGhB;AAmFD,MAAM,CAAN,IAAY,SAgBX;AAhBD,WAAY,SAAS;IACjB,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,yCAA4B,CAAA;IAC5B,uCAA0B,CAAA;IAC1B,yCAA4B,CAAA;IAC5B,mCAAsB,CAAA;IACtB,oDAAuC,CAAA;IACvC,yCAA4B,CAAA;IAC5B,2CAA8B,CAAA;IAC9B,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,qCAAwB,CAAA;IACxB,sDAAyC,CAAA;IACzC,qCAAwB,CAAA;IACxB,uDAA0C,CAAA;AAC9C,CAAC,EAhBW,SAAS,KAAT,SAAS,QAgBpB;AA8DD,MAAM,CAAN,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IACzB,uDAAkC,CAAA;IAClC,qDAAgC,CAAA;IAChC,wDAAmC,CAAA;IACnC,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,kEAA6C,CAAA;IAC7C,+CAA0B,CAAA;IAC1B,uDAAkC,CAAA;IAClC,wDAAmC,CAAA;AACvC,CAAC,EAVW,iBAAiB,KAAjB,iBAAiB,QAU5B;AAsED,MAAM,UAAU,sBAAsB,CAAC,OAAsB;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACd,CAAC;IAED,2EAA2E;IAC3E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5B,OAAO,OAA2B,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAAyB,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,4BAAY,CAAA;AAChB,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAED,MAAM,CAAN,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACjC,sCAAS,CAAA;IACT,sCAAS,CAAA;AACb,CAAC,EAHW,yBAAyB,KAAzB,yBAAyB,QAGpC","sourcesContent":["import * as React from 'react';\n\n// eslint-disable-next-line import/no-extraneous-dependencies\nimport {MarkdownItPluginCb} from '@diplodoc/transform/lib/plugins/typings';\nimport {\n AnalyticsEventsProp,\n HeaderBlockProps as PageConstructorHeaderBlockProps,\n} from '@gravity-ui/page-constructor';\nimport {SelectOption, SelectProps} from '@gravity-ui/uikit';\nimport {IBrowser, IDevice} from 'ua-parser-js';\n\nimport {Locale} from '../models/locale';\n\nexport enum Theme {\n Light = 'light',\n Dark = 'dark',\n}\n\nexport interface ClassNameProps {\n className?: string;\n}\n\nexport type Author = {\n id: number | string;\n avatar: string | null;\n createdAt: string;\n updatedAt: string;\n firstName: string | null;\n secondName: string | null;\n description: string | null;\n fullDescription: string | null;\n shortDescription: string | null;\n} & {\n [x: string]: string | null;\n};\n\nexport type Query = Record<string, number | string | null>;\n\n//page models\n\nexport interface Menu {\n title: string;\n}\n\nexport interface WithDeviceProps {\n device: IDevice;\n browser: IBrowser;\n isRobot: boolean;\n}\n\nexport interface PostsProps {\n posts: PostData[];\n count: number;\n totalCount: number;\n pinnedPost?: PostData;\n}\n\nexport type Tag = {\n slug: string;\n name: string;\n createdAt?: string;\n updatedAt?: string;\n icon?: string;\n isDeleted?: boolean;\n locale?: string;\n blogTagId?: number | string;\n count?: number;\n};\n\nexport interface PostData {\n author?: string;\n authors?: Author[];\n blogPostId?: number | string;\n content?: string;\n date: string;\n description?: string;\n hasUserLike: boolean;\n htmlTitle: string;\n id: number;\n image: string;\n isPublished?: boolean;\n sharedImage?: string;\n likes: number;\n locale: Locale;\n metaDescription?: string | null;\n metaTitle?: string | null;\n readingTime?: number;\n shareDescription?: string;\n shareImage?: string;\n shareTitle?: string;\n slug: string;\n keywords?: string[];\n tags: Tag[];\n textTitle: string;\n title: string;\n url: string;\n noIndex?: boolean;\n}\n\nexport enum BlockType {\n Header = 'blog-header-block',\n YFM = 'blog-yfm-block',\n Layout = 'blog-layout-block',\n Media = 'blog-media-block',\n Banner = 'blog-banner-block',\n CTA = 'blog-cta-block',\n ColoredText = 'blog-colored-text-block',\n Author = 'blog-author-block',\n Suggest = 'blog-suggest-block',\n Meta = 'blog-meta-block',\n Feed = 'blog-feed-block',\n Form = 'blog-form-block',\n CompactMedia = 'blog-compact-media-block',\n Take = 'blog-take-block',\n SideCardList = 'blog-side-card-list-block',\n}\n\nexport type MetaProps = {\n metaComponent: JSX.Element;\n needHelmetWrapper: boolean;\n};\n\nexport type MetaOrganizationType = {\n url: string;\n appTitle: string;\n legalName: string;\n supportEmail: string;\n};\n\nexport interface PostMetaProps {\n title: string;\n date: string;\n image: string;\n canonicalUrl: string;\n content?: string;\n description?: string;\n sharing: {\n shareTitle: string;\n shareDescription: string;\n shareImage: string;\n shareGenImage: string;\n shareGenTitle: string;\n };\n keywords?: string[];\n noIndex?: boolean;\n authors?: Author[];\n tags?: Tag[];\n organization: MetaOrganizationType;\n}\n\nexport type ToggleLikeCallbackType = ({\n postId,\n hasLike,\n}: {\n postId?: number | string;\n hasLike?: boolean;\n}) => void;\n\nexport interface HeaderBlockProps extends PageConstructorHeaderBlockProps {\n backLink?: {\n url: string;\n title: React.ReactNode;\n };\n}\n\nexport type GetPostsRequest = {\n page: number;\n perPage: number;\n savedOnly: boolean;\n search: string | undefined;\n [filterParam: string]: string | number | boolean | undefined;\n};\n\nexport type GetPostsType = (query: GetPostsRequest) => Promise<PostsProps>;\n\nexport type HandleChangeQueryParams = (params: Query) => void;\n\nexport enum DefaultEventNames {\n ShareButton = 'share-button-click',\n SaveButton = 'save-button-click',\n ShowMore = 'show-more-button-click',\n PaginatorHome = 'paginator-home-button-click',\n PaginatorNext = 'paginator-next-button-click',\n PaginatorPage = 'paginator-page-button-click',\n Tag = 'selector-tag-click',\n Service = 'selector-service-click',\n SaveOnly = 'save-only-button-click',\n}\n\nexport type FetchArgs = {\n page?: number;\n query: Query;\n};\n\nexport interface QAProps {\n qa?: string;\n}\n\ntype FilterConfigBase = {\n /** The key used in queryParams and passed to handleLoadData query */\n queryParamName: string;\n /** Optional analytics events fired when this control's value changes */\n analyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SelectFilterCloseData = {\n selectedValues: string[];\n changesCount: number;\n};\n\nexport type DynamicAnalyticsEventsProp<T> =\n | AnalyticsEventsProp\n | ((data: T) => AnalyticsEventsProp);\n\nexport type SelectFilterConfig = FilterConfigBase &\n Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {\n type?: 'select';\n /** The selectable items for this filter */\n options: SelectOption[];\n /** Label shown when nothing is selected (acts as \"All ...\" placeholder) */\n allLabel: string;\n /** Optional QA attribute forwarded to the switcher */\n qa?: string;\n /** Optional analytics events fired when the select opens */\n openAnalyticsEvents?: AnalyticsEventsProp;\n /** Optional analytics events fired when the select closes */\n closeAnalyticsEvents?: DynamicAnalyticsEventsProp<SelectFilterCloseData>;\n };\n\nexport type SearchFilterConfig = FilterConfigBase & {\n type: 'search';\n /** Placeholder text for the search input */\n placeholder?: string;\n /** Optional analytics events fired when the search input is clicked */\n clickAnalyticsEvents?: AnalyticsEventsProp;\n};\n\nexport type SavedOnlyFilterConfig = FilterConfigBase & {\n type: 'savedOnly';\n /** Optional analytics events fired with the next saved-only state */\n clickAnalyticsEvents?: DynamicAnalyticsEventsProp<boolean>;\n};\n\nexport type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;\n\n/**\n * Filters can be supplied either as a flat array (all filters in one row)\n * or as an array of rows (each inner array is rendered as a separate row).\n *\n * @example Single row (backward-compatible)\n * filters: [searchFilter, tagsFilter]\n *\n * @example Multiple rows\n * filters: [[searchFilter, savedOnlyFilter], [tagsFilter, serviceFilter]]\n */\nexport type FiltersConfig = FilterConfig[] | FilterConfig[][];\n\nexport function normalizeFiltersToRows(filters: FiltersConfig): FilterConfig[][] {\n if (filters.length === 0) {\n return [];\n }\n\n // If the first element is itself an array, the input is already multi-row.\n if (Array.isArray(filters[0])) {\n return filters as FilterConfig[][];\n }\n\n return [filters as FilterConfig[]];\n}\n\nexport enum PostCardSize {\n SMALL = 's',\n MEDIUM = 'm',\n}\n\nexport enum PostCardTitleHeadingLevel {\n H2 = 'h2',\n H3 = 'h3',\n}\n\nexport interface TransformPostOptions {\n plugins?: MarkdownItPluginCb[];\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravity-ui/blog-constructor",
3
- "version": "10.1.1-alpha.0",
3
+ "version": "10.1.1-alpha.1",
4
4
  "description": "Gravity UI Blog Constructor",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",
@@ -171,8 +171,9 @@ type FilterConfigBase = {
171
171
  };
172
172
  export type SelectFilterCloseData = {
173
173
  selectedValues: string[];
174
- selectedValuesOnOpen: string[];
174
+ changesCount: number;
175
175
  };
176
+ export type DynamicAnalyticsEventsProp<T> = AnalyticsEventsProp | ((data: T) => AnalyticsEventsProp);
176
177
  export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple' | 'filterable' | 'hasClear' | 'placeholder'> & {
177
178
  type?: 'select';
178
179
  /** The selectable items for this filter */
@@ -181,22 +182,22 @@ export type SelectFilterConfig = FilterConfigBase & Pick<SelectProps, 'multiple'
181
182
  allLabel: string;
182
183
  /** Optional QA attribute forwarded to the switcher */
183
184
  qa?: string;
184
- /** Optional callback fired when the select opens */
185
- onOpen?: () => void;
186
- /** Optional callback fired when the select closes */
187
- onClose?: (data: SelectFilterCloseData) => void;
185
+ /** Optional analytics events fired when the select opens */
186
+ openAnalyticsEvents?: AnalyticsEventsProp;
187
+ /** Optional analytics events fired when the select closes */
188
+ closeAnalyticsEvents?: DynamicAnalyticsEventsProp<SelectFilterCloseData>;
188
189
  };
189
190
  export type SearchFilterConfig = FilterConfigBase & {
190
191
  type: 'search';
191
192
  /** Placeholder text for the search input */
192
193
  placeholder?: string;
193
- /** Optional callback fired when the search input is clicked */
194
- onClick?: () => void;
194
+ /** Optional analytics events fired when the search input is clicked */
195
+ clickAnalyticsEvents?: AnalyticsEventsProp;
195
196
  };
196
197
  export type SavedOnlyFilterConfig = FilterConfigBase & {
197
198
  type: 'savedOnly';
198
- /** Optional callback fired with the next saved-only state */
199
- onClick?: (state: boolean) => void;
199
+ /** Optional analytics events fired with the next saved-only state */
200
+ clickAnalyticsEvents?: DynamicAnalyticsEventsProp<boolean>;
200
201
  };
201
202
  export type FilterConfig = SelectFilterConfig | SearchFilterConfig | SavedOnlyFilterConfig;
202
203
  /**