@fluid-app/portal-sdk 0.1.302 → 0.1.304

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.
@@ -2754,6 +2754,8 @@ const subscriptionsDomain = require_static_dict_adapter.createDomainTranslations
2754
2754
  no_image: "No image",
2755
2755
  quantity_label: "Quantity",
2756
2756
  quantity_aria: "Quantity",
2757
+ decrease_quantity_aria: "Decrease quantity",
2758
+ increase_quantity_aria: "Increase quantity",
2757
2759
  subtotal: "Subtotal",
2758
2760
  discount: "Discount",
2759
2761
  total_label: "Total",
@@ -4209,7 +4211,7 @@ function SubscriptionDetailSkeleton() {
4209
4211
  })]
4210
4212
  });
4211
4213
  }
4212
- function QuantityInput({ inputId, quantity, isUpdatingQuantity, onQuantityChange, quantityAriaLabel }) {
4214
+ function QuantityInput({ inputId, quantity, maxQuantity, isUpdatingQuantity, onQuantityChange, quantityAriaLabel, decrementAriaLabel, incrementAriaLabel }) {
4213
4215
  const inputRef = (0, react.useRef)(null);
4214
4216
  const [inputValue, setInputValue] = (0, react.useState)(String(quantity));
4215
4217
  const focusEntryQuantityRef = (0, react.useRef)(quantity);
@@ -4232,41 +4234,79 @@ function QuantityInput({ inputId, quantity, isUpdatingQuantity, onQuantityChange
4232
4234
  focusEntryQuantityRef.current = next;
4233
4235
  }, 500);
4234
4236
  };
4235
- return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
4236
- ref: inputRef,
4237
- id: inputId,
4238
- type: "number",
4239
- min: 1,
4240
- step: 1,
4241
- value: inputValue,
4242
- onFocus: () => {
4243
- focusEntryQuantityRef.current = quantity;
4244
- },
4245
- onChange: (e) => {
4246
- const raw = e.target.value;
4247
- setInputValue(raw);
4248
- if (raw === "") {
4249
- if (commitTimerRef.current) clearTimeout(commitTimerRef.current);
4250
- return;
4251
- }
4252
- const next = parseInt(raw, 10);
4253
- if (Number.isFinite(next) && next > 0) scheduleCommit(next);
4254
- },
4255
- onBlur: () => {
4256
- if (commitTimerRef.current) clearTimeout(commitTimerRef.current);
4257
- const parsed = parseInt(inputValue, 10);
4258
- if (Number.isFinite(parsed) && parsed > 0) {
4259
- if (parsed !== quantity) onQuantityChange(parsed);
4260
- focusEntryQuantityRef.current = parsed;
4261
- } else {
4262
- const restore = focusEntryQuantityRef.current;
4263
- setInputValue(String(restore));
4264
- if (restore !== quantity) onQuantityChange(restore);
4265
- }
4266
- },
4267
- readOnly: isUpdatingQuantity,
4268
- className: require_src.cn("border-border bg-background h-10 w-16 border text-center", isUpdatingQuantity && "opacity-60"),
4269
- "aria-label": quantityAriaLabel
4237
+ const parsedInput = parseInt(inputValue, 10);
4238
+ const currentValue = Number.isFinite(parsedInput) && parsedInput > 0 ? parsedInput : quantity;
4239
+ const decrementDisabled = isUpdatingQuantity || currentValue <= 1;
4240
+ const incrementDisabled = isUpdatingQuantity || maxQuantity != null && currentValue >= maxQuantity;
4241
+ const clampToBounds = (n) => maxQuantity != null ? Math.min(maxQuantity, Math.max(1, n)) : Math.max(1, n);
4242
+ const stepBy = (delta) => {
4243
+ const clamped = clampToBounds(currentValue + delta);
4244
+ if (clamped === currentValue) return;
4245
+ setInputValue(String(clamped));
4246
+ scheduleCommit(clamped);
4247
+ };
4248
+ const stepperButtonClass = require_src.cn("text-muted-foreground hover:text-foreground hover:bg-muted flex h-7 w-7 shrink-0 items-center justify-center rounded-full shadow-xs disabled:cursor-not-allowed");
4249
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
4250
+ className: require_src.cn("border-border bg-background focus-within:border-ring focus-within:ring-ring/50 flex h-7.5 items-center justify-between rounded-2xl border focus-within:ring-[3px]", isUpdatingQuantity && "opacity-60"),
4251
+ children: [
4252
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4253
+ type: "button",
4254
+ onClick: () => stepBy(-1),
4255
+ disabled: decrementDisabled,
4256
+ "aria-label": decrementAriaLabel,
4257
+ "aria-controls": inputId,
4258
+ className: require_src.cn(stepperButtonClass, decrementDisabled && "opacity-40"),
4259
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Minus, { className: "h-3 w-3" })
4260
+ }),
4261
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_src.Input, {
4262
+ ref: inputRef,
4263
+ id: inputId,
4264
+ type: "number",
4265
+ min: 1,
4266
+ max: maxQuantity ?? void 0,
4267
+ step: 1,
4268
+ value: inputValue,
4269
+ onFocus: () => {
4270
+ focusEntryQuantityRef.current = currentValue;
4271
+ },
4272
+ onChange: (e) => {
4273
+ const raw = e.target.value;
4274
+ setInputValue(raw);
4275
+ if (raw === "") {
4276
+ if (commitTimerRef.current) clearTimeout(commitTimerRef.current);
4277
+ return;
4278
+ }
4279
+ const next = parseInt(raw, 10);
4280
+ if (Number.isFinite(next) && next > 0) scheduleCommit(clampToBounds(next));
4281
+ },
4282
+ onBlur: () => {
4283
+ if (commitTimerRef.current) clearTimeout(commitTimerRef.current);
4284
+ const parsed = parseInt(inputValue, 10);
4285
+ if (Number.isFinite(parsed) && parsed > 0) {
4286
+ const clamped = clampToBounds(parsed);
4287
+ if (clamped !== parsed) setInputValue(String(clamped));
4288
+ if (clamped !== quantity) onQuantityChange(clamped);
4289
+ focusEntryQuantityRef.current = clamped;
4290
+ } else {
4291
+ const restore = focusEntryQuantityRef.current;
4292
+ setInputValue(String(restore));
4293
+ if (restore !== quantity) onQuantityChange(restore);
4294
+ }
4295
+ },
4296
+ readOnly: isUpdatingQuantity,
4297
+ className: "text-foreground h-7 w-10 rounded-none border-0 bg-transparent px-0 text-center text-xs font-semibold shadow-none [-moz-appearance:textfield] focus-visible:border-0 focus-visible:ring-0 md:text-xs [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
4298
+ "aria-label": quantityAriaLabel
4299
+ }),
4300
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
4301
+ type: "button",
4302
+ onClick: () => stepBy(1),
4303
+ disabled: incrementDisabled,
4304
+ "aria-label": incrementAriaLabel,
4305
+ "aria-controls": inputId,
4306
+ className: require_src.cn(stepperButtonClass, incrementDisabled && "opacity-40"),
4307
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "h-3 w-3" })
4308
+ })
4309
+ ]
4270
4310
  });
4271
4311
  }
4272
4312
  function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBillDate, canEditQuantity = false, onQuantityChange, isUpdatingQuantity = false }) {
@@ -4375,9 +4415,12 @@ function SubscriptionItemsSection({ subscription, displayQuantity, displayNextBi
4375
4415
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuantityInput, {
4376
4416
  inputId: quantityInputId,
4377
4417
  quantity,
4418
+ maxQuantity: subscription.subscription_plan.max_quantity,
4378
4419
  isUpdatingQuantity,
4379
4420
  onQuantityChange,
4380
- quantityAriaLabel: t("quantity_aria")
4421
+ quantityAriaLabel: t("quantity_aria"),
4422
+ decrementAriaLabel: t("decrease_quantity_aria"),
4423
+ incrementAriaLabel: t("increase_quantity_aria")
4381
4424
  })]
4382
4425
  })]
4383
4426
  })
@@ -5767,4 +5810,4 @@ Object.defineProperty(exports, "subscriptionsScreenPropertySchema", {
5767
5810
  }
5768
5811
  });
5769
5812
 
5770
- //# sourceMappingURL=SubscriptionsScreen-YL-1_nFd.cjs.map
5813
+ //# sourceMappingURL=SubscriptionsScreen-BxnLHm31.cjs.map