discourse/app/assets/javascripts/select-kit/addon/lib/select-kit-prop-utils.js
Kelv 6cda3c728a
DEV: refactor select-kit utils mixin to property-utils lib (#32665)
Follow up to refactoring the generic utils mixin used in select-kit
components in https://github.com/discourse/discourse/pull/32594.

This PR follows a different approach as the util functions related to
properties here aren't easily extracted without a major change to the
interface due to the dependency on `this.selectKit`. These util
functions are instead declared on the prototype with a class decorator
which ensures the same behaviour is maintained without relying on a
mixin.

It's largely a lift-and-shift with some minor refactoring of the
conditional logic to reduce nesting and improve readability of the
functions.
2025-05-23 09:03:10 +08:00

84 lines
2.1 KiB
JavaScript

import { get } from "@ember/object";
export default function selectKitPropUtils(target) {
target.prototype.defaultItem = function (value, name) {
const { valueProperty, nameProperty } = this.selectKit;
if (valueProperty) {
return {
[valueProperty]: value,
[nameProperty]: name,
};
}
return name || value;
};
target.prototype.itemForValue = function (value, content) {
const { valueProperty } = this.selectKit;
if (valueProperty) {
return content.findBy(valueProperty, value);
}
return value;
};
target.prototype.getProperty = function (
item,
property,
options = { definedOnly: true }
) {
if (!item) {
return null;
}
if (item && typeof property === "string") {
const attempt = get(item, property);
if (attempt) {
return attempt;
}
}
property = get(this.selectKit, property);
if (!property) {
return options.definedOnly ? null : item;
}
if (typeof property === "string") {
return get(item, property);
}
return property(item);
};
target.prototype.getValue = function (item) {
return this.getProperty(item, "valueProperty", { definedOnly: false });
};
target.prototype.getName = function (item) {
return this.getProperty(item, "nameProperty", { definedOnly: false });
};
target.prototype.findValue = function (content, item) {
return this._findInContent(content, item, "valueProperty", (i) =>
this.getValue(i)
);
};
target.prototype.findName = function (content, item) {
return this._findInContent(content, item, "nameProperty", (i) =>
this.getName(i)
);
};
target.prototype._findInContent = function (content, item, type, getterFunc) {
const property = get(this.selectKit, type);
if (!property) {
return content.includes(item) ? item : undefined;
}
if (typeof property === "string") {
return content.findBy(property, getterFunc(item));
}
const name = getterFunc(item);
return content.find((contentItem) => {
return getterFunc(contentItem) === name;
});
};
}