@woocommerce/components
Version:
UI components for WooCommerce.
169 lines (168 loc) • 8.95 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* External dependencies
*/
const prop_types_1 = __importDefault(require("prop-types"));
const components_1 = require("@wordpress/components");
const clsx_1 = __importDefault(require("clsx"));
const element_1 = require("@wordpress/element");
const api_fetch_1 = __importDefault(require("@wordpress/api-fetch"));
const i18n_1 = require("@wordpress/i18n");
/**
* Internal dependencies
*/
const search_1 = __importDefault(require("../search"));
const select_control_1 = __importDefault(require("../select-control"));
const utils_1 = require("./utils");
const getScreenReaderText = ({ attributeTerms, config, filter, selectedAttribute, selectedAttributeTerm, }) => {
if (!attributeTerms ||
attributeTerms.length === 0 ||
!selectedAttribute ||
selectedAttribute.length === 0 ||
selectedAttributeTerm === '') {
return '';
}
const rule = Array.isArray(config.rules)
? config.rules.find((configRule) => configRule.value === filter.rule) || {}
: {};
const attributeName = selectedAttribute[0].label;
const termObject = attributeTerms.find(({ key }) => key === selectedAttributeTerm);
const attributeTerm = termObject && termObject.label;
if (!attributeName || !attributeTerm) {
return '';
}
const filterStr = (0, utils_1.backwardsCompatibleCreateInterpolateElement)(
/* eslint-disable-next-line max-len */
/* translators: Sentence fragment describing a product attribute match. Example: "Color Is Not Blue" - attribute = Color, equals = Is Not, value = Blue */
(0, i18n_1.__)('<attribute/> <equals/> <value/>', 'woocommerce'), {
attribute: (0, element_1.createElement)(element_1.Fragment, null, attributeName),
equals: (0, element_1.createElement)(element_1.Fragment, null, rule.label),
value: (0, element_1.createElement)(element_1.Fragment, null, attributeTerm),
});
return (0, utils_1.textContent)((0, utils_1.backwardsCompatibleCreateInterpolateElement)(config.labels.title, {
filter: (0, element_1.createElement)(element_1.Fragment, null, filterStr),
rule: (0, element_1.createElement)(element_1.Fragment, null),
title: (0, element_1.createElement)(element_1.Fragment, null),
}));
};
const AttributeFilter = (props) => {
const { className, config, filter, isEnglish, onFilterChange } = props;
const { rule, value } = filter;
const { labels, rules } = config;
const [selectedAttribute, setSelectedAttribute] = (0, element_1.useState)([]);
// Set selected attribute from filter value (in query string).
(0, element_1.useEffect)(() => {
if (!selectedAttribute.length &&
Array.isArray(value) &&
value[0]) {
(0, api_fetch_1.default)({
path: `/wc-analytics/products/attributes/${value[0]}`,
})
.then(({ id, name }) => [
{
key: id.toString(),
label: name,
},
])
.then(setSelectedAttribute);
}
}, [value, selectedAttribute]);
const [attributeTerms, setAttributeTerms] = (0, element_1.useState)([]);
// Fetch all product attributes on mount.
(0, element_1.useEffect)(() => {
if (!selectedAttribute.length) {
return;
}
setAttributeTerms(false);
(0, api_fetch_1.default)({
path: `/wc-analytics/products/attributes/${selectedAttribute[0].key}/terms?per_page=100`,
})
.then((terms) => terms.map(({ id, name }) => ({
key: id.toString(),
label: name,
})))
.then(setAttributeTerms);
}, [selectedAttribute]);
const [selectedAttributeTerm, setSelectedAttributeTerm] = (0, element_1.useState)(Array.isArray(value) ? value[1] || '' : '');
const screenReaderText = getScreenReaderText({
attributeTerms,
config,
filter,
selectedAttribute,
selectedAttributeTerm,
});
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
return ((0, element_1.createElement)("fieldset", { className: "woocommerce-filters-advanced__line-item", tabIndex: "0" },
(0, element_1.createElement)("legend", { className: "screen-reader-text" }, labels.add || ''),
(0, element_1.createElement)("div", { className: (0, clsx_1.default)('woocommerce-filters-advanced__fieldset', {
'is-english': isEnglish,
}) }, (0, utils_1.backwardsCompatibleCreateInterpolateElement)(labels.title, {
title: (0, element_1.createElement)("span", { className: className }),
rule: ((0, element_1.createElement)(components_1.SelectControl, { className: (0, clsx_1.default)(className, 'woocommerce-filters-advanced__rule'), options: rules, value: rule, onChange: (selectedValue) => onFilterChange({
property: 'rule',
value: selectedValue,
}), "aria-label": labels.rule })),
filter: ((0, element_1.createElement)("div", { className: (0, clsx_1.default)(className, 'woocommerce-filters-advanced__attribute-fieldset') },
!Array.isArray(value) ||
!value.length ||
selectedAttribute.length ? ((0, element_1.createElement)(search_1.default, { className: "woocommerce-filters-advanced__input woocommerce-search", onChange: ([attr]) => {
setSelectedAttribute(attr ? [attr] : []);
setSelectedAttributeTerm('');
onFilterChange({
property: 'value',
value: [attr && attr.key].filter(Boolean),
});
}, type: "attributes", placeholder: (0, i18n_1.__)('Attribute name', 'woocommerce'), multiple: false, selected: selectedAttribute, inlineTags: true, "aria-label": (0, i18n_1.__)('Attribute name', 'woocommerce') })) : ((0, element_1.createElement)(components_1.Spinner, null)),
selectedAttribute.length > 0 &&
(attributeTerms.length ? ((0, element_1.createElement)(element_1.Fragment, null,
(0, element_1.createElement)("span", { className: "woocommerce-filters-advanced__attribute-field-separator" }, "="),
(0, element_1.createElement)(select_control_1.default, { className: "woocommerce-filters-advanced__input woocommerce-search", placeholder: (0, i18n_1.__)('Attribute value', 'woocommerce'), inlineTags: true, isSearchable: true, multiple: false, showAllOnFocus: true, options: attributeTerms, selected: selectedAttributeTerm, onChange: (term) => {
// Clearing the input using delete/backspace causes an empty array to be passed here.
if (typeof term !== 'string') {
term = '';
}
setSelectedAttributeTerm(term);
onFilterChange({
property: 'value',
value: [
selectedAttribute[0]
.key,
term,
].filter(Boolean),
});
} }))) : ((0, element_1.createElement)(components_1.Spinner, null))))),
})),
screenReaderText && ((0, element_1.createElement)("span", { className: "screen-reader-text" }, screenReaderText))));
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
};
AttributeFilter.propTypes = {
/**
* The configuration object for the single filter to be rendered.
*/
config: prop_types_1.default.shape({
labels: prop_types_1.default.shape({
rule: prop_types_1.default.string,
title: prop_types_1.default.string,
filter: prop_types_1.default.string,
}),
rules: prop_types_1.default.arrayOf(prop_types_1.default.object),
input: prop_types_1.default.object,
}).isRequired,
/**
* The activeFilter handed down by AdvancedFilters.
*/
filter: prop_types_1.default.shape({
key: prop_types_1.default.string,
rule: prop_types_1.default.string,
value: prop_types_1.default.arrayOf(prop_types_1.default.oneOfType([prop_types_1.default.string, prop_types_1.default.number])),
}).isRequired,
/**
* Function to be called on update.
*/
onFilterChange: prop_types_1.default.func.isRequired,
};
exports.default = AttributeFilter;