@aotearoan/neon
Version:
Neon is a lightweight design library of Vue 3 components with minimal dependencies.
139 lines (138 loc) • 5.1 kB
JavaScript
import { defineComponent as F, ref as m, computed as a, watch as k } from "vue";
import x from "../button/NeonButton.vue.es.js";
import T from "../../presentation/dropdown/NeonDropdown.vue.es.js";
import q from "../field-group/NeonFieldGroup.vue.es.js";
import z from "../input/NeonInput.vue.es.js";
import B from "../../navigation/link/NeonLink.vue.es.js";
import D from "../../layout/stack/NeonStack.vue.es.js";
import O from "../switch/NeonSwitch.vue.es.js";
import { NeonNumberUtils as d } from "../../../utils/common/number/NeonNumberUtils.es.js";
import { NeonSize as _ } from "../../../model/common/size/NeonSize.es.js";
import { NeonFunctionalColor as A } from "../../../model/common/color/NeonFunctionalColor.es.js";
const W = F({
name: "NeonFilter",
components: {
NeonButton: x,
NeonDropdown: T,
NeonFieldGroup: q,
NeonInput: z,
NeonLink: B,
NeonStack: D,
NeonSwitch: O
},
props: {
/**
* The list of filter items.
*/
modelValue: { type: Array, required: !0 },
/**
* The button label. This should conform to an i18n pluralization format,
* e.g. 'Artists | {itemLabel} | {count} artists'.
* There are two placeholders: {itemLabel} - the name of the item and {count} the count of selected items.
* NOTE: In the case nothing is selected the label should just be the filter label, e.g. 'Artists' instead of '0 Artists'.
*/
label: { type: String, required: !0 },
/**
* The color of the component.
*/
color: { type: String, default: () => A.HighContrast },
/**
* The size of the dropdown button.
*/
size: { type: String, default: () => _.Small },
/**
* The disabled state of the filter buttons
*/
disabled: { type: Boolean, default: !1 },
/**
* Button title when items are selected.
*/
editTitle: { type: String, default: "Edit" },
/**
* Clear button title.
*/
clearTitle: { type: String, default: "Clear" },
/**
* The reset filter CTA label.
*/
resetLabel: { type: String, default: "Reset filter" },
/**
* The checkbox list filter placeholder text.
*/
placeholder: { type: String, default: "Search" },
/**
* The close CTA label.
*/
closeLabel: { type: String, default: "Close" },
/**
* The show 'n' items CTA label. This should adhere to the vue-i18n pluralization format
* e.g. 'Show {count} items | Show {count} item | Show {count} items'.
* There is one placeholder: {count} - the count of items matching this filter.
*/
showLabel: { type: String, default: "Show {count} items | Show {count} item | Show {count} items" }
},
emits: [
/**
* Emitted when the close CTA is clicked.
*/
"close",
/**
* Emitted when the selection is changed & the 'Show' CTA is triggered.
*
* @type {Array<NeonFilterItem>} - The filtered items.
*/
"update:modelValue"
],
setup(o, { emit: f }) {
const p = m(!1), b = () => o.modelValue.map((e) => ({ ...e })), l = m(b()), u = m(""), v = a(() => {
if (u.value === "")
return [...l.value];
const e = u.value.toLowerCase();
return [...l.value.filter((t) => t.label.toLowerCase().indexOf(e) >= 0)];
}), n = a(() => o.modelValue.filter((e) => e.selected)), g = a(() => v.value.filter((e) => e.selected)), i = a(
() => l.value.filter((e) => e.selected)
), c = a(() => (i.value.length > 0 ? i.value : l.value).map((t) => t.count).reduce((t, r) => t + r, 0)), s = a(() => !(n.value.length === g.value.length && n.value.map((e) => e.label).every((e) => i.value.map((t) => t.label).indexOf(e) >= 0))), N = () => {
l.value = l.value.map((e) => ({ ...e, selected: !1 }));
}, h = (e) => {
const t = l.value.find((r) => r.label === e);
t && (t.selected = !t.selected, l.value = [...l.value]);
}, y = () => {
s.value && f("update:modelValue", l.value), p.value = !1;
}, w = a(() => o.label.split("|").map((t) => t.trim())[0]), L = a(() => {
var S;
const e = o.label.split("|").map((I) => I.trim()), t = n.value.length;
return e[t > 1 ? 2 : t].replace("{count}", d.formatNumber(t)).replace("{itemLabel}", (S = n.value[0]) == null ? void 0 : S.label);
}), C = a(() => {
const t = o.showLabel.split("|").map((r) => r.trim())[c.value > 1 ? 2 : c.value];
return s.value ? t.replace("{count}", d.formatNumber(c.value)) : o.closeLabel;
}), V = () => {
const e = o.modelValue.map((t) => ({ ...t, selected: !1 }));
f("update:modelValue", e);
};
return k(
() => o.modelValue,
() => {
l.value = b();
},
{ deep: !0 }
), {
open: p,
filterString: u,
filteredItems: v,
isDirty: s,
computedLabel: L,
computedShowLabel: C,
computedTitle: w,
selected: n,
clearSelection: V,
resetFilter: N,
toggleSelected: h,
ctaClick: y,
formatNumber: d.formatNumber
};
}
});
export {
W as default
};
//# sourceMappingURL=NeonFilter.es.js.map