@geomak/ui 5.7.0 → 5.7.2

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
@@ -2200,6 +2200,7 @@ function FieldLabel({
2200
2200
  required,
2201
2201
  helperText,
2202
2202
  horizontal = false,
2203
+ align = "start",
2203
2204
  style,
2204
2205
  width,
2205
2206
  className = ""
@@ -2211,7 +2212,10 @@ function FieldLabel({
2211
2212
  style: { width: horizontal ? width : void 0, ...style },
2212
2213
  className: [
2213
2214
  "flex items-center gap-1",
2214
- horizontal ? "mt-2 flex-shrink-0 whitespace-nowrap" : "",
2215
+ horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
2216
+ // Only the 'start' alignment needs the top nudge; 'center' relies
2217
+ // on the row's items-center to line up with a short control.
2218
+ horizontal && align === "start" ? "mt-2" : "",
2215
2219
  className
2216
2220
  ].filter(Boolean).join(" "),
2217
2221
  children: [
@@ -2232,6 +2236,7 @@ function Field({
2232
2236
  layout = "vertical",
2233
2237
  required,
2234
2238
  helperText,
2239
+ labelAlign = "start",
2235
2240
  labelStyle,
2236
2241
  labelWidth,
2237
2242
  className = "",
@@ -2244,7 +2249,7 @@ function Field({
2244
2249
  {
2245
2250
  className: [
2246
2251
  "flex",
2247
- horizontal ? "flex-row items-start gap-3" : "flex-col gap-1.5",
2252
+ horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
2248
2253
  className
2249
2254
  ].filter(Boolean).join(" "),
2250
2255
  children: [
@@ -2256,6 +2261,7 @@ function Field({
2256
2261
  required,
2257
2262
  helperText,
2258
2263
  horizontal,
2264
+ align: labelAlign,
2259
2265
  style: labelStyle,
2260
2266
  width: labelWidth
2261
2267
  }
@@ -3714,14 +3720,15 @@ function Checkbox({
3714
3720
  // legacy alias
3715
3721
  onChange,
3716
3722
  label,
3723
+ description,
3717
3724
  name,
3718
3725
  htmlFor,
3719
3726
  errorMessage,
3727
+ helperText,
3720
3728
  disabled = false,
3729
+ required,
3721
3730
  layout = "horizontal",
3722
- labelPosition = "right",
3723
- helperText,
3724
- required
3731
+ labelPosition = "right"
3725
3732
  }) {
3726
3733
  const isChecked = checked ?? value ?? false;
3727
3734
  const labelFirst = labelPosition === "left";
@@ -3734,11 +3741,12 @@ function Checkbox({
3734
3741
  name,
3735
3742
  checked: isChecked,
3736
3743
  disabled,
3744
+ required,
3737
3745
  onCheckedChange: (c) => onChange?.({ target: { checked: !!c, id: htmlFor, name } }),
3738
3746
  className: [
3739
- "relative flex h-[18px] w-[18px] flex-shrink-0 items-center justify-center",
3747
+ "relative mt-0.5 flex h-[18px] w-[18px] flex-shrink-0 items-center justify-center",
3740
3748
  "rounded-sm border transition-colors duration-150",
3741
- "border-border-strong bg-surface",
3749
+ hasError ? "border-status-error" : "border-border-strong",
3742
3750
  "data-[state=checked]:bg-accent data-[state=checked]:border-accent",
3743
3751
  // Focus halo matches the field tokens for a consistent look.
3744
3752
  "focus:outline-none focus-visible:ring-[3px] focus-visible:ring-focus-ring",
@@ -3750,33 +3758,60 @@ function Checkbox({
3750
3758
  children: /* @__PURE__ */ jsxRuntime.jsx(CheckboxPrimitive__namespace.Indicator, { className: "flex items-center justify-center data-[state=checked]:animate-check-pop", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "11", height: "9", viewBox: "0 0 11 9", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 4.5L4 7.5L10 1", stroke: "white", strokeWidth: "1.8", strokeLinecap: "round", strokeLinejoin: "round" }) }) })
3751
3759
  }
3752
3760
  );
3753
- const labelEl = label && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-foreground-secondary select-none leading-snug", children: [
3754
- label,
3755
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
3756
- ] });
3761
+ const labelText = label != null && /* @__PURE__ */ jsxRuntime.jsxs(
3762
+ "label",
3763
+ {
3764
+ htmlFor,
3765
+ className: ["block select-none text-sm text-foreground leading-snug", disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"].join(" "),
3766
+ children: [
3767
+ label,
3768
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
3769
+ ]
3770
+ }
3771
+ );
3772
+ const descriptionEl = description != null && /* @__PURE__ */ jsxRuntime.jsx(
3773
+ "label",
3774
+ {
3775
+ htmlFor,
3776
+ className: `block text-xs text-foreground-secondary mt-0.5 ${disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}`,
3777
+ children: description
3778
+ }
3779
+ );
3780
+ let content;
3781
+ if (layout === "vertical") {
3782
+ content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col items-start gap-1.5", children: [
3783
+ labelFirst ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3784
+ labelText,
3785
+ box
3786
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3787
+ box,
3788
+ labelText
3789
+ ] }),
3790
+ descriptionEl
3791
+ ] });
3792
+ } else if (labelFirst) {
3793
+ content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col", children: [
3794
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start gap-2.5", children: [
3795
+ labelText,
3796
+ box
3797
+ ] }),
3798
+ descriptionEl
3799
+ ] });
3800
+ } else {
3801
+ content = /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-start gap-2.5", children: [
3802
+ box,
3803
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col", children: [
3804
+ labelText,
3805
+ descriptionEl
3806
+ ] })
3807
+ ] });
3808
+ }
3757
3809
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
3758
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
3759
- /* @__PURE__ */ jsxRuntime.jsx(
3760
- "label",
3761
- {
3762
- htmlFor,
3763
- className: [
3764
- "inline-flex",
3765
- layout === "vertical" ? "flex-col items-start gap-1.5" : "flex-row items-center gap-2.5",
3766
- disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
3767
- ].join(" "),
3768
- children: labelFirst ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3769
- labelEl,
3770
- box
3771
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3772
- box,
3773
- labelEl
3774
- ] })
3775
- }
3776
- ),
3810
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-1", children: [
3811
+ content,
3777
3812
  helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
