All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.dist.index.mjs Maven / Gradle / Ivy

The newest version!
import { createAnatomy } from '@zag-js/anatomy';
import { createScope } from '@zag-js/dom-query';
import { createMachine } from '@zag-js/core';
import { createSplitProps, compact, isNumber } from '@zag-js/utils';
import { createProps } from '@zag-js/types';

// src/progress.anatomy.ts
var anatomy = createAnatomy("progress").parts(
  "root",
  "label",
  "track",
  "range",
  "valueText",
  "view",
  "circle",
  "circleTrack",
  "circleRange"
);
var parts = anatomy.build();
var dom = createScope({
  getRootId: (ctx) => ctx.ids?.root ?? `progress-${ctx.id}`,
  getTrackId: (ctx) => ctx.ids?.track ?? `progress-${ctx.id}-track`,
  getLabelId: (ctx) => ctx.ids?.label ?? `progress-${ctx.id}-label`,
  getCircleId: (ctx) => ctx.ids?.circle ?? `progress-${ctx.id}-circle`
});

// src/progress.connect.ts
function connect(state, send, normalize) {
  const percent = state.context.percent;
  const percentAsString = state.context.isIndeterminate ? "" : `${percent}%`;
  const max = state.context.max;
  const min = state.context.min;
  const orientation = state.context.orientation;
  const translations = state.context.translations;
  const indeterminate = state.context.isIndeterminate;
  const value = state.context.value;
  const valueAsString = translations.value({ value, max, percent, min });
  const progressState = getProgressState(value, max);
  const progressbarProps = {
    role: "progressbar",
    "aria-label": valueAsString,
    "data-max": max,
    "aria-valuemin": min,
    "aria-valuemax": max,
    "aria-valuenow": value ?? void 0,
    "data-orientation": orientation,
    "data-state": progressState
  };
  const circleProps = getCircleProps(state.context);
  return {
    value,
    valueAsString,
    min,
    max,
    percent,
    percentAsString,
    indeterminate,
    setValue(value2) {
      send({ type: "VALUE.SET", value: value2 });
    },
    setToMax() {
      send({ type: "VALUE.SET", value: max });
    },
    setToMin() {
      send({ type: "VALUE.SET", value: min });
    },
    getRootProps() {
      return normalize.element({
        dir: state.context.dir,
        ...parts.root.attrs,
        id: dom.getRootId(state.context),
        "data-max": max,
        "data-value": value ?? void 0,
        "data-state": progressState,
        "data-orientation": orientation,
        style: {
          "--percent": indeterminate ? void 0 : percent
        }
      });
    },
    getLabelProps() {
      return normalize.element({
        dir: state.context.dir,
        id: dom.getLabelId(state.context),
        ...parts.label.attrs,
        "data-orientation": orientation
      });
    },
    getValueTextProps() {
      return normalize.element({
        dir: state.context.dir,
        "aria-live": "polite",
        ...parts.valueText.attrs
      });
    },
    getTrackProps() {
      return normalize.element({
        dir: state.context.dir,
        id: dom.getTrackId(state.context),
        ...parts.track.attrs,
        ...progressbarProps
      });
    },
    getRangeProps() {
      return normalize.element({
        dir: state.context.dir,
        ...parts.range.attrs,
        "data-orientation": orientation,
        "data-state": progressState,
        style: {
          [state.context.isHorizontal ? "width" : "height"]: indeterminate ? void 0 : `${percent}%`
        }
      });
    },
    getCircleProps() {
      return normalize.element({
        dir: state.context.dir,
        id: dom.getCircleId(state.context),
        ...parts.circle.attrs,
        ...progressbarProps,
        ...circleProps.root
      });
    },
    getCircleTrackProps() {
      return normalize.element({
        dir: state.context.dir,
        "data-orientation": orientation,
        ...parts.circleTrack.attrs,
        ...circleProps.track
      });
    },
    getCircleRangeProps() {
      return normalize.element({
        dir: state.context.dir,
        ...parts.circleRange.attrs,
        ...circleProps.range,
        "data-state": progressState
      });
    },
    getViewProps(props2) {
      return normalize.element({
        dir: state.context.dir,
        ...parts.view.attrs,
        "data-state": props2.state,
        hidden: props2.state !== progressState
      });
    }
  };
}
function getProgressState(value, maxValue) {
  return value == null ? "indeterminate" : value === maxValue ? "complete" : "loading";
}
function getCircleProps(ctx) {
  const circleProps = {
    style: {
      "--radius": "calc(var(--size) / 2 - var(--thickness) / 2)",
      cx: "calc(var(--size) / 2)",
      cy: "calc(var(--size) / 2)",
      r: "var(--radius)",
      fill: "transparent",
      strokeWidth: "var(--thickness)"
    }
  };
  return {
    root: {
      style: {
        width: "var(--size)",
        height: "var(--size)"
      }
    },
    track: circleProps,
    range: {
      opacity: ctx.value === 0 ? 0 : void 0,
      style: {
        ...circleProps.style,
        "--percent": ctx.percent,
        "--circumference": `calc(2 * 3.14159 * var(--radius))`,
        "--offset": `calc(var(--circumference) * (100 - var(--percent)) / 100)`,
        strokeDashoffset: `calc(var(--circumference) * ((100 - var(--percent)) / 100))`,
        strokeDasharray: ctx.isIndeterminate ? void 0 : `var(--circumference)`,
        transformOrigin: "center",
        transform: "rotate(-90deg)"
      }
    }
  };
}
function midValue(min, max) {
  return min + (max - min) / 2;
}
function machine(userContext) {
  const ctx = compact(userContext);
  return createMachine(
    {
      id: "progress",
      initial: "idle",
      context: {
        max: ctx.max ?? 100,
        min: ctx.min ?? 0,
        value: midValue(ctx.min ?? 0, ctx.max ?? 100),
        orientation: "horizontal",
        translations: {
          value: ({ percent }) => percent === -1 ? "loading..." : `${percent} percent`,
          ...ctx.translations
        },
        ...ctx
      },
      created: ["validateContext"],
      computed: {
        isIndeterminate: (ctx2) => ctx2.value === null,
        percent(ctx2) {
          if (!isNumber(ctx2.value)) return -1;
          return Math.round((ctx2.value - ctx2.min) / (ctx2.max - ctx2.min) * 100);
        },
        isAtMax: (ctx2) => ctx2.value === ctx2.max,
        isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
        isRtl: (ctx2) => ctx2.dir === "rtl"
      },
      states: {
        idle: {
          on: {
            "VALUE.SET": {
              actions: ["setValue"]
            }
          }
        }
      }
    },
    {
      actions: {
        setValue: (ctx2, evt) => {
          ctx2.value = evt.value === null ? null : Math.max(0, Math.min(evt.value, ctx2.max));
        },
        validateContext: (ctx2) => {
          if (ctx2.value == null) return;
          if (!isValidNumber(ctx2.max)) {
            throw new Error(`[progress] The max value passed \`${ctx2.max}\` is not a valid number`);
          }
          if (!isValidMax(ctx2.value, ctx2.max)) {
            throw new Error(`[progress] The value passed \`${ctx2.value}\` exceeds the max value \`${ctx2.max}\``);
          }
          if (!isValidMin(ctx2.value, ctx2.min)) {
            throw new Error(`[progress] The value passed \`${ctx2.value}\` exceeds the min value \`${ctx2.min}\``);
          }
        }
      }
    }
  );
}
function isValidNumber(max) {
  return isNumber(max) && !isNaN(max);
}
function isValidMax(value, max) {
  return isValidNumber(value) && value <= max;
}
function isValidMin(value, min) {
  return isValidNumber(value) && value >= min;
}
var props = createProps()([
  "dir",
  "getRootNode",
  "id",
  "ids",
  "max",
  "min",
  "orientation",
  "translations",
  "value"
]);
var splitProps = createSplitProps(props);

export { anatomy, connect, machine, props, splitProps };




© 2015 - 2025 Weber Informatics LLC | Privacy Policy