UNPKG

@zag-js/rating-group

Version:

Core logic for the rating-group widget implemented as a state machine

226 lines (224 loc) • 8.12 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/rating-group.connect.ts var rating_group_connect_exports = {}; __export(rating_group_connect_exports, { connect: () => connect }); module.exports = __toCommonJS(rating_group_connect_exports); var import_dom_query = require("@zag-js/dom-query"); var dom = __toESM(require("./rating-group.dom.js")); var import_rating_group = require("./rating-group.anatomy.js"); function connect(service, normalize) { const { context, send, prop, scope, computed } = service; const interactive = computed("isInteractive"); const disabled = computed("isDisabled"); const readOnly = !!prop("readOnly"); const required = !!prop("required"); const value = context.get("value"); const hoveredValue = context.get("hoveredValue"); const translations = prop("translations"); function getItemState(props) { const currentValue = computed("isHovering") ? hoveredValue : value; const equal = Math.ceil(currentValue) === props.index; const highlighted = props.index <= currentValue || equal; const half = equal && Math.abs(currentValue - props.index) === 0.5; return { highlighted, half, checked: equal || value <= 0 && props.index === 1 }; } return { hovering: computed("isHovering"), value, hoveredValue, count: prop("count"), items: Array.from({ length: prop("count") }).map((_, index) => index + 1), setValue(value2) { send({ type: "SET_VALUE", value: value2 }); }, clearValue() { send({ type: "CLEAR_VALUE" }); }, getRootProps() { return normalize.element({ ...import_rating_group.parts.root.attrs, dir: prop("dir"), id: dom.getRootId(scope) }); }, getHiddenInputProps() { return normalize.input({ name: prop("name"), form: prop("form"), type: "text", hidden: true, disabled, readOnly, required: prop("required"), id: dom.getHiddenInputId(scope), defaultValue: value }); }, getLabelProps() { return normalize.label({ ...import_rating_group.parts.label.attrs, dir: prop("dir"), id: dom.getLabelId(scope), "data-disabled": (0, import_dom_query.dataAttr)(disabled), "data-required": (0, import_dom_query.dataAttr)(required), htmlFor: dom.getHiddenInputId(scope), onClick(event) { if (event.defaultPrevented) return; if (!interactive) return; event.preventDefault(); const radioEl = dom.getRadioEl(scope, Math.max(1, context.get("value"))); radioEl?.focus({ preventScroll: true }); } }); }, getControlProps() { return normalize.element({ id: dom.getControlId(scope), ...import_rating_group.parts.control.attrs, dir: prop("dir"), role: "radiogroup", "aria-orientation": "horizontal", "aria-labelledby": dom.getLabelId(scope), "aria-readonly": (0, import_dom_query.ariaAttr)(readOnly), "data-readonly": (0, import_dom_query.dataAttr)(readOnly), "data-disabled": (0, import_dom_query.dataAttr)(disabled), onPointerMove(event) { if (!interactive) return; if (event.pointerType === "touch") return; send({ type: "GROUP_POINTER_OVER" }); }, onPointerLeave(event) { if (!interactive) return; if (event.pointerType === "touch") return; send({ type: "GROUP_POINTER_LEAVE" }); } }); }, getItemState, getItemProps(props) { const { index } = props; const itemState = getItemState(props); const valueText = translations.ratingValueText(index); return normalize.element({ ...import_rating_group.parts.item.attrs, dir: prop("dir"), id: dom.getItemId(scope, index.toString()), role: "radio", tabIndex: (() => { if (readOnly) return itemState.checked ? 0 : void 0; if (disabled) return void 0; return itemState.checked ? 0 : -1; })(), "aria-roledescription": "rating", "aria-label": valueText, "aria-disabled": disabled, "data-disabled": (0, import_dom_query.dataAttr)(disabled), "data-readonly": (0, import_dom_query.dataAttr)(readOnly), "aria-setsize": prop("count"), "aria-checked": itemState.checked, "data-checked": (0, import_dom_query.dataAttr)(itemState.checked), "aria-posinset": index, "data-highlighted": (0, import_dom_query.dataAttr)(itemState.highlighted), "data-half": (0, import_dom_query.dataAttr)(itemState.half), onPointerDown(event) { if (!interactive) return; if (!(0, import_dom_query.isLeftClick)(event)) return; event.preventDefault(); }, onPointerMove(event) { if (!interactive) return; const point = (0, import_dom_query.getEventPoint)(event); const relativePoint = (0, import_dom_query.getRelativePoint)(point, event.currentTarget); const percentX = relativePoint.getPercentValue({ orientation: "horizontal", dir: prop("dir") }); const isMidway = percentX < 0.5; send({ type: "POINTER_OVER", index, isMidway }); }, onKeyDown(event) { if (event.defaultPrevented) return; if (!interactive) return; const keyMap = { ArrowLeft() { send({ type: "ARROW_LEFT" }); }, ArrowRight() { send({ type: "ARROW_RIGHT" }); }, ArrowUp() { send({ type: "ARROW_LEFT" }); }, ArrowDown() { send({ type: "ARROW_RIGHT" }); }, Space() { send({ type: "SPACE", value: index }); }, Home() { send({ type: "HOME" }); }, End() { send({ type: "END" }); } }; const key = (0, import_dom_query.getEventKey)(event, { dir: prop("dir") }); const exec = keyMap[key]; if (exec) { event.preventDefault(); exec(event); } }, onClick() { if (!interactive) return; send({ type: "CLICK", value: index }); }, onFocus() { if (!interactive) return; send({ type: "FOCUS" }); }, onBlur() { if (!interactive) return; send({ type: "BLUR" }); } }); } }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { connect });