3778
3813
  ] }),
3779
- errorMessage && /* @__PURE__ */ jsxRuntime.jsx("span", { id: errorId, className: "text-xs text-status-error mt-0.5", children: errorMessage })
3814
+ hasError && /* @__PURE__ */ jsxRuntime.jsx("span", { id: errorId, className: "text-xs text-status-error mt-0.5", children: errorMessage })
3780
3815
  ] });
3781
3816
  }
3782
3817
  var DOT_SIZE = {
@@ -3852,29 +3887,35 @@ function RadioGroup({
3852
3887
  children: /* @__PURE__ */ jsxRuntime.jsx(RadioGroupPrimitive__namespace.Indicator, { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block h-1/2 w-1/2 rounded-full bg-accent" }) })
3853
3888
  }
3854
3889
  );
3855
- const labelEl = /* @__PURE__ */ jsxRuntime.jsxs(
3890
+ const labelClass = [
3891
+ "block select-none",
3892
+ opt.disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"
3893
+ ].join(" ");
3894
+ const labelTextEl = /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: itemId, className: labelClass, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `block ${TEXT_SIZE[size]} text-foreground`, children: opt.label }) });
3895
+ const descriptionEl = opt.description ? /* @__PURE__ */ jsxRuntime.jsx(
3856
3896
  "label",
3857
3897
  {
3858
3898
  htmlFor: itemId,
3859
- className: [
3860
- "select-none",
3861
- opt.disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer",
3862
- labelFirst ? "text-right" : ""
3863
- ].filter(Boolean).join(" "),
3864
- children: [
3865
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: `block ${TEXT_SIZE[size]} text-foreground`, children: opt.label }),
3866
- opt.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-xs text-foreground-secondary mt-0.5", children: opt.description })
3867
- ]
3899
+ className: `block text-xs text-foreground-secondary mt-0.5 ${opt.disabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer"}`,
3900
+ children: opt.description
3868
3901
  }
3869
- );
3870
- const rowClass = labelFirst && layout === "vertical" ? "grid grid-cols-[1fr_auto] items-start gap-2.5" : "flex items-start gap-2.5";
3871
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: rowClass, children: labelFirst ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3872
- labelEl,
3873
- dot
3874
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
3902
+ ) : null;
3903
+ if (labelFirst) {
3904
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
3905
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2.5", children: [
3906
+ labelTextEl,
3907
+ dot
3908
+ ] }),
3909
+ descriptionEl
3910
+ ] }, opt.value);
3911
+ }
3912
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start gap-2.5", children: [
3875
3913
  dot,
3876
- labelEl
3877
- ] }) }, opt.value);
3914
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col", children: [
3915
+ labelTextEl,
3916
+ descriptionEl
3917
+ ] })
3918
+ ] }, opt.value);
3878
3919
  })
3879
3920
  }
3880
3921
  )
@@ -3922,6 +3963,7 @@ function Switch({
3922
3963
  layout,
3923
3964
  required,
3924
3965
  helperText,
3966
+ labelAlign: "center",
3925
3967
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5", children: [
3926
3968
  offLabel != null && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: stateLabel(!isOn), children: offLabel }),
3927
3969
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -4211,19 +4253,17 @@ function TreeSelect({
4211
4253
  setOpen(false);
4212
4254
  }
4213
4255
  };
4214
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-1", children: [
4215
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex ${layout === "vertical" ? "flex-col gap-1" : "flex-row items-center gap-2"}`, children: [
4216
- /* @__PURE__ */ jsxRuntime.jsx(
4217
- FieldLabel,
4218
- {
4219
- label,
4220
- htmlFor,
4221
- required,
4222
- helperText,
4223
- horizontal: layout === "horizontal"
4224
- }
4225
- ),
4226
- /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
4256
+ return /* @__PURE__ */ jsxRuntime.jsx(
4257
+ Field,
4258
+ {
4259
+ label,
4260
+ htmlFor,
4261
+ errorId,
4262
+ errorMessage,
4263
+ layout,
4264
+ required,
4265
+ helperText,
4266
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open: open && !disabled, onOpenChange: (o) => !disabled && setOpen(o), children: [
4227
4267
  /* @__PURE__ */ jsxRuntime.jsx(Popover__namespace.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
4228
4268
  "button",
4229
4269
  {
@@ -4287,10 +4327,9 @@ function TreeSelect({
4287
4327
  )
4288
4328
  }
4289
4329
  ) })
4290
- ] })
4291
- ] }),
4292
- hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-xs text-status-error ml-1", children: errorMessage })
4293
- ] });
4330
+ ] }) })
4331
+ }
4332
+ );
4294
4333
  }
4295
4334
  function TreeNodeRow({
4296
4335
  node,