@nation-a/ui 0.9.2 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -790,12 +790,23 @@ var isString = (v2) => typeof v2 === "string";
790
790
  var isFunction = (v2) => typeof v2 === "function";
791
791
  var fnToString = Function.prototype.toString;
792
792
  fnToString.call(Object);
793
+ var runIfFn = (v2, ...a) => {
794
+ const res = typeof v2 === "function" ? v2(...a) : v2;
795
+ return res ?? void 0;
796
+ };
793
797
  var identity = (v2) => v2();
794
798
  var callAll = (...fns2) => (...a) => {
795
799
  fns2.forEach(function(fn) {
796
800
  fn == null ? void 0 : fn(...a);
797
801
  });
798
802
  };
803
+ var uuid = /* @__PURE__ */ (() => {
804
+ let id = 0;
805
+ return () => {
806
+ id++;
807
+ return id.toString(36);
808
+ };
809
+ })();
799
810
  function compact(obj) {
800
811
  if (!isPlainObject2(obj) || obj === void 0) return obj;
801
812
  const keys = Reflect.ownKeys(obj).filter((key) => typeof key === "string");
@@ -811,6 +822,19 @@ function compact(obj) {
811
822
  var isPlainObject2 = (v2) => {
812
823
  return v2 && typeof v2 === "object" && v2.constructor === Object;
813
824
  };
825
+ function setRafTimeout(callback, delay2) {
826
+ const start2 = performance.now();
827
+ let handle;
828
+ function loop2(now) {
829
+ handle = requestAnimationFrame(loop2);
830
+ const delta = now - start2;
831
+ if (delta >= delay2) {
832
+ callback();
833
+ }
834
+ }
835
+ handle = requestAnimationFrame(loop2);
836
+ return () => cancelAnimationFrame(handle);
837
+ }
814
838
  function warn(...a) {
815
839
  const m2 = a.length === 1 ? a[0] : a[1];
816
840
  const c = a.length === 2 ? a[0] : true;
@@ -821,7 +845,16 @@ function warn(...a) {
821
845
  function ensure(c, m2) {
822
846
  if (c == null) throw new Error(m2);
823
847
  }
848
+ function ensureProps(props, keys, scope) {
849
+ let missingKeys = [];
850
+ for (const key of keys) {
851
+ if (props[key] == null) missingKeys.push(key);
852
+ }
853
+ if (missingKeys.length > 0)
854
+ throw new Error(`[zag-js${` > ${scope}`}] missing required props: ${missingKeys.join(", ")}`);
855
+ }
824
856
  var isObject = (v2) => typeof v2 === "object" && v2 !== null;
857
+ var MAX_Z_INDEX = 2147483647;
825
858
  var dataAttr = (guard) => guard ? "" : void 0;
826
859
  var ELEMENT_NODE = 1;
827
860
  var DOCUMENT_NODE = 9;
@@ -2096,6 +2129,27 @@ function trackDismissableElement(nodeOrFn, options) {
2096
2129
  cleanups2.forEach((fn) => fn == null ? void 0 : fn());
2097
2130
  };
2098
2131
  }
2132
+ function trackDismissableBranch(nodeOrFn, options = {}) {
2133
+ const { defer } = options;
2134
+ const func = defer ? raf$2 : (v2) => v2();
2135
+ const cleanups2 = [];
2136
+ cleanups2.push(
2137
+ func(() => {
2138
+ const node = isFunction(nodeOrFn) ? nodeOrFn() : nodeOrFn;
2139
+ if (!node) {
2140
+ warn("[@zag-js/dismissable] branch node is `null` or `undefined`");
2141
+ return;
2142
+ }
2143
+ layerStack.addBranch(node);
2144
+ cleanups2.push(() => {
2145
+ layerStack.removeBranch(node);
2146
+ });
2147
+ })
2148
+ );
2149
+ return () => {
2150
+ cleanups2.forEach((fn) => fn == null ? void 0 : fn());
2151
+ };
2152
+ }
2099
2153
  const [RenderStrategyPropsProvider, useRenderStrategyPropsContext] = createContext({
2100
2154
  name: "RenderStrategyContext",
2101
2155
  hookName: "useRenderStrategyContext",
@@ -2129,7 +2183,7 @@ const [PresenceProvider, usePresenceContext] = createContext({
2129
2183
  providerName: "<PresenceProvider />"
2130
2184
  });
2131
2185
  const splitPresenceProps = (props) => createSplitProps()(props, ["immediate", "lazyMount", "onExitComplete", "present", "unmountOnExit"]);
2132
- function connect$2(service, _normalize) {
2186
+ function connect$3(service, _normalize) {
2133
2187
  const { state, send, context: context2 } = service;
2134
2188
  const present = state.matches("mounted", "unmountSuspended");
2135
2189
  return {
@@ -2144,7 +2198,7 @@ function connect$2(service, _normalize) {
2144
2198
  }
2145
2199
  };
2146
2200
  }
2147
- var machine$2 = createMachine({
2201
+ var machine$3 = createMachine({
2148
2202
  props({ props: props2 }) {
2149
2203
  return { ...props2, present: !!props2.present };
2150
2204
  },
@@ -2311,8 +2365,8 @@ const usePresence = (props = {}) => {
2311
2365
  present,
2312
2366
  onExitComplete: useEvent(props.onExitComplete)
2313
2367
  };
2314
- const service = useMachine(machine$2, machineProps);
2315
- const api = connect$2(service);
2368
+ const service = useMachine(machine$3, machineProps);
2369
+ const api = connect$3(service);
2316
2370
  if (api.present) {
2317
2371
  wasEverPresent.current = true;
2318
2372
  }
@@ -2928,7 +2982,7 @@ var FocusTrap = class {
2928
2982
  nextTabbableNode
2929
2983
  };
2930
2984
  });
2931
- this.state.tabbableGroups = this.state.containerGroups.filter((group) => group.tabbableNodes.length > 0);
2985
+ this.state.tabbableGroups = this.state.containerGroups.filter((group2) => group2.tabbableNodes.length > 0);
2932
2986
  if (this.state.tabbableGroups.length <= 0 && !this.getNodeForOption("fallbackFocus")) {
2933
2987
  throw new Error(
2934
2988
  "Your focus-trap must have at least one container with at least one tabbable node in it at all times"
@@ -3091,7 +3145,7 @@ function preventBodyScroll(_document) {
3091
3145
  body.removeAttribute(LOCK_CLASSNAME);
3092
3146
  };
3093
3147
  }
3094
- var anatomy$1 = createAnatomy("dialog").parts(
3148
+ var anatomy$2 = createAnatomy("dialog").parts(
3095
3149
  "trigger",
3096
3150
  "backdrop",
3097
3151
  "positioner",
@@ -3100,7 +3154,7 @@ var anatomy$1 = createAnatomy("dialog").parts(
3100
3154
  "description",
3101
3155
  "closeTrigger"
3102
3156
  );
3103
- var parts$1 = anatomy$1.build();
3157
+ var parts$2 = anatomy$2.build();
3104
3158
  var getPositionerId = (ctx2) => {
3105
3159
  var _a;
3106
3160
  return ((_a = ctx2.ids) == null ? void 0 : _a.positioner) ?? `dialog:${ctx2.id}:positioner`;
@@ -3117,15 +3171,15 @@ var getTriggerId$1 = (ctx2) => {
3117
3171
  var _a;
3118
3172
  return ((_a = ctx2.ids) == null ? void 0 : _a.trigger) ?? `dialog:${ctx2.id}:trigger`;
3119
3173
  };
3120
- var getTitleId = (ctx2) => {
3174
+ var getTitleId$1 = (ctx2) => {
3121
3175
  var _a;
3122
3176
  return ((_a = ctx2.ids) == null ? void 0 : _a.title) ?? `dialog:${ctx2.id}:title`;
3123
3177
  };
3124
- var getDescriptionId = (ctx2) => {
3178
+ var getDescriptionId$1 = (ctx2) => {
3125
3179
  var _a;
3126
3180
  return ((_a = ctx2.ids) == null ? void 0 : _a.description) ?? `dialog:${ctx2.id}:description`;
3127
3181
  };
3128
- var getCloseTriggerId = (ctx2) => {
3182
+ var getCloseTriggerId$1 = (ctx2) => {
3129
3183
  var _a;
3130
3184
  return ((_a = ctx2.ids) == null ? void 0 : _a.closeTrigger) ?? `dialog:${ctx2.id}:close`;
3131
3185
  };
@@ -3133,10 +3187,10 @@ var getContentEl$1 = (ctx2) => ctx2.getById(getContentId$1(ctx2));
3133
3187
  var getPositionerEl = (ctx2) => ctx2.getById(getPositionerId(ctx2));
3134
3188
  var getBackdropEl = (ctx2) => ctx2.getById(getBackdropId(ctx2));
3135
3189
  var getTriggerEl$1 = (ctx2) => ctx2.getById(getTriggerId$1(ctx2));
3136
- var getTitleEl = (ctx2) => ctx2.getById(getTitleId(ctx2));
3137
- var getDescriptionEl = (ctx2) => ctx2.getById(getDescriptionId(ctx2));
3138
- var getCloseTriggerEl = (ctx2) => ctx2.getById(getCloseTriggerId(ctx2));
3139
- function connect$1(service, normalize) {
3190
+ var getTitleEl = (ctx2) => ctx2.getById(getTitleId$1(ctx2));
3191
+ var getDescriptionEl = (ctx2) => ctx2.getById(getDescriptionId$1(ctx2));
3192
+ var getCloseTriggerEl = (ctx2) => ctx2.getById(getCloseTriggerId$1(ctx2));
3193
+ function connect$2(service, normalize) {
3140
3194
  const { state, send, context: context2, prop, scope } = service;
3141
3195
  const ariaLabel = prop("aria-label");
3142
3196
  const open = state.matches("open");
@@ -3149,7 +3203,7 @@ function connect$1(service, normalize) {
3149
3203
  },
3150
3204
  getTriggerProps() {
3151
3205
  return normalize.button({
3152
- ...parts$1.trigger.attrs,
3206
+ ...parts$2.trigger.attrs,
3153
3207
  dir: prop("dir"),
3154
3208
  id: getTriggerId$1(scope),
3155
3209
  "aria-haspopup": "dialog",
@@ -3165,7 +3219,7 @@ function connect$1(service, normalize) {
3165
3219
  },
3166
3220
  getBackdropProps() {
3167
3221
  return normalize.element({
3168
- ...parts$1.backdrop.attrs,
3222
+ ...parts$2.backdrop.attrs,
3169
3223
  dir: prop("dir"),
3170
3224
  hidden: !open,
3171
3225
  id: getBackdropId(scope),
@@ -3174,7 +3228,7 @@ function connect$1(service, normalize) {
3174
3228
  },
3175
3229
  getPositionerProps() {
3176
3230
  return normalize.element({
3177
- ...parts$1.positioner.attrs,
3231
+ ...parts$2.positioner.attrs,
3178
3232
  dir: prop("dir"),
3179
3233
  id: getPositionerId(scope),
3180
3234
  style: {
@@ -3185,7 +3239,7 @@ function connect$1(service, normalize) {
3185
3239
  getContentProps() {
3186
3240
  const rendered = context2.get("rendered");
3187
3241
  return normalize.element({
3188
- ...parts$1.content.attrs,
3242
+ ...parts$2.content.attrs,
3189
3243
  dir: prop("dir"),
3190
3244
  role: prop("role"),
3191
3245
  hidden: !open,
@@ -3194,29 +3248,29 @@ function connect$1(service, normalize) {
3194
3248
  "data-state": open ? "open" : "closed",
3195
3249
  "aria-modal": true,
3196
3250
  "aria-label": ariaLabel || void 0,
3197
- "aria-labelledby": ariaLabel || !rendered.title ? void 0 : getTitleId(scope),
3198
- "aria-describedby": rendered.description ? getDescriptionId(scope) : void 0
3251
+ "aria-labelledby": ariaLabel || !rendered.title ? void 0 : getTitleId$1(scope),
3252
+ "aria-describedby": rendered.description ? getDescriptionId$1(scope) : void 0
3199
3253
  });
3200
3254
  },
3201
3255
  getTitleProps() {
3202
3256
  return normalize.element({
3203
- ...parts$1.title.attrs,
3257
+ ...parts$2.title.attrs,
3204
3258
  dir: prop("dir"),
3205
- id: getTitleId(scope)
3259
+ id: getTitleId$1(scope)
3206
3260
  });
3207
3261
  },
3208
3262
  getDescriptionProps() {
3209
3263
  return normalize.element({
3210
- ...parts$1.description.attrs,
3264
+ ...parts$2.description.attrs,
3211
3265
  dir: prop("dir"),
3212
- id: getDescriptionId(scope)
3266
+ id: getDescriptionId$1(scope)
3213
3267
  });
3214
3268
  },
3215
3269
  getCloseTriggerProps() {
3216
3270
  return normalize.button({
3217
- ...parts$1.closeTrigger.attrs,
3271
+ ...parts$2.closeTrigger.attrs,
3218
3272
  dir: prop("dir"),
3219
- id: getCloseTriggerId(scope),
3273
+ id: getCloseTriggerId$1(scope),
3220
3274
  type: "button",
3221
3275
  onClick(event) {
3222
3276
  if (event.defaultPrevented) return;
@@ -3227,7 +3281,7 @@ function connect$1(service, normalize) {
3227
3281
  }
3228
3282
  };
3229
3283
  }
3230
- var machine$1 = createMachine({
3284
+ var machine$2 = createMachine({
3231
3285
  props({ props: props2, scope }) {
3232
3286
  const alertDialog = props2.role === "alertdialog";
3233
3287
  const initialFocusEl = alertDialog ? () => getCloseTriggerEl(scope) : void 0;
@@ -3446,8 +3500,8 @@ const useDialog = (props) => {
3446
3500
  dir,
3447
3501
  ...props
3448
3502
  };
3449
- const service = useMachine(machine$1, machineProps);
3450
- return connect$1(service, normalizeProps);
3503
+ const service = useMachine(machine$2, machineProps);
3504
+ return connect$2(service, normalizeProps);
3451
3505
  };
3452
3506
  const DialogRoot = (props) => {
3453
3507
  const [presenceProps, { children, ...localProps }] = splitPresenceProps(props);
@@ -3521,9 +3575,9 @@ const TabTrigger = React.forwardRef((props, ref) => {
3521
3575
  return /* @__PURE__ */ jsxRuntime.jsx(ark.button, { ...mergedProps, ref });
3522
3576
  });
3523
3577
  TabTrigger.displayName = "TabTrigger";
3524
- var anatomy = createAnatomy("tabs").parts("root", "list", "trigger", "content", "indicator");
3525
- var parts = anatomy.build();
3526
- var getRootId = (ctx2) => {
3578
+ var anatomy$1 = createAnatomy("tabs").parts("root", "list", "trigger", "content", "indicator");
3579
+ var parts$1 = anatomy$1.build();
3580
+ var getRootId$1 = (ctx2) => {
3527
3581
  var _a;
3528
3582
  return ((_a = ctx2.ids) == null ? void 0 : _a.root) ?? `tabs:${ctx2.id}`;
3529
3583
  };
@@ -3574,7 +3628,7 @@ var resolveRect = (rect) => ({
3574
3628
  left: `${rect.left}px`,
3575
3629
  top: `${rect.top}px`
3576
3630
  });
3577
- function connect(service, normalize) {
3631
+ function connect$1(service, normalize) {
3578
3632
  const { state, send, context: context2, prop, scope } = service;
3579
3633
  const translations = prop("translations");
3580
3634
  const focused = state.matches("focused");
@@ -3620,8 +3674,8 @@ function connect(service, normalize) {
3620
3674
  },
3621
3675
  getRootProps() {
3622
3676
  return normalize.element({
3623
- ...parts.root.attrs,
3624
- id: getRootId(scope),
3677
+ ...parts$1.root.attrs,
3678
+ id: getRootId$1(scope),
3625
3679
  "data-orientation": prop("orientation"),
3626
3680
  "data-focus": dataAttr(focused),
3627
3681
  dir: prop("dir")
@@ -3629,7 +3683,7 @@ function connect(service, normalize) {
3629
3683
  },
3630
3684
  getListProps() {
3631
3685
  return normalize.element({
3632
- ...parts.list.attrs,
3686
+ ...parts$1.list.attrs,
3633
3687
  id: getListId(scope),
3634
3688
  role: "tablist",
3635
3689
  dir: prop("dir"),
@@ -3685,7 +3739,7 @@ function connect(service, normalize) {
3685
3739
  const { value, disabled } = props2;
3686
3740
  const triggerState = getTriggerState(props2);
3687
3741
  return normalize.button({
3688
- ...parts.trigger.attrs,
3742
+ ...parts$1.trigger.attrs,
3689
3743
  role: "tab",
3690
3744
  type: "button",
3691
3745
  disabled,
@@ -3725,7 +3779,7 @@ function connect(service, normalize) {
3725
3779
  const { value } = props2;
3726
3780
  const selected = context2.get("value") === value;
3727
3781
  return normalize.element({
3728
- ...parts.content.attrs,
3782
+ ...parts$1.content.attrs,
3729
3783
  dir: prop("dir"),
3730
3784
  id: getContentId(scope, value),
3731
3785
  tabIndex: composite ? 0 : -1,
@@ -3742,7 +3796,7 @@ function connect(service, normalize) {
3742
3796
  const indicatorTransition = context2.get("indicatorTransition");
3743
3797
  return normalize.element({
3744
3798
  id: getIndicatorId(scope),
3745
- ...parts.indicator.attrs,
3799
+ ...parts$1.indicator.attrs,
3746
3800
  dir: prop("dir"),
3747
3801
  "data-orientation": prop("orientation"),
3748
3802
  style: {
@@ -3762,8 +3816,8 @@ function connect(service, normalize) {
3762
3816
  }
3763
3817
  };
3764
3818
  }
3765
- var { not } = createGuards();
3766
- var machine = createMachine({
3819
+ var { not: not$1 } = createGuards();
3820
+ var machine$1 = createMachine({
3767
3821
  props({ props: props2 }) {
3768
3822
  return {
3769
3823
  dir: "ltr",
@@ -3886,7 +3940,7 @@ var machine = createMachine({
3886
3940
  }
3887
3941
  ],
3888
3942
  ENTER: {
3889
- guard: not("selectOnFocus"),
3943
+ guard: not$1("selectOnFocus"),
3890
3944
  actions: ["selectFocusedTab"]
3891
3945
  },
3892
3946
  TAB_FOCUS: {
@@ -3989,109 +4043,1192 @@ var machine = createMachine({
3989
4043
  const cleanup = refs.get("indicatorCleanup");
3990
4044
  if (cleanup) cleanup();
3991
4045
  },
3992
- allowIndicatorTransition({ context: context2 }) {
3993
- context2.set("indicatorTransition", true);
4046
+ allowIndicatorTransition({ context: context2 }) {
4047
+ context2.set("indicatorTransition", true);
4048
+ },
4049
+ setIndicatorRect({ context: context2, event, scope }) {
4050
+ const value = event.id ?? context2.get("value");
4051
+ const indicatorEl = getIndicatorEl(scope);
4052
+ if (!indicatorEl || !value) return;
4053
+ const triggerEl = getTriggerEl(scope, value);
4054
+ if (!triggerEl) return;
4055
+ context2.set("indicatorRect", getRectById(scope, value));
4056
+ nextTick(() => {
4057
+ context2.set("indicatorTransition", false);
4058
+ });
4059
+ },
4060
+ syncSsr({ context: context2 }) {
4061
+ context2.set("ssr", false);
4062
+ },
4063
+ syncIndicatorRect({ context: context2, refs, scope }) {
4064
+ const cleanup = refs.get("indicatorCleanup");
4065
+ if (cleanup) cleanup();
4066
+ const value = context2.get("value");
4067
+ if (!value) return;
4068
+ const triggerEl = getTriggerEl(scope, value);
4069
+ const indicatorEl = getIndicatorEl(scope);
4070
+ if (!triggerEl || !indicatorEl) return;
4071
+ const exec = () => {
4072
+ const rect = getOffsetRect(triggerEl);
4073
+ context2.set("indicatorRect", resolveRect(rect));
4074
+ nextTick(() => {
4075
+ context2.set("indicatorTransition", false);
4076
+ });
4077
+ };
4078
+ exec();
4079
+ const win = scope.getWin();
4080
+ const obs = new win.ResizeObserver(exec);
4081
+ obs.observe(triggerEl);
4082
+ refs.set("indicatorCleanup", () => obs.disconnect());
4083
+ },
4084
+ navigateIfNeeded({ context: context2, prop, scope }) {
4085
+ var _a;
4086
+ const value = context2.get("value");
4087
+ if (!value) return;
4088
+ const triggerEl = getTriggerEl(scope, value);
4089
+ if (!isAnchorElement(triggerEl)) return;
4090
+ (_a = prop("navigate")) == null ? void 0 : _a({ value, node: triggerEl });
4091
+ }
4092
+ }
4093
+ }
4094
+ });
4095
+ createProps()([
4096
+ "activationMode",
4097
+ "composite",
4098
+ "deselectable",
4099
+ "dir",
4100
+ "getRootNode",
4101
+ "id",
4102
+ "ids",
4103
+ "loopFocus",
4104
+ "navigate",
4105
+ "onFocusChange",
4106
+ "onValueChange",
4107
+ "orientation",
4108
+ "translations",
4109
+ "value",
4110
+ "defaultValue"
4111
+ ]);
4112
+ createProps()(["disabled", "value"]);
4113
+ createProps()(["value"]);
4114
+ const useTabs = (props) => {
4115
+ const id = React.useId();
4116
+ const { getRootNode } = useEnvironmentContext();
4117
+ const { dir } = useLocaleContext();
4118
+ const machineProps = {
4119
+ id,
4120
+ dir,
4121
+ getRootNode,
4122
+ ...props
4123
+ };
4124
+ const service = useMachine(machine$1, machineProps);
4125
+ return connect$1(service, normalizeProps);
4126
+ };
4127
+ const TabsRoot = React.forwardRef((props, ref) => {
4128
+ const [renderStrategyProps, tabsProps] = splitRenderStrategyProps(props);
4129
+ const [useTabsProps, localprops] = createSplitProps()(tabsProps, [
4130
+ "activationMode",
4131
+ "composite",
4132
+ "defaultValue",
4133
+ "deselectable",
4134
+ "id",
4135
+ "ids",
4136
+ "loopFocus",
4137
+ "navigate",
4138
+ "onFocusChange",
4139
+ "onValueChange",
4140
+ "orientation",
4141
+ "translations",
4142
+ "value"
4143
+ ]);
4144
+ const tabs = useTabs(useTabsProps);
4145
+ const mergedProps = mergeProps(tabs.getRootProps(), localprops);
4146
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsProvider, { value: tabs, children: /* @__PURE__ */ jsxRuntime.jsx(RenderStrategyPropsProvider, { value: renderStrategyProps, children: /* @__PURE__ */ jsxRuntime.jsx(ark.div, { ...mergedProps, ref }) }) });
4147
+ });
4148
+ TabsRoot.displayName = "TabsRoot";
4149
+ var anatomy = createAnatomy("toast").parts(
4150
+ "group",
4151
+ "root",
4152
+ "title",
4153
+ "description",
4154
+ "actionTrigger",
4155
+ "closeTrigger"
4156
+ );
4157
+ var parts = anatomy.build();
4158
+ var getRegionId = (placement) => `toast-group:${placement}`;
4159
+ var getRegionEl = (ctx2, placement) => ctx2.getById(`toast-group:${placement}`);
4160
+ var getRootId = (ctx2) => `toast:${ctx2.id}`;
4161
+ var getRootEl = (ctx2) => ctx2.getById(getRootId(ctx2));
4162
+ var getTitleId = (ctx2) => `toast:${ctx2.id}:title`;
4163
+ var getDescriptionId = (ctx2) => `toast:${ctx2.id}:description`;
4164
+ var getCloseTriggerId = (ctx2) => `toast${ctx2.id}:close`;
4165
+ var defaultTimeouts = {
4166
+ info: 5e3,
4167
+ error: 5e3,
4168
+ success: 2e3,
4169
+ loading: Infinity,
4170
+ DEFAULT: 5e3
4171
+ };
4172
+ function getToastDuration(duration, type) {
4173
+ return duration ?? defaultTimeouts[type] ?? defaultTimeouts.DEFAULT;
4174
+ }
4175
+ var getOffsets = (offsets) => typeof offsets === "string" ? { left: offsets, right: offsets, bottom: offsets, top: offsets } : offsets;
4176
+ function getGroupPlacementStyle(service, placement) {
4177
+ var _a;
4178
+ const { prop, computed, context: context2 } = service;
4179
+ const { offsets, gap } = prop("store").attrs;
4180
+ const heights = context2.get("heights");
4181
+ const computedOffset = getOffsets(offsets);
4182
+ const rtl = prop("dir") === "rtl";
4183
+ const computedPlacement = placement.replace("-start", rtl ? "-right" : "-left").replace("-end", rtl ? "-left" : "-right");
4184
+ const isRighty = computedPlacement.includes("right");
4185
+ const isLefty = computedPlacement.includes("left");
4186
+ const styles = {
4187
+ position: "fixed",
4188
+ pointerEvents: computed("count") > 0 ? void 0 : "none",
4189
+ display: "flex",
4190
+ flexDirection: "column",
4191
+ "--gap": `${gap}px`,
4192
+ "--first-height": `${((_a = heights[0]) == null ? void 0 : _a.height) || 0}px`,
4193
+ zIndex: MAX_Z_INDEX
4194
+ };
4195
+ let alignItems = "center";
4196
+ if (isRighty) alignItems = "flex-end";
4197
+ if (isLefty) alignItems = "flex-start";
4198
+ styles.alignItems = alignItems;
4199
+ if (computedPlacement.includes("top")) {
4200
+ const offset = computedOffset.top;
4201
+ styles.top = `max(env(safe-area-inset-top, 0px), ${offset})`;
4202
+ }
4203
+ if (computedPlacement.includes("bottom")) {
4204
+ const offset = computedOffset.bottom;
4205
+ styles.bottom = `max(env(safe-area-inset-bottom, 0px), ${offset})`;
4206
+ }
4207
+ if (!computedPlacement.includes("left")) {
4208
+ const offset = computedOffset.right;
4209
+ styles.insetInlineEnd = `calc(env(safe-area-inset-right, 0px) + ${offset})`;
4210
+ }
4211
+ if (!computedPlacement.includes("right")) {
4212
+ const offset = computedOffset.left;
4213
+ styles.insetInlineStart = `calc(env(safe-area-inset-left, 0px) + ${offset})`;
4214
+ }
4215
+ return styles;
4216
+ }
4217
+ function getPlacementStyle(service, visible) {
4218
+ const { prop, context: context2, computed } = service;
4219
+ const parent = prop("parent");
4220
+ const placement = parent.computed("placement");
4221
+ const { gap } = parent.prop("store").attrs;
4222
+ const [side] = placement.split("-");
4223
+ const mounted = context2.get("mounted");
4224
+ const remainingTime = context2.get("remainingTime");
4225
+ const height = computed("height");
4226
+ const frontmost = computed("frontmost");
4227
+ const sibling = !frontmost;
4228
+ const overlap = !prop("stacked");
4229
+ const stacked = prop("stacked");
4230
+ const type = prop("type");
4231
+ const duration = type === "loading" ? Number.MAX_SAFE_INTEGER : remainingTime;
4232
+ const offset = computed("heightIndex") * gap + computed("heightBefore");
4233
+ const styles = {
4234
+ position: "absolute",
4235
+ pointerEvents: "auto",
4236
+ "--opacity": "0",
4237
+ "--remove-delay": `${prop("removeDelay")}ms`,
4238
+ "--duration": `${duration}ms`,
4239
+ "--initial-height": `${height}px`,
4240
+ "--offset": `${offset}px`,
4241
+ "--index": prop("index"),
4242
+ "--z-index": computed("zIndex"),
4243
+ "--lift-amount": "calc(var(--lift) * var(--gap))",
4244
+ "--y": "100%",
4245
+ "--x": "0"
4246
+ };
4247
+ const assign2 = (overrides) => Object.assign(styles, overrides);
4248
+ if (side === "top") {
4249
+ assign2({
4250
+ top: "0",
4251
+ "--sign": "-1",
4252
+ "--y": "-100%",
4253
+ "--lift": "1"
4254
+ });
4255
+ } else if (side === "bottom") {
4256
+ assign2({
4257
+ bottom: "0",
4258
+ "--sign": "1",
4259
+ "--y": "100%",
4260
+ "--lift": "-1"
4261
+ });
4262
+ }
4263
+ if (mounted) {
4264
+ assign2({
4265
+ "--y": "0",
4266
+ "--opacity": "1"
4267
+ });
4268
+ if (stacked) {
4269
+ assign2({
4270
+ "--y": "calc(var(--lift) * var(--offset))",
4271
+ "--height": "var(--initial-height)"
4272
+ });
4273
+ }
4274
+ }
4275
+ if (!visible) {
4276
+ assign2({
4277
+ "--opacity": "0",
4278
+ pointerEvents: "none"
4279
+ });
4280
+ }
4281
+ if (sibling && overlap) {
4282
+ assign2({
4283
+ "--base-scale": "var(--index) * 0.05 + 1",
4284
+ "--y": "calc(var(--lift-amount) * var(--index))",
4285
+ "--scale": "calc(-1 * var(--base-scale))",
4286
+ "--height": "var(--first-height)"
4287
+ });
4288
+ if (!visible) {
4289
+ assign2({
4290
+ "--y": "calc(var(--sign) * 40%)"
4291
+ });
4292
+ }
4293
+ }
4294
+ if (sibling && stacked && !visible) {
4295
+ assign2({
4296
+ "--y": "calc(var(--lift) * var(--offset) + var(--lift) * -100%)"
4297
+ });
4298
+ }
4299
+ if (frontmost && !visible) {
4300
+ assign2({
4301
+ "--y": "calc(var(--lift) * -100%)"
4302
+ });
4303
+ }
4304
+ return styles;
4305
+ }
4306
+ function getGhostBeforeStyle(service, visible) {
4307
+ const { computed } = service;
4308
+ const styles = {
4309
+ position: "absolute",
4310
+ inset: "0",
4311
+ scale: "1 2",
4312
+ pointerEvents: visible ? "none" : "auto"
4313
+ };
4314
+ const assign2 = (overrides) => Object.assign(styles, overrides);
4315
+ if (computed("frontmost") && !visible) {
4316
+ assign2({
4317
+ height: "calc(var(--initial-height) + 80%)"
4318
+ });
4319
+ }
4320
+ return styles;
4321
+ }
4322
+ function getGhostAfterStyle() {
4323
+ return {
4324
+ position: "absolute",
4325
+ left: "0",
4326
+ height: "calc(var(--gap) + 2px)",
4327
+ bottom: "100%",
4328
+ width: "100%"
4329
+ };
4330
+ }
4331
+ function groupConnect(service, normalize) {
4332
+ const { context: context2, prop, send, refs, computed } = service;
4333
+ return {
4334
+ getCount() {
4335
+ return context2.get("toasts").length;
4336
+ },
4337
+ getToasts() {
4338
+ return context2.get("toasts");
4339
+ },
4340
+ getGroupProps(options = {}) {
4341
+ const { label = "Notifications" } = options;
4342
+ const { hotkey } = prop("store").attrs;
4343
+ const hotkeyLabel = hotkey.join("+").replace(/Key/g, "").replace(/Digit/g, "");
4344
+ const placement = computed("placement");
4345
+ const [side, align = "center"] = placement.split("-");
4346
+ return normalize.element({
4347
+ ...parts.group.attrs,
4348
+ dir: prop("dir"),
4349
+ tabIndex: -1,
4350
+ "aria-label": `${placement} ${label} ${hotkeyLabel}`,
4351
+ id: getRegionId(placement),
4352
+ "data-placement": placement,
4353
+ "data-side": side,
4354
+ "data-align": align,
4355
+ "aria-live": "polite",
4356
+ role: "region",
4357
+ style: getGroupPlacementStyle(service, placement),
4358
+ onMouseMove() {
4359
+ send({ type: "REGION.POINTER_ENTER", placement });
4360
+ },
4361
+ onMouseLeave() {
4362
+ send({ type: "REGION.POINTER_LEAVE", placement });
4363
+ },
4364
+ onFocus(event) {
4365
+ send({ type: "REGION.FOCUS", target: event.relatedTarget });
4366
+ },
4367
+ onBlur(event) {
4368
+ if (refs.get("isFocusWithin") && !contains(event.currentTarget, event.relatedTarget)) {
4369
+ queueMicrotask(() => send({ type: "REGION.BLUR" }));
4370
+ }
4371
+ }
4372
+ });
4373
+ },
4374
+ subscribe(fn) {
4375
+ const store = prop("store");
4376
+ return store.subscribe(() => fn(context2.get("toasts")));
4377
+ }
4378
+ };
4379
+ }
4380
+ var groupMachine = createMachine({
4381
+ props({ props }) {
4382
+ return {
4383
+ dir: "ltr",
4384
+ id: uuid(),
4385
+ ...props,
4386
+ store: props.store
4387
+ };
4388
+ },
4389
+ initialState({ prop }) {
4390
+ return prop("store").attrs.overlap ? "overlap" : "stack";
4391
+ },
4392
+ refs() {
4393
+ return {
4394
+ lastFocusedEl: null,
4395
+ isFocusWithin: false,
4396
+ dismissableCleanup: void 0
4397
+ };
4398
+ },
4399
+ context({ bindable }) {
4400
+ return {
4401
+ toasts: bindable(() => ({
4402
+ defaultValue: [],
4403
+ sync: true,
4404
+ hash: (toasts) => toasts.map((t) => t.id).join(",")
4405
+ })),
4406
+ heights: bindable(() => ({
4407
+ defaultValue: [],
4408
+ sync: true
4409
+ }))
4410
+ };
4411
+ },
4412
+ computed: {
4413
+ count: ({ context: context2 }) => context2.get("toasts").length,
4414
+ overlap: ({ prop }) => prop("store").attrs.overlap,
4415
+ placement: ({ prop }) => prop("store").attrs.placement
4416
+ },
4417
+ effects: ["subscribeToStore", "trackDocumentVisibility", "trackHotKeyPress"],
4418
+ watch({ track, context: context2, action }) {
4419
+ track([() => context2.hash("toasts")], () => {
4420
+ queueMicrotask(() => {
4421
+ action(["collapsedIfEmpty", "setDismissableBranch"]);
4422
+ });
4423
+ });
4424
+ },
4425
+ exit: ["clearDismissableBranch", "clearLastFocusedEl"],
4426
+ on: {
4427
+ "DOC.HOTKEY": {
4428
+ actions: ["focusRegionEl"]
4429
+ },
4430
+ "REGION.BLUR": [
4431
+ {
4432
+ guard: "isOverlapping",
4433
+ target: "overlap",
4434
+ actions: ["collapseToasts", "resumeToasts", "restoreLastFocusedEl"]
4435
+ },
4436
+ {
4437
+ target: "stack",
4438
+ actions: ["resumeToasts", "restoreLastFocusedEl"]
4439
+ }
4440
+ ],
4441
+ "TOAST.REMOVE": {
4442
+ actions: ["removeToast", "removeHeight"]
4443
+ },
4444
+ "TOAST.PAUSE": {
4445
+ actions: ["pauseToasts"]
4446
+ }
4447
+ },
4448
+ states: {
4449
+ stack: {
4450
+ on: {
4451
+ "REGION.POINTER_LEAVE": [
4452
+ {
4453
+ guard: "isOverlapping",
4454
+ target: "overlap",
4455
+ actions: ["resumeToasts", "collapseToasts"]
4456
+ },
4457
+ {
4458
+ actions: ["resumeToasts"]
4459
+ }
4460
+ ],
4461
+ "REGION.OVERLAP": {
4462
+ target: "overlap",
4463
+ actions: ["collapseToasts"]
4464
+ },
4465
+ "REGION.FOCUS": {
4466
+ actions: ["setLastFocusedEl", "pauseToasts"]
4467
+ },
4468
+ "REGION.POINTER_ENTER": {
4469
+ actions: ["pauseToasts"]
4470
+ }
4471
+ }
4472
+ },
4473
+ overlap: {
4474
+ on: {
4475
+ "REGION.STACK": {
4476
+ target: "stack",
4477
+ actions: ["expandToasts"]
4478
+ },
4479
+ "REGION.POINTER_ENTER": {
4480
+ target: "stack",
4481
+ actions: ["pauseToasts", "expandToasts"]
4482
+ },
4483
+ "REGION.FOCUS": {
4484
+ target: "stack",
4485
+ actions: ["setLastFocusedEl", "pauseToasts", "expandToasts"]
4486
+ }
4487
+ }
4488
+ }
4489
+ },
4490
+ implementations: {
4491
+ guards: {
4492
+ isOverlapping: ({ computed }) => computed("overlap")
4493
+ },
4494
+ effects: {
4495
+ subscribeToStore({ context: context2, prop }) {
4496
+ return prop("store").subscribe((toast2) => {
4497
+ if (toast2.dismiss) {
4498
+ context2.set("toasts", (prev) => prev.filter((t) => t.id !== toast2.id));
4499
+ return;
4500
+ }
4501
+ context2.set("toasts", (prev) => {
4502
+ const index2 = prev.findIndex((t) => t.id === toast2.id);
4503
+ if (index2 !== -1) {
4504
+ return [...prev.slice(0, index2), { ...prev[index2], ...toast2 }, ...prev.slice(index2 + 1)];
4505
+ }
4506
+ return [toast2, ...prev];
4507
+ });
4508
+ });
4509
+ },
4510
+ trackHotKeyPress({ prop, send }) {
4511
+ const handleKeyDown = (event) => {
4512
+ const { hotkey } = prop("store").attrs;
4513
+ const isHotkeyPressed = hotkey.every((key) => event[key] || event.code === key);
4514
+ if (!isHotkeyPressed) return;
4515
+ send({ type: "DOC.HOTKEY" });
4516
+ };
4517
+ return addDomEvent(document, "keydown", handleKeyDown, { capture: true });
4518
+ },
4519
+ trackDocumentVisibility({ prop, send, scope }) {
4520
+ const { pauseOnPageIdle } = prop("store").attrs;
4521
+ if (!pauseOnPageIdle) return;
4522
+ const doc = scope.getDoc();
4523
+ return addDomEvent(doc, "visibilitychange", () => {
4524
+ const isHidden = doc.visibilityState === "hidden";
4525
+ send({ type: isHidden ? "PAUSE_ALL" : "RESUME_ALL" });
4526
+ });
4527
+ }
4528
+ },
4529
+ actions: {
4530
+ setDismissableBranch({ refs, context: context2, computed, scope }) {
4531
+ var _a;
4532
+ const toasts = context2.get("toasts");
4533
+ const placement = computed("placement");
4534
+ const hasToasts = toasts.length > 0;
4535
+ if (!hasToasts) {
4536
+ (_a = refs.get("dismissableCleanup")) == null ? void 0 : _a();
4537
+ return;
4538
+ }
4539
+ if (hasToasts && refs.get("dismissableCleanup")) {
4540
+ return;
4541
+ }
4542
+ const groupEl = () => getRegionEl(scope, placement);
4543
+ const cleanup = trackDismissableBranch(groupEl, { defer: true });
4544
+ refs.set("dismissableCleanup", cleanup);
4545
+ },
4546
+ clearDismissableBranch({ refs }) {
4547
+ var _a;
4548
+ (_a = refs.get("dismissableCleanup")) == null ? void 0 : _a();
4549
+ },
4550
+ focusRegionEl({ scope, computed }) {
4551
+ queueMicrotask(() => {
4552
+ var _a;
4553
+ (_a = getRegionEl(scope, computed("placement"))) == null ? void 0 : _a.focus();
4554
+ });
4555
+ },
4556
+ pauseToasts({ prop }) {
4557
+ prop("store").pause();
4558
+ },
4559
+ resumeToasts({ prop }) {
4560
+ prop("store").resume();
4561
+ },
4562
+ expandToasts({ prop }) {
4563
+ prop("store").expand();
4564
+ },
4565
+ collapseToasts({ prop }) {
4566
+ prop("store").collapse();
4567
+ },
4568
+ removeToast({ prop, event }) {
4569
+ prop("store").remove(event.id);
4570
+ },
4571
+ removeHeight({ event, context: context2 }) {
4572
+ if ((event == null ? void 0 : event.id) == null) return;
4573
+ queueMicrotask(() => {
4574
+ context2.set("heights", (heights) => heights.filter((height) => height.id !== event.id));
4575
+ });
4576
+ },
4577
+ collapsedIfEmpty({ send, computed }) {
4578
+ if (!computed("overlap") || computed("count") > 1) return;
4579
+ send({ type: "REGION.OVERLAP" });
4580
+ },
4581
+ setLastFocusedEl({ refs, event }) {
4582
+ if (refs.get("isFocusWithin") || !event.target) return;
4583
+ refs.set("isFocusWithin", true);
4584
+ refs.set("lastFocusedEl", event.target);
4585
+ },
4586
+ restoreLastFocusedEl({ refs }) {
4587
+ var _a;
4588
+ if (!refs.get("lastFocusedEl")) return;
4589
+ (_a = refs.get("lastFocusedEl")) == null ? void 0 : _a.focus({ preventScroll: true });
4590
+ refs.set("lastFocusedEl", null);
4591
+ refs.set("isFocusWithin", false);
4592
+ },
4593
+ clearLastFocusedEl({ refs }) {
4594
+ var _a;
4595
+ if (!refs.get("lastFocusedEl")) return;
4596
+ (_a = refs.get("lastFocusedEl")) == null ? void 0 : _a.focus({ preventScroll: true });
4597
+ refs.set("lastFocusedEl", null);
4598
+ refs.set("isFocusWithin", false);
4599
+ }
4600
+ }
4601
+ }
4602
+ });
4603
+ function connect(service, normalize) {
4604
+ const { state, send, prop, scope, context: context2, computed } = service;
4605
+ const visible = state.hasTag("visible");
4606
+ const paused = state.hasTag("paused");
4607
+ const mounted = context2.get("mounted");
4608
+ const frontmost = computed("frontmost");
4609
+ const placement = prop("parent").computed("placement");
4610
+ const type = prop("type");
4611
+ const stacked = prop("stacked");
4612
+ const title = prop("title");
4613
+ const description = prop("description");
4614
+ const action = prop("action");
4615
+ const [side, align = "center"] = placement.split("-");
4616
+ return {
4617
+ type,
4618
+ title,
4619
+ description,
4620
+ placement,
4621
+ visible,
4622
+ paused,
4623
+ closable: !!prop("closable"),
4624
+ pause() {
4625
+ send({ type: "PAUSE" });
4626
+ },
4627
+ resume() {
4628
+ send({ type: "RESUME" });
4629
+ },
4630
+ dismiss() {
4631
+ send({ type: "DISMISS", src: "programmatic" });
4632
+ },
4633
+ getRootProps() {
4634
+ return normalize.element({
4635
+ ...parts.root.attrs,
4636
+ dir: prop("dir"),
4637
+ id: getRootId(scope),
4638
+ "data-state": visible ? "open" : "closed",
4639
+ "data-type": type,
4640
+ "data-placement": placement,
4641
+ "data-align": align,
4642
+ "data-side": side,
4643
+ "data-mounted": dataAttr(mounted),
4644
+ "data-paused": dataAttr(paused),
4645
+ "data-first": dataAttr(frontmost),
4646
+ "data-sibling": dataAttr(!frontmost),
4647
+ "data-stack": dataAttr(stacked),
4648
+ "data-overlap": dataAttr(!stacked),
4649
+ role: "status",
4650
+ "aria-atomic": "true",
4651
+ "aria-describedby": description ? getDescriptionId(scope) : void 0,
4652
+ "aria-labelledby": title ? getTitleId(scope) : void 0,
4653
+ tabIndex: 0,
4654
+ style: getPlacementStyle(service, visible),
4655
+ onKeyDown(event) {
4656
+ if (event.defaultPrevented) return;
4657
+ if (event.key == "Escape") {
4658
+ send({ type: "DISMISS", src: "keyboard" });
4659
+ event.preventDefault();
4660
+ }
4661
+ }
4662
+ });
4663
+ },
4664
+ /* Leave a ghost div to avoid setting hover to false when transitioning out */
4665
+ getGhostBeforeProps() {
4666
+ return normalize.element({
4667
+ "data-ghost": "before",
4668
+ style: getGhostBeforeStyle(service, visible)
4669
+ });
4670
+ },
4671
+ /* Needed to avoid setting hover to false when in between toasts */
4672
+ getGhostAfterProps() {
4673
+ return normalize.element({
4674
+ "data-ghost": "after",
4675
+ style: getGhostAfterStyle()
4676
+ });
4677
+ },
4678
+ getTitleProps() {
4679
+ return normalize.element({
4680
+ ...parts.title.attrs,
4681
+ id: getTitleId(scope)
4682
+ });
4683
+ },
4684
+ getDescriptionProps() {
4685
+ return normalize.element({
4686
+ ...parts.description.attrs,
4687
+ id: getDescriptionId(scope)
4688
+ });
4689
+ },
4690
+ getActionTriggerProps() {
4691
+ return normalize.button({
4692
+ ...parts.actionTrigger.attrs,
4693
+ type: "button",
4694
+ onClick(event) {
4695
+ var _a;
4696
+ if (event.defaultPrevented) return;
4697
+ (_a = action == null ? void 0 : action.onClick) == null ? void 0 : _a.call(action);
4698
+ send({ type: "DISMISS", src: "user" });
4699
+ }
4700
+ });
4701
+ },
4702
+ getCloseTriggerProps() {
4703
+ return normalize.button({
4704
+ id: getCloseTriggerId(scope),
4705
+ ...parts.closeTrigger.attrs,
4706
+ type: "button",
4707
+ "aria-label": "Dismiss notification",
4708
+ onClick(event) {
4709
+ if (event.defaultPrevented) return;
4710
+ send({ type: "DISMISS", src: "user" });
4711
+ }
4712
+ });
4713
+ }
4714
+ };
4715
+ }
4716
+ var { not } = createGuards();
4717
+ var machine = createMachine({
4718
+ props({ props }) {
4719
+ ensureProps(props, ["id", "type", "parent", "removeDelay"], "toast");
4720
+ return {
4721
+ closable: true,
4722
+ ...props,
4723
+ duration: getToastDuration(props.duration, props.type)
4724
+ };
4725
+ },
4726
+ initialState({ prop }) {
4727
+ const persist = prop("type") === "loading" || prop("duration") === Infinity;
4728
+ return persist ? "visible:persist" : "visible";
4729
+ },
4730
+ context({ prop, bindable }) {
4731
+ return {
4732
+ remainingTime: bindable(() => ({
4733
+ defaultValue: getToastDuration(prop("duration"), prop("type"))
4734
+ })),
4735
+ createdAt: bindable(() => ({
4736
+ defaultValue: Date.now()
4737
+ })),
4738
+ mounted: bindable(() => ({
4739
+ defaultValue: false
4740
+ })),
4741
+ initialHeight: bindable(() => ({
4742
+ defaultValue: 0
4743
+ }))
4744
+ };
4745
+ },
4746
+ refs() {
4747
+ return {
4748
+ closeTimerStartTime: Date.now(),
4749
+ lastCloseStartTimerStartTime: 0
4750
+ };
4751
+ },
4752
+ computed: {
4753
+ zIndex: ({ prop }) => {
4754
+ const toasts = prop("parent").context.get("toasts");
4755
+ const index2 = toasts.findIndex((toast2) => toast2.id === prop("id"));
4756
+ return toasts.length - index2;
4757
+ },
4758
+ height: ({ prop }) => {
4759
+ const heights = prop("parent").context.get("heights");
4760
+ const height = heights.find((height2) => height2.id === prop("id"));
4761
+ return (height == null ? void 0 : height.height) ?? 0;
4762
+ },
4763
+ heightIndex: ({ prop }) => {
4764
+ const heights = prop("parent").context.get("heights");
4765
+ return heights.findIndex((height) => height.id === prop("id"));
4766
+ },
4767
+ frontmost: ({ prop }) => prop("index") === 0,
4768
+ heightBefore: ({ prop }) => {
4769
+ const heights = prop("parent").context.get("heights");
4770
+ const heightIndex = heights.findIndex((height) => height.id === prop("id"));
4771
+ return heights.reduce((prev, curr, reducerIndex) => {
4772
+ if (reducerIndex >= heightIndex) return prev;
4773
+ return prev + curr.height;
4774
+ }, 0);
4775
+ },
4776
+ shouldPersist: ({ prop }) => prop("type") === "loading" || prop("duration") === Infinity
4777
+ },
4778
+ watch({ track, prop, send }) {
4779
+ track([() => prop("message")], () => {
4780
+ const message = prop("message");
4781
+ if (message) send({ type: message, src: "programmatic" });
4782
+ });
4783
+ track([() => prop("type"), () => prop("duration")], () => {
4784
+ send({ type: "UPDATE" });
4785
+ });
4786
+ },
4787
+ on: {
4788
+ UPDATE: [
4789
+ {
4790
+ guard: "shouldPersist",
4791
+ target: "visible:persist",
4792
+ actions: ["resetCloseTimer"]
4793
+ },
4794
+ {
4795
+ target: "visible:updating",
4796
+ actions: ["resetCloseTimer"]
4797
+ }
4798
+ ],
4799
+ MEASURE: {
4800
+ actions: ["measureHeight"]
4801
+ }
4802
+ },
4803
+ entry: ["setMounted", "measureHeight", "invokeOnVisible"],
4804
+ effects: ["trackHeight"],
4805
+ states: {
4806
+ "visible:updating": {
4807
+ tags: ["visible", "updating"],
4808
+ effects: ["waitForNextTick"],
4809
+ on: {
4810
+ SHOW: {
4811
+ target: "visible"
4812
+ }
4813
+ }
4814
+ },
4815
+ "visible:persist": {
4816
+ tags: ["visible", "paused"],
4817
+ on: {
4818
+ RESUME: {
4819
+ guard: not("isLoadingType"),
4820
+ target: "visible",
4821
+ actions: ["setCloseTimer"]
4822
+ },
4823
+ DISMISS: {
4824
+ target: "dismissing"
4825
+ }
4826
+ }
4827
+ },
4828
+ visible: {
4829
+ tags: ["visible"],
4830
+ effects: ["waitForDuration"],
4831
+ on: {
4832
+ DISMISS: {
4833
+ target: "dismissing"
4834
+ },
4835
+ PAUSE: {
4836
+ target: "visible:persist",
4837
+ actions: ["syncRemainingTime"]
4838
+ }
4839
+ }
4840
+ },
4841
+ dismissing: {
4842
+ entry: ["invokeOnDismiss"],
4843
+ effects: ["waitForRemoveDelay"],
4844
+ on: {
4845
+ REMOVE: {
4846
+ target: "unmounted",
4847
+ actions: ["notifyParentToRemove"]
4848
+ }
4849
+ }
4850
+ },
4851
+ unmounted: {
4852
+ entry: ["invokeOnUnmount"]
4853
+ }
4854
+ },
4855
+ implementations: {
4856
+ effects: {
4857
+ waitForRemoveDelay({ prop, send }) {
4858
+ return setRafTimeout(() => {
4859
+ send({ type: "REMOVE", src: "timer" });
4860
+ }, prop("removeDelay"));
4861
+ },
4862
+ waitForDuration({ send, context: context2, computed }) {
4863
+ if (computed("shouldPersist")) return;
4864
+ return setRafTimeout(() => {
4865
+ send({ type: "DISMISS", src: "timer" });
4866
+ }, context2.get("remainingTime"));
4867
+ },
4868
+ waitForNextTick({ send }) {
4869
+ return setRafTimeout(() => {
4870
+ send({ type: "SHOW", src: "timer" });
4871
+ }, 0);
4872
+ },
4873
+ trackHeight({ scope, prop }) {
4874
+ let cleanup;
4875
+ raf$2(() => {
4876
+ const rootEl = getRootEl(scope);
4877
+ if (!rootEl) return;
4878
+ const syncHeight = () => {
4879
+ const originalHeight = rootEl.style.height;
4880
+ rootEl.style.height = "auto";
4881
+ const height = rootEl.getBoundingClientRect().height;
4882
+ rootEl.style.height = originalHeight;
4883
+ const item = { id: prop("id"), height };
4884
+ setHeight(prop("parent"), item);
4885
+ };
4886
+ const win = scope.getWin();
4887
+ const observer = new win.MutationObserver(syncHeight);
4888
+ observer.observe(rootEl, {
4889
+ childList: true,
4890
+ subtree: true,
4891
+ characterData: true
4892
+ });
4893
+ cleanup = () => observer.disconnect();
4894
+ });
4895
+ return () => cleanup == null ? void 0 : cleanup();
4896
+ }
4897
+ },
4898
+ guards: {
4899
+ isLoadingType: ({ prop }) => prop("type") === "loading",
4900
+ shouldPersist: ({ computed }) => computed("shouldPersist")
4901
+ },
4902
+ actions: {
4903
+ setMounted({ context: context2 }) {
4904
+ raf$2(() => {
4905
+ context2.set("mounted", true);
4906
+ });
4907
+ },
4908
+ measureHeight({ scope, prop, context: context2 }) {
4909
+ queueMicrotask(() => {
4910
+ const rootEl = getRootEl(scope);
4911
+ if (!rootEl) return;
4912
+ const originalHeight = rootEl.style.height;
4913
+ rootEl.style.height = "auto";
4914
+ const height = rootEl.getBoundingClientRect().height;
4915
+ rootEl.style.height = originalHeight;
4916
+ context2.set("initialHeight", height);
4917
+ const item = { id: prop("id"), height };
4918
+ setHeight(prop("parent"), item);
4919
+ });
4920
+ },
4921
+ setCloseTimer({ refs }) {
4922
+ refs.set("closeTimerStartTime", Date.now());
3994
4923
  },
3995
- setIndicatorRect({ context: context2, event, scope }) {
3996
- const value = event.id ?? context2.get("value");
3997
- const indicatorEl = getIndicatorEl(scope);
3998
- if (!indicatorEl || !value) return;
3999
- const triggerEl = getTriggerEl(scope, value);
4000
- if (!triggerEl) return;
4001
- context2.set("indicatorRect", getRectById(scope, value));
4002
- nextTick(() => {
4003
- context2.set("indicatorTransition", false);
4924
+ resetCloseTimer({ context: context2, refs, prop }) {
4925
+ refs.set("closeTimerStartTime", Date.now());
4926
+ context2.set("remainingTime", getToastDuration(prop("duration"), prop("type")));
4927
+ },
4928
+ syncRemainingTime({ context: context2, refs }) {
4929
+ context2.set("remainingTime", (prev) => {
4930
+ const closeTimerStartTime = refs.get("closeTimerStartTime");
4931
+ const elapsedTime = Date.now() - closeTimerStartTime;
4932
+ refs.set("lastCloseStartTimerStartTime", Date.now());
4933
+ return prev - elapsedTime;
4004
4934
  });
4005
4935
  },
4006
- syncSsr({ context: context2 }) {
4007
- context2.set("ssr", false);
4936
+ notifyParentToRemove({ prop }) {
4937
+ const parent = prop("parent");
4938
+ parent.send({ type: "TOAST.REMOVE", id: prop("id") });
4008
4939
  },
4009
- syncIndicatorRect({ context: context2, refs, scope }) {
4010
- const cleanup = refs.get("indicatorCleanup");
4011
- if (cleanup) cleanup();
4012
- const value = context2.get("value");
4013
- if (!value) return;
4014
- const triggerEl = getTriggerEl(scope, value);
4015
- const indicatorEl = getIndicatorEl(scope);
4016
- if (!triggerEl || !indicatorEl) return;
4017
- const exec = () => {
4018
- const rect = getOffsetRect(triggerEl);
4019
- context2.set("indicatorRect", resolveRect(rect));
4020
- nextTick(() => {
4021
- context2.set("indicatorTransition", false);
4022
- });
4023
- };
4024
- exec();
4025
- const win = scope.getWin();
4026
- const obs = new win.ResizeObserver(exec);
4027
- obs.observe(triggerEl);
4028
- refs.set("indicatorCleanup", () => obs.disconnect());
4940
+ invokeOnDismiss({ prop, event }) {
4941
+ var _a;
4942
+ (_a = prop("onStatusChange")) == null ? void 0 : _a({ status: "dismissing", src: event.src });
4029
4943
  },
4030
- navigateIfNeeded({ context: context2, prop, scope }) {
4944
+ invokeOnUnmount({ prop }) {
4031
4945
  var _a;
4032
- const value = context2.get("value");
4033
- if (!value) return;
4034
- const triggerEl = getTriggerEl(scope, value);
4035
- if (!isAnchorElement(triggerEl)) return;
4036
- (_a = prop("navigate")) == null ? void 0 : _a({ value, node: triggerEl });
4946
+ (_a = prop("onStatusChange")) == null ? void 0 : _a({ status: "unmounted" });
4947
+ },
4948
+ invokeOnVisible({ prop }) {
4949
+ var _a;
4950
+ (_a = prop("onStatusChange")) == null ? void 0 : _a({ status: "visible" });
4037
4951
  }
4038
4952
  }
4039
4953
  }
4040
4954
  });
4041
- createProps()([
4042
- "activationMode",
4043
- "composite",
4044
- "deselectable",
4045
- "dir",
4046
- "getRootNode",
4047
- "id",
4048
- "ids",
4049
- "loopFocus",
4050
- "navigate",
4051
- "onFocusChange",
4052
- "onValueChange",
4053
- "orientation",
4054
- "translations",
4055
- "value",
4056
- "defaultValue"
4057
- ]);
4058
- createProps()(["disabled", "value"]);
4059
- createProps()(["value"]);
4060
- const useTabs = (props) => {
4061
- const id = React.useId();
4062
- const { getRootNode } = useEnvironmentContext();
4063
- const { dir } = useLocaleContext();
4064
- const machineProps = {
4065
- id,
4066
- dir,
4067
- getRootNode,
4068
- ...props
4955
+ function setHeight(parent, item) {
4956
+ const { id, height } = item;
4957
+ parent.context.set("heights", (prev) => {
4958
+ const alreadyExists = prev.find((i) => i.id === id);
4959
+ if (!alreadyExists) {
4960
+ return [{ id, height }, ...prev];
4961
+ } else {
4962
+ return prev.map((i) => i.id === id ? { ...i, height } : i);
4963
+ }
4964
+ });
4965
+ }
4966
+ var withDefaults = (options, defaults2) => {
4967
+ return { ...defaults2, ...options };
4968
+ };
4969
+ function createToastStore(props) {
4970
+ const attrs = withDefaults(props, {
4971
+ placement: "bottom",
4972
+ overlap: false,
4973
+ max: 24,
4974
+ gap: 16,
4975
+ offsets: "1rem",
4976
+ hotkey: ["altKey", "KeyT"],
4977
+ removeDelay: 200,
4978
+ pauseOnPageIdle: true
4979
+ });
4980
+ let subscribers = [];
4981
+ let toasts = [];
4982
+ let dismissedToasts = /* @__PURE__ */ new Set();
4983
+ const subscribe2 = (subscriber) => {
4984
+ subscribers.push(subscriber);
4985
+ return () => {
4986
+ const index2 = subscribers.indexOf(subscriber);
4987
+ subscribers.splice(index2, 1);
4988
+ };
4989
+ };
4990
+ const publish = (data) => {
4991
+ subscribers.forEach((subscriber) => subscriber(data));
4992
+ return data;
4993
+ };
4994
+ const addToast = (data) => {
4995
+ if (toasts.length >= attrs.max) return;
4996
+ publish(data);
4997
+ toasts.unshift(data);
4998
+ };
4999
+ const create = (data) => {
5000
+ const id = data.id ?? `toast:${uuid()}`;
5001
+ const exists = toasts.find((toast2) => toast2.id === id);
5002
+ if (dismissedToasts.has(id)) dismissedToasts.delete(id);
5003
+ if (exists) {
5004
+ toasts = toasts.map((toast2) => {
5005
+ if (toast2.id === id) {
5006
+ return publish({ ...toast2, ...data, id });
5007
+ }
5008
+ return toast2;
5009
+ });
5010
+ } else {
5011
+ addToast({
5012
+ id,
5013
+ duration: attrs.duration,
5014
+ removeDelay: attrs.removeDelay,
5015
+ type: "info",
5016
+ ...data,
5017
+ stacked: !attrs.overlap,
5018
+ gap: attrs.gap
5019
+ });
5020
+ }
5021
+ return id;
5022
+ };
5023
+ const remove = (id) => {
5024
+ dismissedToasts.add(id);
5025
+ if (!id) {
5026
+ toasts.forEach((toast2) => {
5027
+ subscribers.forEach((subscriber) => subscriber({ id: toast2.id, dismiss: true }));
5028
+ });
5029
+ toasts = [];
5030
+ } else {
5031
+ subscribers.forEach((subscriber) => subscriber({ id, dismiss: true }));
5032
+ toasts = toasts.filter((toast2) => toast2.id !== id);
5033
+ }
5034
+ return id;
5035
+ };
5036
+ const error = (data) => {
5037
+ return create({ ...data, type: "error" });
5038
+ };
5039
+ const success = (data) => {
5040
+ return create({ ...data, type: "success" });
5041
+ };
5042
+ const info = (data) => {
5043
+ return create({ ...data, type: "info" });
5044
+ };
5045
+ const warning = (data) => {
5046
+ return create({ ...data, type: "warning" });
5047
+ };
5048
+ const loading = (data) => {
5049
+ return create({ ...data, type: "loading" });
4069
5050
  };
4070
- const service = useMachine(machine, machineProps);
4071
- return connect(service, normalizeProps);
5051
+ const getVisibleToasts = () => {
5052
+ return toasts.filter((toast2) => !dismissedToasts.has(toast2.id));
5053
+ };
5054
+ const getCount = () => {
5055
+ return toasts.length;
5056
+ };
5057
+ const promise = (promise2, options, shared = {}) => {
5058
+ if (!options) return;
5059
+ let id = void 0;
5060
+ if (options.loading !== void 0) {
5061
+ id = create({
5062
+ ...shared,
5063
+ ...options.loading,
5064
+ promise: promise2,
5065
+ type: "loading"
5066
+ });
5067
+ }
5068
+ let removable = id !== void 0;
5069
+ let result;
5070
+ const prom = runIfFn(promise2).then(async (response) => {
5071
+ result = ["resolve", response];
5072
+ if (isHttpResponse(response) && !response.ok) {
5073
+ removable = false;
5074
+ const errorOptions = runIfFn(options.error, `HTTP Error! status: ${response.status}`);
5075
+ create({ ...shared, ...errorOptions, id, type: "error" });
5076
+ } else if (options.success !== void 0) {
5077
+ removable = false;
5078
+ const successOptions = runIfFn(options.success, response);
5079
+ create({ ...shared, ...successOptions, id, type: "success" });
5080
+ }
5081
+ }).catch(async (error2) => {
5082
+ result = ["reject", error2];
5083
+ if (options.error !== void 0) {
5084
+ removable = false;
5085
+ const errorOptions = runIfFn(options.error, error2);
5086
+ create({ ...shared, ...errorOptions, id, type: "error" });
5087
+ }
5088
+ }).finally(() => {
5089
+ var _a;
5090
+ if (removable) {
5091
+ remove(id);
5092
+ id = void 0;
5093
+ }
5094
+ (_a = options.finally) == null ? void 0 : _a.call(options);
5095
+ });
5096
+ const unwrap = () => new Promise(
5097
+ (resolve, reject) => prom.then(() => result[0] === "reject" ? reject(result[1]) : resolve(result[1])).catch(reject)
5098
+ );
5099
+ return { id, unwrap };
5100
+ };
5101
+ const update2 = (id, data) => {
5102
+ return create({ id, ...data });
5103
+ };
5104
+ const pause = (id) => {
5105
+ if (id != null) {
5106
+ toasts = toasts.map((toast2) => {
5107
+ if (toast2.id === id) return publish({ ...toast2, message: "PAUSE" });
5108
+ return toast2;
5109
+ });
5110
+ } else {
5111
+ toasts = toasts.map((toast2) => publish({ ...toast2, message: "PAUSE" }));
5112
+ }
5113
+ };
5114
+ const resume = (id) => {
5115
+ if (id != null) {
5116
+ toasts = toasts.map((toast2) => {
5117
+ if (toast2.id === id) return publish({ ...toast2, message: "RESUME" });
5118
+ return toast2;
5119
+ });
5120
+ } else {
5121
+ toasts = toasts.map((toast2) => publish({ ...toast2, message: "RESUME" }));
5122
+ }
5123
+ };
5124
+ const dismiss = (id) => {
5125
+ if (id != null) {
5126
+ toasts = toasts.map((toast2) => {
5127
+ if (toast2.id === id) return publish({ ...toast2, message: "DISMISS" });
5128
+ return toast2;
5129
+ });
5130
+ } else {
5131
+ toasts = toasts.map((toast2) => publish({ ...toast2, message: "DISMISS" }));
5132
+ }
5133
+ };
5134
+ const isVisible = (id) => {
5135
+ return !dismissedToasts.has(id) && !!toasts.find((toast2) => toast2.id === id);
5136
+ };
5137
+ const isDismissed = (id) => {
5138
+ return dismissedToasts.has(id);
5139
+ };
5140
+ const expand = () => {
5141
+ toasts = toasts.map((toast2) => publish({ ...toast2, stacked: true }));
5142
+ };
5143
+ const collapse = () => {
5144
+ toasts = toasts.map((toast2) => publish({ ...toast2, stacked: false }));
5145
+ };
5146
+ return {
5147
+ attrs,
5148
+ subscribe: subscribe2,
5149
+ create,
5150
+ update: update2,
5151
+ remove,
5152
+ dismiss,
5153
+ error,
5154
+ success,
5155
+ info,
5156
+ warning,
5157
+ loading,
5158
+ getVisibleToasts,
5159
+ getCount,
5160
+ promise,
5161
+ pause,
5162
+ resume,
5163
+ isVisible,
5164
+ isDismissed,
5165
+ expand,
5166
+ collapse
5167
+ };
5168
+ }
5169
+ var isHttpResponse = (data) => {
5170
+ return data && typeof data === "object" && "ok" in data && typeof data.ok === "boolean" && "status" in data && typeof data.status === "number";
4072
5171
  };
4073
- const TabsRoot = React.forwardRef((props, ref) => {
4074
- const [renderStrategyProps, tabsProps] = splitRenderStrategyProps(props);
4075
- const [useTabsProps, localprops] = createSplitProps()(tabsProps, [
4076
- "activationMode",
4077
- "composite",
4078
- "defaultValue",
4079
- "deselectable",
4080
- "id",
4081
- "ids",
4082
- "loopFocus",
4083
- "navigate",
4084
- "onFocusChange",
4085
- "onValueChange",
4086
- "orientation",
4087
- "translations",
4088
- "value"
4089
- ]);
4090
- const tabs = useTabs(useTabsProps);
4091
- const mergedProps = mergeProps(tabs.getRootProps(), localprops);
4092
- return /* @__PURE__ */ jsxRuntime.jsx(TabsProvider, { value: tabs, children: /* @__PURE__ */ jsxRuntime.jsx(RenderStrategyPropsProvider, { value: renderStrategyProps, children: /* @__PURE__ */ jsxRuntime.jsx(ark.div, { ...mergedProps, ref }) }) });
5172
+ var group = {
5173
+ connect: groupConnect,
5174
+ machine: groupMachine
5175
+ };
5176
+ const createToaster = (props) => {
5177
+ return createToastStore(props);
5178
+ };
5179
+ const [ToastProvider$1, useToastContext] = createContext({
5180
+ name: "ToastContext",
5181
+ hookName: "useToastContext",
5182
+ providerName: "<ToastProvider />"
4093
5183
  });
4094
- TabsRoot.displayName = "TabsRoot";
5184
+ const ToastActionTrigger = React.forwardRef((props, ref) => {
5185
+ const toast2 = useToastContext();
5186
+ const mergedProps = mergeProps(toast2.getActionTriggerProps(), props);
5187
+ return /* @__PURE__ */ jsxRuntime.jsx(ark.button, { ...mergedProps, ref });
5188
+ });
5189
+ ToastActionTrigger.displayName = "ToastActionTrigger";
5190
+ const ToastDescription = React.forwardRef((props, ref) => {
5191
+ const toast2 = useToastContext();
5192
+ const mergedProps = mergeProps(toast2.getDescriptionProps(), props);
5193
+ return /* @__PURE__ */ jsxRuntime.jsx(ark.div, { ...mergedProps, ref });
5194
+ });
5195
+ ToastDescription.displayName = "ToastDescription";
5196
+ const ToastRoot = React.forwardRef((props, ref) => {
5197
+ const toast2 = useToastContext();
5198
+ const mergedProps = mergeProps(toast2.getRootProps(), props);
5199
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ...mergedProps, ref, children: [
5200
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ...toast2.getGhostBeforeProps() }),
5201
+ props.children,
5202
+ /* @__PURE__ */ jsxRuntime.jsx("div", { ...toast2.getGhostAfterProps() })
5203
+ ] });
5204
+ });
5205
+ ToastRoot.displayName = "ToastRoot";
5206
+ const Toaster = React.forwardRef((props, ref) => {
5207
+ const { toaster, children, ...localProps } = props;
5208
+ const locale = useLocaleContext();
5209
+ const env = useEnvironmentContext();
5210
+ const service = useMachine(group.machine, {
5211
+ store: toaster,
5212
+ id: React.useId(),
5213
+ dir: locale == null ? void 0 : locale.dir,
5214
+ getRootNode: () => env == null ? void 0 : env.getDocument()
5215
+ });
5216
+ const api = group.connect(service, normalizeProps);
5217
+ const mergedProps = mergeProps(api.getGroupProps(), localProps);
5218
+ return /* @__PURE__ */ jsxRuntime.jsx(ark.div, { ...mergedProps, ref, children: api.getToasts().map((toast2, index2) => /* @__PURE__ */ jsxRuntime.jsx(ToastActor, { value: toast2, parent: service, index: index2, children: (ctx2) => children(ctx2) }, toast2.id)) });
5219
+ });
5220
+ Toaster.displayName = "Toaster";
5221
+ const ToastActor = (props) => {
5222
+ const localProps = {
5223
+ ...props.value,
5224
+ parent: props.parent,
5225
+ index: props.index
5226
+ };
5227
+ const service = useMachine(machine, { ...localProps });
5228
+ const api = connect(service, normalizeProps);
5229
+ return /* @__PURE__ */ jsxRuntime.jsx(ToastProvider$1, { value: api, children: props.children(props.value) });
5230
+ };
5231
+ ToastActor.displayName = "ToastActor";
4095
5232
  const spinnerRecipe = cva({
4096
5233
  base: {
4097
5234
  display: "inline-block",
@@ -4708,7 +5845,7 @@ const createStyleContext = (recipe) => {
4708
5845
  };
4709
5846
  return StyledComponent;
4710
5847
  };
4711
- const withProvider = (Component, slot, options) => {
5848
+ const withProvider2 = (Component, slot, options) => {
4712
5849
  const StyledComponent = styled(
4713
5850
  Component,
4714
5851
  {},
@@ -4735,13 +5872,13 @@ const createStyleContext = (recipe) => {
4735
5872
  };
4736
5873
  return {
4737
5874
  withRootProvider: withRootProvider2,
4738
- withProvider,
5875
+ withProvider: withProvider2,
4739
5876
  withContext: withContext2
4740
5877
  };
4741
5878
  };
4742
5879
  const dialogRecipe = sva({
4743
5880
  className: "dialog",
4744
- slots: [...anatomy$1.keys(), "header", "footer", "body"],
5881
+ slots: [...anatomy$2.keys(), "header", "footer", "body"],
4745
5882
  base: {
4746
5883
  backdrop: {
4747
5884
  backdropFilter: "blur(3px)",
@@ -4823,16 +5960,16 @@ const dialogRecipe = sva({
4823
5960
  }
4824
5961
  }
4825
5962
  });
4826
- const { withRootProvider: withRootProvider$1, withContext: withContext$1 } = createStyleContext(dialogRecipe);
4827
- const Root$1 = withRootProvider$1(DialogRoot);
4828
- const Backdrop$1 = withContext$1(DialogBackdrop, "backdrop");
4829
- const Trigger$1 = withContext$1(DialogTrigger, "trigger");
4830
- const Content = withContext$1(DialogContent, "content");
4831
- const Title = withContext$1(DialogTitle, "title");
4832
- const Description = withContext$1(DialogDescription, "description");
4833
- const Positioner = withContext$1(DialogPositioner, "positioner");
4834
- const Header = withContext$1(ark.header, "header");
4835
- const Footer = withContext$1(
5963
+ const { withRootProvider: withRootProvider$1, withContext: withContext$2 } = createStyleContext(dialogRecipe);
5964
+ const Root$2 = withRootProvider$1(DialogRoot);
5965
+ const Backdrop$1 = withContext$2(DialogBackdrop, "backdrop");
5966
+ const Trigger$1 = withContext$2(DialogTrigger, "trigger");
5967
+ const Content$1 = withContext$2(DialogContent, "content");
5968
+ const Title = withContext$2(DialogTitle, "title");
5969
+ const Description$1 = withContext$2(DialogDescription, "description");
5970
+ const Positioner = withContext$2(DialogPositioner, "positioner");
5971
+ const Header = withContext$2(ark.header, "header");
5972
+ const Footer = withContext$2(
4836
5973
  ({ orientation = "horizontal", className, ...props }) => {
4837
5974
  return /* @__PURE__ */ jsxRuntime.jsx(
4838
5975
  ark.footer,
@@ -4850,15 +5987,15 @@ const Footer = withContext$1(
4850
5987
  },
4851
5988
  "footer"
4852
5989
  );
4853
- const Body = withContext$1(ark.main, "body");
4854
- const CloseTrigger = withContext$1(DialogCloseTrigger, "closeTrigger");
5990
+ const Body = withContext$2(ark.main, "body");
5991
+ const CloseTrigger = withContext$2(DialogCloseTrigger, "closeTrigger");
4855
5992
  const Dialog = {
4856
- Root: Root$1,
5993
+ Root: Root$2,
4857
5994
  Backdrop: Backdrop$1,
4858
5995
  Trigger: Trigger$1,
4859
- Content,
5996
+ Content: Content$1,
4860
5997
  Title,
4861
- Description,
5998
+ Description: Description$1,
4862
5999
  Positioner,
4863
6000
  Header,
4864
6001
  Footer,
@@ -8421,7 +9558,8 @@ const useBottomSheet = (props) => {
8421
9558
  initTransformValue: 0,
8422
9559
  canDragRef: true,
8423
9560
  maxTransformValue: 0,
8424
- initialOpenHeightPx: 0
9561
+ initialOpenHeightPx: 0,
9562
+ isBottomSheetOpen: false
8425
9563
  });
8426
9564
  const [springs, api] = useSpring(() => ({
8427
9565
  transform: "translateY(0px)",
@@ -8429,22 +9567,25 @@ const useBottomSheet = (props) => {
8429
9567
  }));
8430
9568
  const snapToMax = () => {
8431
9569
  const { maxTransformValue } = metrics.current;
9570
+ console.log("maxTransformValue", maxTransformValue);
8432
9571
  api.start({
8433
9572
  transform: `translateY(${maxTransformValue}px)`,
8434
9573
  config: SPRING_CONFIG.up
8435
9574
  });
8436
- if (onOpen) onOpen();
9575
+ if (onOpen && !metrics.current.isBottomSheetOpen) onOpen();
9576
+ metrics.current.isBottomSheetOpen = true;
8437
9577
  };
8438
9578
  const snapToMin = () => {
8439
9579
  api.start({
8440
9580
  transform: "translateY(0px)",
8441
9581
  config: SPRING_CONFIG.down
8442
9582
  });
8443
- if (onClose) onClose();
9583
+ if (onClose && metrics.current.isBottomSheetOpen) onClose();
9584
+ metrics.current.isBottomSheetOpen = false;
8444
9585
  };
8445
9586
  const handleContentTouch = (e) => {
8446
9587
  const target = e.target;
8447
- if (!target.matches(INTERACTIVE_ELEMENTS) && expendOnContentDrag) {
9588
+ if (!target.matches(INTERACTIVE_ELEMENTS) && expendOnContentDrag || !metrics.current.isBottomSheetOpen) {
8448
9589
  metrics.current.canDragRef = true;
8449
9590
  } else {
8450
9591
  metrics.current.canDragRef = false;
@@ -8460,9 +9601,7 @@ const useBottomSheet = (props) => {
8460
9601
  return;
8461
9602
  }
8462
9603
  const currentTransform = springs.transform.get();
8463
- const initTransformValue = Number(
8464
- currentTransform.replace("translateY(", "").replace("px)", "") || 0
8465
- );
9604
+ const initTransformValue = Number(currentTransform.replace("translateY(", "").replace("px)", "") || 0);
8466
9605
  metrics.current.initTransformValue = initTransformValue;
8467
9606
  metrics.current.initTouchPosition = clientY;
8468
9607
  };
@@ -8488,9 +9627,7 @@ const useBottomSheet = (props) => {
8488
9627
  return;
8489
9628
  }
8490
9629
  const currentTransform = springs.transform.get();
8491
- const finalTransformValue = Number(
8492
- currentTransform.replace("translateY(", "").replace("px)", "") || 0
8493
- );
9630
+ const finalTransformValue = Number(currentTransform.replace("translateY(", "").replace("px)", "") || 0);
8494
9631
  const transformedDistance = initTransformValue - finalTransformValue;
8495
9632
  if (transformedDistance < 0 && SNAP_TO_MIN_THRESHOLD < Math.abs(transformedDistance)) {
8496
9633
  snapToMin();
@@ -8517,21 +9654,55 @@ const useBottomSheet = (props) => {
8517
9654
  up: handleEnd,
8518
9655
  leave: handleEnd
8519
9656
  };
9657
+ const preventScrollOnBackdrop = (e) => {
9658
+ if (bottomSheetRef.current && (bottomSheetRef.current.contains(e.target) || // 최소 높이로 떠 있는 바텀시트의 핸들 영역을 클릭하는 경우 특별 처리
9659
+ e instanceof TouchEvent && isBottomSheetHandleArea(e.touches[0].clientY))) {
9660
+ return;
9661
+ }
9662
+ e.preventDefault();
9663
+ e.stopPropagation();
9664
+ };
9665
+ const isBottomSheetHandleArea = (clientY) => {
9666
+ if (!bottomSheetRef.current) return false;
9667
+ const { initialOpenHeightPx } = metrics.current;
9668
+ const bottomSheetTop = window.innerHeight - initialOpenHeightPx;
9669
+ const handleAreaTop = bottomSheetTop;
9670
+ const handleAreaBottom = bottomSheetTop + BOTTOM_SHEET_HANDLE_HEIGHT;
9671
+ return clientY >= handleAreaTop && clientY <= handleAreaBottom;
9672
+ };
9673
+ const handleTouchStart = (e) => {
9674
+ const clientY = e.touches[0].clientY;
9675
+ if (isBottomSheetHandleArea(clientY)) {
9676
+ e.preventDefault();
9677
+ e.stopPropagation();
9678
+ handleTouch.start(e);
9679
+ }
9680
+ };
8520
9681
  React.useEffect(() => {
8521
9682
  if (isOpen) snapToMax();
8522
9683
  else snapToMin();
8523
- const handleTouchMove = (e) => {
8524
- if (bottomSheetRef.current && !bottomSheetRef.current.contains(e.target)) {
8525
- e.preventDefault();
8526
- }
8527
- };
8528
9684
  if (isOpen) {
8529
- document.addEventListener("touchmove", handleTouchMove, { passive: false });
9685
+ document.addEventListener("touchmove", preventScrollOnBackdrop, { passive: false });
9686
+ document.addEventListener("wheel", preventScrollOnBackdrop, { passive: false });
9687
+ document.addEventListener("mousewheel", preventScrollOnBackdrop, { passive: false });
9688
+ document.addEventListener("touchstart", handleTouchStart, { passive: false });
9689
+ document.body.style.overflow = "hidden";
9690
+ document.body.style.touchAction = "none";
8530
9691
  } else {
8531
- document.removeEventListener("touchmove", handleTouchMove);
9692
+ document.removeEventListener("touchmove", preventScrollOnBackdrop);
9693
+ document.removeEventListener("wheel", preventScrollOnBackdrop);
9694
+ document.removeEventListener("mousewheel", preventScrollOnBackdrop);
9695
+ document.removeEventListener("touchstart", handleTouchStart);
9696
+ document.body.style.overflow = "";
9697
+ document.body.style.touchAction = "";
8532
9698
  }
8533
9699
  return () => {
8534
- document.removeEventListener("touchmove", handleTouchMove);
9700
+ document.removeEventListener("touchmove", preventScrollOnBackdrop);
9701
+ document.removeEventListener("wheel", preventScrollOnBackdrop);
9702
+ document.removeEventListener("mousewheel", preventScrollOnBackdrop);
9703
+ document.removeEventListener("touchstart", handleTouchStart);
9704
+ document.body.style.overflow = "";
9705
+ document.body.style.touchAction = "";
8535
9706
  };
8536
9707
  }, [isOpen]);
8537
9708
  React.useEffect(() => {
@@ -8539,7 +9710,7 @@ const useBottomSheet = (props) => {
8539
9710
  const contentElement = contentRef.current;
8540
9711
  metrics.current.initialOpenHeightPx = window.innerHeight * (snapPercent.min > 1 ? 1 : snapPercent.min);
8541
9712
  if (snapPercent.max === "INNER_HEIGHT" && contentElement) {
8542
- metrics.current.maxTransformValue = (contentElement.clientHeight - BOTTOM_SHEET_HANDLE_HEIGHT) * -1;
9713
+ metrics.current.maxTransformValue = (contentElement.clientHeight + BOTTOM_SHEET_HANDLE_HEIGHT) * -1;
8543
9714
  } else if (typeof snapPercent.max === "number") {
8544
9715
  metrics.current.maxTransformValue = (window.innerHeight - metrics.current.initialOpenHeightPx) * (snapPercent.max > 1 ? 1 : snapPercent.max) * -1;
8545
9716
  }
@@ -8702,7 +9873,7 @@ BottomSheetFrame.displayName = "BottomSheetFrame";
8702
9873
  Backdrop.displayName = "Backdrop";
8703
9874
  const navigationRecipe = sva({
8704
9875
  className: "navigation",
8705
- slots: anatomy.keys(),
9876
+ slots: anatomy$1.keys(),
8706
9877
  base: {
8707
9878
  root: {
8708
9879
  bg: "surface.layer_1",
@@ -8743,18 +9914,18 @@ const navigationRecipe = sva({
8743
9914
  }
8744
9915
  }
8745
9916
  });
8746
- const { withRootProvider, withContext } = createStyleContext(navigationRecipe);
8747
- const Root = withRootProvider(TabsRoot);
8748
- const Trigger = withContext(
9917
+ const { withRootProvider, withContext: withContext$1 } = createStyleContext(navigationRecipe);
9918
+ const Root$1 = withRootProvider(TabsRoot);
9919
+ const Trigger = withContext$1(
8749
9920
  ({ icon, label, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs(TabTrigger, { ...props, children: [
8750
9921
  icon,
8751
9922
  label
8752
9923
  ] }),
8753
9924
  "trigger"
8754
9925
  );
8755
- const List = withContext(TabList, "list");
9926
+ const List = withContext$1(TabList, "list");
8756
9927
  const Navigation = {
8757
- Root,
9928
+ Root: Root$1,
8758
9929
  Item: Trigger,
8759
9930
  List
8760
9931
  };
@@ -9565,6 +10736,261 @@ const preset = definePreset({
9565
10736
  }
9566
10737
  }
9567
10738
  });
10739
+ const toastRecipe = sva({
10740
+ className: "toast",
10741
+ slots: [...anatomy.keys(), "content", "icon"],
10742
+ base: {
10743
+ root: {
10744
+ display: "flex",
10745
+ alignItems: "center",
10746
+ justifyContent: "center",
10747
+ backgroundColor: "background.neutralInverse.default",
10748
+ borderRadius: 16,
10749
+ height: "fit-content",
10750
+ minHeight: "48px",
10751
+ width: "fit-content",
10752
+ maxWidth: "328px",
10753
+ overflowWrap: "anywhere",
10754
+ zIndex: "overlay",
10755
+ fontStyle: "body.md",
10756
+ color: "content.neutralInverse.bold",
10757
+ pr: 4,
10758
+ pl: 3,
10759
+ py: 2,
10760
+ boxShadow: "0px 4px 12px rgba(0, 0, 0, 0.1)",
10761
+ animation: "fadeIn 0.25s ease-out",
10762
+ transform: "translateY(20px)",
10763
+ shadow: "overlay",
10764
+ transition: "transform 0.25s ease-out",
10765
+ '&[data-state="open"]': {
10766
+ animation: "slide-in 0.4s cubic-bezier(0.05, 0.7, 0.1, 1.0)",
10767
+ transform: "translateY(0px)"
10768
+ },
10769
+ '&[data-state="closed"]': {
10770
+ animation: "slide-out 0.2s cubic-bezier(0.3, 0.0, 0.8, 0.15)",
10771
+ transform: "translateY(64px)"
10772
+ }
10773
+ },
10774
+ content: {
10775
+ display: "inline-flex",
10776
+ alignItems: "center"
10777
+ },
10778
+ description: {
10779
+ textStyle: "body.md",
10780
+ marginLeft: 2
10781
+ },
10782
+ actionTrigger: {
10783
+ height: "100%",
10784
+ width: "fit-content",
10785
+ display: "flex",
10786
+ alignItems: "center",
10787
+ justifyContent: "center",
10788
+ textStyle: "title.sm",
10789
+ cursor: "pointer",
10790
+ px: 4,
10791
+ pr: 1,
10792
+ whiteSpace: "nowrap",
10793
+ transition: "opacity 0.2s ease",
10794
+ color: "content.neutralInverse.bold",
10795
+ "&:hover": {
10796
+ opacity: 0.8
10797
+ }
10798
+ },
10799
+ icon: {
10800
+ width: 6,
10801
+ height: 6,
10802
+ minWidth: 6,
10803
+ minHeight: 6,
10804
+ display: "flex",
10805
+ alignItems: "center",
10806
+ justifyContent: "center"
10807
+ }
10808
+ },
10809
+ variants: {
10810
+ width: {
10811
+ full: {
10812
+ root: {
10813
+ width: "100%",
10814
+ justifyContent: "space-between"
10815
+ }
10816
+ },
10817
+ fit: {
10818
+ root: {
10819
+ width: "fit-content"
10820
+ }
10821
+ }
10822
+ },
10823
+ asLink: {
10824
+ true: {
10825
+ actionTrigger: {
10826
+ textDecoration: "underline",
10827
+ cursor: "pointer"
10828
+ }
10829
+ }
10830
+ }
10831
+ }
10832
+ });
10833
+ const { withProvider, withContext } = createStyleContext(toastRecipe);
10834
+ const OriginalRoot = withProvider(ToastRoot, "root");
10835
+ const Root = React.forwardRef((props, ref) => {
10836
+ const { children, width, ...rest } = props;
10837
+ const hasActionTrigger = React.Children.toArray(children).some((child) => {
10838
+ if (React.isValidElement(child)) {
10839
+ if (child.type === ActionTrigger) {
10840
+ return true;
10841
+ }
10842
+ if (child.type === React.Fragment && child.props.children) {
10843
+ return React.Children.toArray(child.props.children).some(
10844
+ (fragmentChild) => React.isValidElement(fragmentChild) && fragmentChild.type === ActionTrigger
10845
+ );
10846
+ }
10847
+ }
10848
+ return false;
10849
+ });
10850
+ const widthValue = width !== void 0 ? width : hasActionTrigger ? "full" : "fit";
10851
+ return /* @__PURE__ */ jsxRuntime.jsx(OriginalRoot, { ref, width: widthValue, ...rest, children });
10852
+ });
10853
+ Root.displayName = "Toast.Root";
10854
+ const OriginalActionTrigger = withContext(
10855
+ ToastActionTrigger,
10856
+ "actionTrigger"
10857
+ );
10858
+ const OriginalActionTriggerAsLink = withContext(ark.a, "actionTrigger");
10859
+ const ActionTrigger = React.forwardRef((props, ref) => {
10860
+ const { asLink, ...rest } = props;
10861
+ return asLink ? /* @__PURE__ */ jsxRuntime.jsx(OriginalActionTriggerAsLink, { ref, ...rest }) : /* @__PURE__ */ jsxRuntime.jsx(OriginalActionTrigger, { ref, ...rest });
10862
+ });
10863
+ ActionTrigger.displayName = "Toast.ActionTrigger";
10864
+ const Description = withContext(
10865
+ ToastDescription,
10866
+ "description"
10867
+ );
10868
+ const Content = withContext(ark.div, "content");
10869
+ const Icon = withContext(ark.div, "icon");
10870
+ const Toast = {
10871
+ Root,
10872
+ ActionTrigger,
10873
+ Content,
10874
+ Description,
10875
+ Icon
10876
+ };
10877
+ const toast = {
10878
+ queue: [],
10879
+ // ToastProvider에서 호출
10880
+ _getQueue: () => {
10881
+ const queue = [...toast.queue];
10882
+ toast.queue = [];
10883
+ return queue;
10884
+ },
10885
+ // render toast
10886
+ show: (message, options) => {
10887
+ const toastData = {
10888
+ description: message,
10889
+ action: (options == null ? void 0 : options.actionLabel) ? {
10890
+ label: options.actionLabel,
10891
+ onClick: options.onActionClick
10892
+ } : void 0,
10893
+ icon: options == null ? void 0 : options.icon,
10894
+ asLink: options == null ? void 0 : options.asLink,
10895
+ duration: options == null ? void 0 : options.duration
10896
+ };
10897
+ toast.queue.push(toastData);
10898
+ if (typeof window !== "undefined") {
10899
+ window.dispatchEvent(new CustomEvent("toast-queue-updated"));
10900
+ }
10901
+ },
10902
+ success: (message, options) => {
10903
+ toast.show(message, { ...options });
10904
+ },
10905
+ error: (message, options) => {
10906
+ toast.show(message, { ...options });
10907
+ },
10908
+ warning: (message, options) => {
10909
+ toast.show(message, { ...options });
10910
+ },
10911
+ info: (message, options) => {
10912
+ toast.show(message, { ...options });
10913
+ }
10914
+ };
10915
+ const DURATION = {
10916
+ DEFAULT: 2500,
10917
+ HAS_ACTION: 5500
10918
+ };
10919
+ const ToastProvider = ({ children }) => {
10920
+ const toaster = createToaster({
10921
+ placement: "bottom",
10922
+ duration: DURATION.DEFAULT,
10923
+ offsets: {
10924
+ bottom: "55px",
10925
+ top: "0px",
10926
+ left: "0px",
10927
+ right: "0px"
10928
+ },
10929
+ overlap: true
10930
+ });
10931
+ React.useEffect(() => {
10932
+ let currentZIndexCounter = 1300;
10933
+ const showToasts = () => {
10934
+ const queuedToasts = toast._getQueue();
10935
+ queuedToasts.forEach((toastData) => {
10936
+ try {
10937
+ const options = {
10938
+ description: toastData.description,
10939
+ zIndex: currentZIndexCounter++
10940
+ // 증가된 zIndex 값 사용
10941
+ };
10942
+ options.data = {
10943
+ icon: toastData.icon ? toastData.icon : null,
10944
+ asLink: toastData.asLink,
10945
+ zIndex: options.zIndex
10946
+ // zIndex를 data에도 저장
10947
+ };
10948
+ if (toastData.action) {
10949
+ options.action = {
10950
+ label: toastData.action.label,
10951
+ onClick: toastData.action.onClick ?? (() => {
10952
+ }),
10953
+ duration: DURATION.HAS_ACTION
10954
+ };
10955
+ }
10956
+ if (toastData.duration) {
10957
+ options.duration = toastData.duration;
10958
+ }
10959
+ toaster.create(options);
10960
+ } catch (error) {
10961
+ console.error("Error creating toast:", error);
10962
+ }
10963
+ });
10964
+ };
10965
+ showToasts();
10966
+ const handleToastQueue = () => showToasts();
10967
+ window.addEventListener("toast-queue-updated", handleToastQueue);
10968
+ return () => {
10969
+ window.removeEventListener("toast-queue-updated", handleToastQueue);
10970
+ };
10971
+ }, [toaster]);
10972
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
10973
+ children,
10974
+ /* @__PURE__ */ jsxRuntime.jsx(Toaster, { toaster, children: (toast2) => {
10975
+ var _a, _b, _c, _d, _e;
10976
+ return /* @__PURE__ */ jsxRuntime.jsxs(
10977
+ Toast.Root,
10978
+ {
10979
+ asLink: (_a = toast2.data) == null ? void 0 : _a.asLink,
10980
+ style: { zIndex: ((_b = toast2.data) == null ? void 0 : _b.zIndex) || 1e3 },
10981
+ children: [
10982
+ /* @__PURE__ */ jsxRuntime.jsxs(Toast.Content, { children: [
10983
+ ((_c = toast2.data) == null ? void 0 : _c.icon) && /* @__PURE__ */ jsxRuntime.jsx(Toast.Icon, { children: toast2.data.icon }),
10984
+ toast2.description && /* @__PURE__ */ jsxRuntime.jsx(Toast.Description, { children: toast2.description })
10985
+ ] }),
10986
+ toast2.action && /* @__PURE__ */ jsxRuntime.jsx(Toast.ActionTrigger, { onClick: (_d = toast2.action) == null ? void 0 : _d.onClick, children: (_e = toast2.action) == null ? void 0 : _e.label })
10987
+ ]
10988
+ },
10989
+ toast2.id
10990
+ );
10991
+ } })
10992
+ ] });
10993
+ };
9568
10994
  exports.BottomSheet = BottomSheet;
9569
10995
  exports.Box = Box2;
9570
10996
  exports.Button = index$1;
@@ -9583,6 +11009,8 @@ exports.Stack = Stack2;
9583
11009
  exports.Tag = Tag;
9584
11010
  exports.Text = Text;
9585
11011
  exports.TextArea = Textarea;
11012
+ exports.ToastProvider = ToastProvider;
9586
11013
  exports.VStack = VStack2;
9587
11014
  exports.preset = preset;
11015
+ exports.toast = toast;
9588
11016
  //# sourceMappingURL=index.cjs.map