UNPKG

@agnos-ui/core

Version:

Framework-agnostic headless component library.

181 lines (180 loc) 6.09 kB
"use strict"; const tansu = require("@amadeus-it-group/tansu"); const types = require("./types.cjs"); const utils_directive = require("./dom-CuBx1JPZ.cjs"); const utils_writables = require("./writables-Bn3uhKEG.cjs"); const utils_func = require("./utils/func.cjs"); const utils_stores = require("./utils/stores.cjs"); const utils_widget = require("./utils/widget.cjs"); const defaultConfig = { rating: 0, tabindex: 0, maxRating: 10, disabled: false, readonly: false, resettable: true, ariaValueTextFn: (rating, maxRating) => `${rating} out of ${maxRating}`, onHover: utils_func.noop, onLeave: utils_func.noop, onRatingChange: utils_func.noop, className: "", ariaLabel: "Rating", ariaLabelledBy: "" }; function getRatingDefaultConfig() { return { ...defaultConfig }; } const configValidator = { rating: utils_writables.typeNumber, tabindex: utils_writables.typeNumber, maxRating: { normalizeValue: (value) => utils_writables.isNumber(value) ? Math.max(0, value) : types.INVALID_VALUE }, disabled: utils_writables.typeBoolean, readonly: utils_writables.typeBoolean, resettable: utils_writables.typeBoolean, ariaValueTextFn: utils_writables.typeFunction, onHover: utils_writables.typeFunction, onLeave: utils_writables.typeFunction, onRatingChange: utils_writables.typeFunction, className: utils_writables.typeString, ariaLabel: utils_writables.typeString, ariaLabelledBy: utils_writables.typeString }; const createRating = utils_widget.createWidgetFactory("rating", (config) => { const [ { // dirty inputs that need adjustment: rating$: _dirtyRating$, tabindex$: _dirtyTabindex$, ariaValueTextFn$, onHover$, onLeave$, onRatingChange$, ...stateProps }, patch ] = utils_stores.writablesForProps(defaultConfig, config, configValidator); const { ariaLabel$, ariaLabelledBy$, className$, disabled$, maxRating$, readonly$, resettable$ } = stateProps; const tabindex$ = tansu.computed(() => disabled$() ? -1 : _dirtyTabindex$()); const rating$ = utils_stores.bindableProp(_dirtyRating$, onRatingChange$, (dirtyRating) => utils_writables.clamp(dirtyRating, maxRating$(), 0)); const _hoveredRating$ = tansu.writable(0); const interactive$ = tansu.computed(() => !disabled$() && !readonly$()); const visibleRating$ = tansu.computed(() => { const hoveredRating = _hoveredRating$(); return hoveredRating !== 0 ? hoveredRating : rating$(); }); const ariaValueText$ = tansu.computed(() => ariaValueTextFn$()(visibleRating$(), maxRating$())); const stars$ = tansu.computed(() => { const visibleRating = visibleRating$(); return Array.from({ length: maxRating$() }, (_v, i) => ({ fill: Math.round(Math.max(Math.min(visibleRating - i, 1), 0) * 100), index: i })); }); const widget = { ...utils_stores.stateStores({ ariaValueText$, interactive$, rating$, stars$, tabindex$, visibleRating$, ...stateProps }), patch, directives: { containerDirective: utils_directive.createAttributesDirective(() => ({ events: { keydown: (event) => { if (interactive$()) { const { key } = event; switch (key) { case "ArrowLeft": case "ArrowDown": rating$.update((rating) => rating - 1); break; case "ArrowRight": case "ArrowUp": rating$.update((rating) => rating + 1); break; case "Home": case "PageDown": rating$.set(0); break; case "End": case "PageUp": rating$.set(maxRating$()); break; default: return; } event.preventDefault(); event.stopPropagation(); } }, mouseleave: () => { if (interactive$()) { widget.api.leave(); } } }, attributes: { role: tansu.readable("slider"), class: className$, "aria-valuemin": tansu.readable(0), tabindex: tabindex$, "aria-valuemax": maxRating$, "aria-valuenow": visibleRating$, "aria-valuetext": ariaValueText$, "aria-readonly": tansu.computed(() => readonly$() ? "true" : void 0), "aria-disabled": tansu.computed(() => disabled$() ? "true" : void 0), "aria-label": ariaLabel$, "aria-labelledby": tansu.computed(() => ariaLabelledBy$() || void 0) }, classNames: { "au-rating": utils_stores.true$ } })), starDirective: utils_directive.createAttributesDirective((starContext$) => { return { events: { mouseenter: () => { const index = starContext$().index + 1; if (interactive$() && index > 0 && index <= maxRating$()) { _hoveredRating$.set(index); onHover$()(index); } }, click: () => { const index = starContext$().index + 1; if (interactive$() && index > 0 && index <= maxRating$()) { rating$.update((rating) => rating === index && resettable$() ? 0 : index); } } }, styles: { cursor: tansu.computed(() => interactive$() ? "pointer" : "default") }, classNames: { "au-rating-star": utils_stores.true$ } }; }) }, api: { setRating(index) { rating$.set(index); }, setHoveredRating(index) { onHover$()(index); _hoveredRating$.set(index); }, leave() { onLeave$()(visibleRating$()); _hoveredRating$.set(0); } } }; return widget; }); exports.createRating = createRating; exports.getRatingDefaultConfig = getRatingDefaultConfig;