@timeax/form-palette 0.0.25 → 0.0.27

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.js CHANGED
@@ -15248,6 +15248,65 @@ var ToggleVariantModule = {
15248
15248
  }
15249
15249
  };
15250
15250
  var toggle_default2 = ToggleVariantModule;
15251
+
15252
+ // src/lib/group-layout.ts
15253
+ function buildGroupLayoutClasses(opts) {
15254
+ const {
15255
+ layout,
15256
+ columns,
15257
+ itemGapPx,
15258
+ groupClassName,
15259
+ className,
15260
+ optionClassName,
15261
+ labelClassName,
15262
+ descriptionClassName,
15263
+ densityPaddingClass,
15264
+ labelTextSizeClass,
15265
+ descriptionTextSizeClass
15266
+ } = opts;
15267
+ let groupStyle;
15268
+ if (!itemGapPx) {
15269
+ if (layout === "grid") {
15270
+ groupStyle = {
15271
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
15272
+ };
15273
+ }
15274
+ } else if (layout === "list") {
15275
+ groupStyle = { rowGap: itemGapPx };
15276
+ } else {
15277
+ groupStyle = {
15278
+ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
15279
+ gap: itemGapPx
15280
+ };
15281
+ }
15282
+ const groupClasses = cn(
15283
+ layout === "grid" ? "grid" : "flex flex-col",
15284
+ groupClassName != null ? groupClassName : className
15285
+ );
15286
+ const baseOptionClass = cn(
15287
+ "relative flex items-start",
15288
+ "data-[disabled=true]:opacity-60 data-[disabled=true]:cursor-not-allowed",
15289
+ densityPaddingClass,
15290
+ optionClassName
15291
+ );
15292
+ const labelClassesBase = cn(
15293
+ "font-medium text-foreground",
15294
+ labelTextSizeClass,
15295
+ labelClassName
15296
+ );
15297
+ const descriptionClassesBase = cn(
15298
+ "mt-0.5 text-muted-foreground",
15299
+ descriptionTextSizeClass,
15300
+ descriptionClassName
15301
+ );
15302
+ return {
15303
+ groupStyle,
15304
+ groupClasses,
15305
+ baseOptionClass,
15306
+ labelClassesBase,
15307
+ descriptionClassesBase
15308
+ };
15309
+ }
15251
15310
  function RadioGroup({
15252
15311
  className,
15253
15312
  ...props
@@ -15285,6 +15344,139 @@ function RadioGroupItem({
15285
15344
  }
15286
15345
  );
15287
15346
  }
15347
+
15348
+ // src/lib/normalise-options.ts
15349
+ function isPrimitiveOption(raw) {
15350
+ return typeof raw === "string" || typeof raw === "number";
15351
+ }
15352
+ function asObject(raw) {
15353
+ return isPrimitiveOption(raw) ? { label: String(raw), value: raw } : raw;
15354
+ }
15355
+ var RENDER_KEYS = [
15356
+ "render",
15357
+ "renderOption",
15358
+ "renderItem",
15359
+ "renderLabel",
15360
+ "renderer"
15361
+ ];
15362
+ function resolveRender(obj) {
15363
+ if (!obj) return void 0;
15364
+ for (const k of RENDER_KEYS) {
15365
+ const maybe = obj[k];
15366
+ if (typeof maybe === "function") return maybe;
15367
+ }
15368
+ return void 0;
15369
+ }
15370
+ function resolveValue(raw, obj, index, optionValue) {
15371
+ var _a, _b, _c;
15372
+ return typeof optionValue === "function" ? optionValue(raw) : typeof optionValue === "string" ? obj[optionValue] : (_c = (_b = (_a = obj.value) != null ? _a : obj.id) != null ? _b : obj.key) != null ? _c : String(index);
15373
+ }
15374
+ function resolveLabelNode(raw, obj, value, optionLabel) {
15375
+ var _a, _b, _c;
15376
+ return typeof optionLabel === "function" ? optionLabel(raw) : typeof optionLabel === "string" ? (_b = (_a = obj[optionLabel]) != null ? _a : obj.label) != null ? _b : String(value) : (_c = obj.label) != null ? _c : String(value);
15377
+ }
15378
+ function resolveDescription(raw, obj, optionDescription) {
15379
+ return typeof optionDescription === "function" ? optionDescription(raw) : typeof optionDescription === "string" ? obj[optionDescription] : obj.description;
15380
+ }
15381
+ function resolveDisabled(raw, obj, optionDisabled) {
15382
+ return typeof optionDisabled === "function" ? optionDisabled(raw) : typeof optionDisabled === "string" ? !!obj[optionDisabled] : !!obj.disabled;
15383
+ }
15384
+ function resolveIcon(raw, obj, optionIcon) {
15385
+ return typeof optionIcon === "function" ? optionIcon(raw) : typeof optionIcon === "string" ? obj[optionIcon] : obj.icon;
15386
+ }
15387
+ function resolveKey(raw, obj, index, value, optionKey) {
15388
+ var _a, _b, _c, _d;
15389
+ return typeof optionKey === "function" ? optionKey(raw, index) : typeof optionKey === "string" ? (_b = (_a = obj[optionKey]) != null ? _a : value) != null ? _b : index : (_d = (_c = obj.key) != null ? _c : value) != null ? _d : index;
15390
+ }
15391
+ function resolveLabelText(labelNode, obj, value) {
15392
+ var _a;
15393
+ return typeof labelNode === "string" ? labelNode : typeof labelNode === "number" ? String(labelNode) : (_a = obj.labelText) != null ? _a : String(value);
15394
+ }
15395
+ function normalizeOne(raw, index, config) {
15396
+ const obj = asObject(raw);
15397
+ const value = resolveValue(raw, obj, index, config.optionValue);
15398
+ let labelNode = resolveLabelNode(raw, obj, value, config.optionLabel);
15399
+ if (config.autoCap && typeof labelNode === "string") {
15400
+ labelNode = capitalizeFirst(labelNode);
15401
+ }
15402
+ const labelText = resolveLabelText(labelNode, obj, value);
15403
+ const description = resolveDescription(raw, obj, config.optionDescription);
15404
+ const disabled = resolveDisabled(raw, obj, config.optionDisabled);
15405
+ const icon = resolveIcon(raw, obj, config.optionIcon);
15406
+ const key = resolveKey(raw, obj, index, value, config.optionKey);
15407
+ const render = resolveRender(obj);
15408
+ return {
15409
+ key: String(key),
15410
+ value,
15411
+ labelNode,
15412
+ labelText,
15413
+ description,
15414
+ disabled,
15415
+ icon,
15416
+ render,
15417
+ raw
15418
+ };
15419
+ }
15420
+ function globalNormalizeOptions(opts, config) {
15421
+ if (!opts || !opts.length) return [];
15422
+ return opts.map(
15423
+ (raw, index) => normalizeOne(raw, index, config)
15424
+ );
15425
+ }
15426
+ function globalNormalizeCheckBasedOptions(item, index, optionLabelKey, optionValueKey) {
15427
+ var _a, _b;
15428
+ const anyItem = item;
15429
+ const rawValue = optionValueKey != null ? anyItem[optionValueKey] : anyItem.value;
15430
+ const value = rawValue;
15431
+ const rawLabel = optionLabelKey != null ? anyItem[optionLabelKey] : (_a = anyItem.label) != null ? _a : String(rawValue != null ? rawValue : index);
15432
+ const description = anyItem.description;
15433
+ const disabled = !!anyItem.disabled;
15434
+ const key = (_b = anyItem.key) != null ? _b : index;
15435
+ const render = resolveRender(anyItem);
15436
+ return {
15437
+ key: String(key),
15438
+ value,
15439
+ label: rawLabel,
15440
+ description,
15441
+ disabled,
15442
+ render,
15443
+ raw: item
15444
+ };
15445
+ }
15446
+ function normalizeTree(opts, config, level = 0, parentValue, path = []) {
15447
+ if (!opts || !opts.length) return [];
15448
+ return opts.map((raw, index) => {
15449
+ const obj = asObject(raw);
15450
+ const base = normalizeOne(
15451
+ raw,
15452
+ index,
15453
+ config
15454
+ // (config shape matches; this avoids duplicating the resolver types)
15455
+ );
15456
+ const childrenRaw = obj.children;
15457
+ const nextPath = [...path, base.value];
15458
+ const children = normalizeTree(
15459
+ childrenRaw != null ? childrenRaw : [],
15460
+ config,
15461
+ level + 1,
15462
+ base.value,
15463
+ nextPath
15464
+ );
15465
+ return {
15466
+ ...base,
15467
+ level,
15468
+ parentValue,
15469
+ path,
15470
+ // ancestors only (EXACT behaviour preserved)
15471
+ hasChildren: !!children.length,
15472
+ children
15473
+ };
15474
+ });
15475
+ }
15476
+ function capitalizeFirst(label) {
15477
+ if (!label) return label;
15478
+ return label.charAt(0).toUpperCase() + label.slice(1);
15479
+ }
15288
15480
  function paddingForDensity(density) {
15289
15481
  switch (density) {
15290
15482
  case "compact":
@@ -15318,7 +15510,7 @@ function descriptionTextSize(size) {
15318
15510
  return "text-xs";
15319
15511
  }
15320
15512
  }
15321
- function capitalizeFirst(label) {
15513
+ function capitalizeFirst2(label) {
15322
15514
  if (!label) return label;
15323
15515
  return label.charAt(0).toUpperCase() + label.slice(1);
15324
15516
  }
@@ -15334,21 +15526,12 @@ function normalizeItems(items, mappers, optionValueKey, optionLabelKey) {
15334
15526
  }
15335
15527
  if (optionValueKey || optionLabelKey) {
15336
15528
  return items.map((item, index) => {
15337
- var _a, _b;
15338
- const anyItem = item;
15339
- const rawValue = optionValueKey != null ? anyItem[optionValueKey] : anyItem.value;
15340
- const value = rawValue;
15341
- const rawLabel = optionLabelKey != null ? anyItem[optionLabelKey] : (_a = anyItem.label) != null ? _a : String(rawValue != null ? rawValue : index);
15342
- const description = anyItem.description;
15343
- const disabled = !!anyItem.disabled;
15344
- const key = (_b = anyItem.key) != null ? _b : index;
15345
- return {
15346
- value,
15347
- label: rawLabel,
15348
- description,
15349
- disabled,
15350
- key
15351
- };
15529
+ return globalNormalizeCheckBasedOptions(
15530
+ item,
15531
+ index,
15532
+ optionLabelKey,
15533
+ optionValueKey
15534
+ );
15352
15535
  });
15353
15536
  }
15354
15537
  return items.map((item, index) => {
@@ -15435,54 +15618,31 @@ var InnerShadcnRadioVariant = (props, ref) => {
15435
15618
  );
15436
15619
  const handleRadioChange = React10__namespace.useCallback(
15437
15620
  (raw) => {
15438
- const found = normalized.find(
15439
- (item) => String(item.value) === raw
15440
- );
15621
+ const found = normalized.find((item) => String(item.value) === raw);
15441
15622
  if (!found) return;
15442
15623
  handleSelect(found.value);
15443
15624
  },
15444
15625
  [normalized, handleSelect]
15445
15626
  );
15446
- const groupStyle = React10__namespace.useMemo(() => {
15447
- if (!itemGapPx) {
15448
- if (layout === "grid") {
15449
- return {
15450
- gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
15451
- };
15452
- }
15453
- return void 0;
15454
- }
15455
- if (layout === "list") {
15456
- return { rowGap: itemGapPx };
15457
- }
15458
- return {
15459
- gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
15460
- gap: itemGapPx
15461
- };
15462
- }, [layout, columns, itemGapPx]);
15463
- const groupClasses = cn(
15464
- layout === "grid" ? "grid" : "flex flex-col",
15465
- groupClassName != null ? groupClassName : className
15466
- );
15467
- const baseOptionClass = cn(
15468
- // layout container for each option row
15469
- "relative flex items-start",
15470
- // keep disabled styles
15471
- "data-[disabled=true]:opacity-60 data-[disabled=true]:cursor-not-allowed",
15472
- // vertical padding from density
15473
- paddingForDensity(density),
15474
- optionClassName
15475
- );
15476
- const labelClassesBase = cn(
15477
- "font-medium text-foreground",
15478
- labelTextSize(size),
15479
- labelClassName
15480
- );
15481
- const descriptionClassesBase = cn(
15482
- "mt-0.5 text-muted-foreground",
15483
- descriptionTextSize(size),
15484
- descriptionClassName
15485
- );
15627
+ const {
15628
+ groupStyle,
15629
+ groupClasses,
15630
+ baseOptionClass,
15631
+ labelClassesBase,
15632
+ descriptionClassesBase
15633
+ } = buildGroupLayoutClasses({
15634
+ layout,
15635
+ columns,
15636
+ itemGapPx,
15637
+ groupClassName,
15638
+ className,
15639
+ optionClassName,
15640
+ labelClassName,
15641
+ descriptionClassName,
15642
+ densityPaddingClass: paddingForDensity(density),
15643
+ labelTextSizeClass: labelTextSize(size),
15644
+ descriptionTextSizeClass: descriptionTextSize(size)
15645
+ });
15486
15646
  return /* @__PURE__ */ jsxRuntime.jsx(
15487
15647
  RadioGroup,
15488
15648
  {
@@ -15502,7 +15662,7 @@ var InnerShadcnRadioVariant = (props, ref) => {
15502
15662
  "data-slot": "radio-group",
15503
15663
  ...restGroupProps,
15504
15664
  children: normalized.map((item, index) => {
15505
- var _a;
15665
+ var _a, _b;
15506
15666
  const itemString = String(item.value);
15507
15667
  const selected = selectedString === itemString;
15508
15668
  const optionDisabled = !!disabled || !!item.disabled;
@@ -15512,7 +15672,7 @@ var InnerShadcnRadioVariant = (props, ref) => {
15512
15672
  if (autoCap && typeof item.label === "string") {
15513
15673
  displayItem = {
15514
15674
  ...item,
15515
- label: capitalizeFirst(item.label)
15675
+ label: capitalizeFirst2(item.label)
15516
15676
  };
15517
15677
  }
15518
15678
  const radioNode = /* @__PURE__ */ jsxRuntime.jsx(
@@ -15524,7 +15684,8 @@ var InnerShadcnRadioVariant = (props, ref) => {
15524
15684
  className: "mt-1"
15525
15685
  }
15526
15686
  );
15527
- if (renderOption) {
15687
+ const renderer = (_b = item.render) != null ? _b : renderOption;
15688
+ if (renderer) {
15528
15689
  return /* @__PURE__ */ jsxRuntime.jsx(
15529
15690
  "div",
15530
15691
  {
@@ -15532,7 +15693,7 @@ var InnerShadcnRadioVariant = (props, ref) => {
15532
15693
  "data-checked": selected ? "true" : "false",
15533
15694
  "data-disabled": optionDisabled ? "true" : "false",
15534
15695
  className: baseOptionClass,
15535
- children: renderOption({
15696
+ children: renderer({
15536
15697
  item: displayItem,
15537
15698
  index,
15538
15699
  selected,
@@ -15578,7 +15739,9 @@ var InnerShadcnRadioVariant = (props, ref) => {
15578
15739
  }
15579
15740
  );
15580
15741
  };
15581
- var ShadcnRadioVariant = React10__namespace.forwardRef(InnerShadcnRadioVariant);
15742
+ var ShadcnRadioVariant = React10__namespace.forwardRef(
15743
+ InnerShadcnRadioVariant
15744
+ );
15582
15745
 
15583
15746
  // src/variants/core/radio.tsx
15584
15747
  var radioVariantModule = {
@@ -15690,7 +15853,7 @@ function descriptionTextSize2(size) {
15690
15853
  return "text-xs";
15691
15854
  }
15692
15855
  }
15693
- function capitalizeFirst2(label) {
15856
+ function capitalizeFirst3(label) {
15694
15857
  if (!label) return label;
15695
15858
  return label.charAt(0).toUpperCase() + label.slice(1);
15696
15859
  }
@@ -15708,21 +15871,16 @@ function normalizeItems2(items, mappers, optionValueKey, optionLabelKey) {
15708
15871
  }
15709
15872
  if (optionValueKey || optionLabelKey) {
15710
15873
  return items.map((item, index) => {
15711
- var _a, _b;
15712
15874
  const anyItem = item;
15713
- const rawValue = optionValueKey != null ? anyItem[optionValueKey] : anyItem.value;
15714
- const value = rawValue;
15715
- const rawLabel = optionLabelKey != null ? anyItem[optionLabelKey] : (_a = anyItem.label) != null ? _a : String(rawValue != null ? rawValue : index);
15716
- const description = anyItem.description;
15717
- const disabled = !!anyItem.disabled;
15718
- const key = (_b = anyItem.key) != null ? _b : index;
15875
+ const normalised = globalNormalizeCheckBasedOptions(
15876
+ item,
15877
+ index,
15878
+ optionLabelKey,
15879
+ optionValueKey
15880
+ );
15719
15881
  const tristate = anyItem.tristate;
15720
15882
  return {
15721
- value,
15722
- label: rawLabel,
15723
- description,
15724
- disabled,
15725
- key,
15883
+ ...normalised,
15726
15884
  tristate
15727
15885
  };
15728
15886
  });
@@ -15817,7 +15975,7 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
15817
15975
  };
15818
15976
  let labelText = singleLabel != null ? singleLabel : void 0;
15819
15977
  if (autoCap && typeof labelText === "string") {
15820
- labelText = capitalizeFirst2(labelText);
15978
+ labelText = capitalizeFirst3(labelText);
15821
15979
  }
15822
15980
  const descriptionText = singleDescription != null ? singleDescription : void 0;
15823
15981
  const labelCls = cn(
@@ -15877,43 +16035,25 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
15877
16035
  ),
15878
16036
  [items, mappers, optionValue, optionLabel]
15879
16037
  );
15880
- const groupStyle = React10__namespace.useMemo(() => {
15881
- if (!itemGapPx) {
15882
- if (layout === "grid") {
15883
- return {
15884
- gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`
15885
- };
15886
- }
15887
- return void 0;
15888
- }
15889
- if (layout === "list") {
15890
- return { rowGap: itemGapPx };
15891
- }
15892
- return {
15893
- gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
15894
- gap: itemGapPx
15895
- };
15896
- }, [layout, columns, itemGapPx]);
15897
- const groupClasses = cn(
15898
- layout === "grid" ? "grid" : "flex flex-col",
15899
- groupClassName != null ? groupClassName : className
15900
- );
15901
- const baseOptionClass = cn(
15902
- "relative flex items-start",
15903
- "data-[disabled=true]:opacity-60 data-[disabled=true]:cursor-not-allowed",
15904
- paddingForDensity2(density),
15905
- optionClassName
15906
- );
15907
- const labelClassesBase = cn(
15908
- "font-medium text-foreground",
15909
- labelTextSize2(size),
15910
- labelClassName
15911
- );
15912
- const descriptionClassesBase = cn(
15913
- "mt-0.5 text-muted-foreground",
15914
- descriptionTextSize2(size),
15915
- descriptionClassName
15916
- );
16038
+ const {
16039
+ groupStyle,
16040
+ groupClasses,
16041
+ baseOptionClass,
16042
+ labelClassesBase,
16043
+ descriptionClassesBase
16044
+ } = buildGroupLayoutClasses({
16045
+ layout,
16046
+ columns,
16047
+ itemGapPx,
16048
+ groupClassName,
16049
+ className,
16050
+ optionClassName,
16051
+ labelClassName,
16052
+ descriptionClassName,
16053
+ densityPaddingClass: paddingForDensity2(density),
16054
+ labelTextSizeClass: labelTextSize2(size),
16055
+ descriptionTextSizeClass: descriptionTextSize2(size)
16056
+ });
15917
16057
  const findEntryIndex = React10__namespace.useCallback(
15918
16058
  (val) => {
15919
16059
  if (!groupValue) return -1;
@@ -16009,7 +16149,7 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16009
16149
  style: groupStyle,
16010
16150
  ...restProps,
16011
16151
  children: normalized.map((item, index) => {
16012
- var _a, _b, _c;
16152
+ var _a, _b, _c, _d;
16013
16153
  const effectiveTristate = (_b = (_a = item.tristate) != null ? _a : tristateDefault) != null ? _b : false;
16014
16154
  const currentState = getEntryState(item.value);
16015
16155
  const internalState = effectiveTristate ? currentState : currentState === "none" ? false : currentState;
@@ -16020,7 +16160,7 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16020
16160
  if (autoCap && typeof item.label === "string") {
16021
16161
  displayItem = {
16022
16162
  ...item,
16023
- label: capitalizeFirst2(item.label)
16163
+ label: capitalizeFirst3(item.label)
16024
16164
  };
16025
16165
  }
16026
16166
  const checkboxNode = /* @__PURE__ */ jsxRuntime.jsx(
@@ -16047,7 +16187,8 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16047
16187
  disabled: getEntryState(item.value) === "none"
16048
16188
  }
16049
16189
  ) : null;
16050
- if (renderOption) {
16190
+ const renderer = (_d = item.render) != null ? _d : renderOption;
16191
+ if (renderer) {
16051
16192
  return /* @__PURE__ */ jsxRuntime.jsxs(
16052
16193
  "div",
16053
16194
  {
@@ -16055,7 +16196,7 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16055
16196
  "data-disabled": optionDisabled ? "true" : "false",
16056
16197
  className: baseOptionClass,
16057
16198
  children: [
16058
- renderOption({
16199
+ renderer({
16059
16200
  item: displayItem,
16060
16201
  index,
16061
16202
  state: internalState,
@@ -16067,7 +16208,11 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16067
16208
  click() {
16068
16209
  if (optionDisabled) return;
16069
16210
  const nextInternal = effectiveTristate ? internalState === "none" ? true : internalState === true ? false : "none" : internalState === true ? false : true;
16070
- updateGroupValue(item.value, nextInternal, effectiveTristate);
16211
+ updateGroupValue(
16212
+ item.value,
16213
+ nextInternal,
16214
+ effectiveTristate
16215
+ );
16071
16216
  },
16072
16217
  checkbox: checkboxNode
16073
16218
  }),
@@ -16092,14 +16237,17 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16092
16237
  children: [
16093
16238
  checkboxNode,
16094
16239
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col", children: [
16095
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(labelClassesBase, optionLabelClassName), children: displayItem.label }),
16096
- displayItem.description != null && /* @__PURE__ */ jsxRuntime.jsx(
16240
+ /* @__PURE__ */ jsxRuntime.jsx(
16097
16241
  "span",
16098
16242
  {
16099
- className: descriptionClassesBase,
16100
- children: displayItem.description
16243
+ className: cn(
16244
+ labelClassesBase,
16245
+ optionLabelClassName
16246
+ ),
16247
+ children: displayItem.label
16101
16248
  }
16102
- )
16249
+ ),
16250
+ displayItem.description != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: descriptionClassesBase, children: displayItem.description })
16103
16251
  ] })
16104
16252
  ]
16105
16253
  }
@@ -16113,7 +16261,9 @@ var InnerShadcnCheckboxVariant = (props, ref) => {
16113
16261
  }
16114
16262
  );
16115
16263
  };
16116
- var ShadcnCheckboxVariant = React10__namespace.forwardRef(InnerShadcnCheckboxVariant);
16264
+ var ShadcnCheckboxVariant = React10__namespace.forwardRef(
16265
+ InnerShadcnCheckboxVariant
16266
+ );
16117
16267
 
16118
16268
  // src/variants/core/checkbox.tsx
16119
16269
  var checkboxModule = {
@@ -16134,39 +16284,6 @@ var checkboxModule = {
16134
16284
  tags: ["checkbox", "group", "boolean", "tri-state"]
16135
16285
  }
16136
16286
  };
16137
-
16138
- // src/lib/normalise-selects.ts
16139
- function globalNormalizeOptions(opts, config) {
16140
- if (!opts || !opts.length) return [];
16141
- return opts.map((raw, index) => {
16142
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
16143
- const asObj = typeof raw === "string" || typeof raw === "number" ? { label: String(raw), value: raw } : raw;
16144
- const value = typeof config.optionValue === "function" ? config.optionValue(raw) : typeof config.optionValue === "string" ? asObj[config.optionValue] : (_c = (_b = (_a = asObj.value) != null ? _a : asObj.id) != null ? _b : asObj.key) != null ? _c : String(index);
16145
- let labelNode = typeof config.optionLabel === "function" ? config.optionLabel(raw) : typeof config.optionLabel === "string" ? (_e = (_d = asObj[config.optionLabel]) != null ? _d : asObj.label) != null ? _e : String(value) : (_f = asObj.label) != null ? _f : String(value);
16146
- if (config.autoCap && typeof labelNode === "string") {
16147
- labelNode = capitalizeFirst3(labelNode);
16148
- }
16149
- const labelText = typeof labelNode === "string" ? labelNode : typeof labelNode === "number" ? String(labelNode) : (_g = asObj.labelText) != null ? _g : String(value);
16150
- const description = typeof config.optionDescription === "function" ? config.optionDescription(raw) : typeof config.optionDescription === "string" ? asObj[config.optionDescription] : asObj.description;
16151
- const disabled = typeof config.optionDisabled === "function" ? config.optionDisabled(raw) : typeof config.optionDisabled === "string" ? !!asObj[config.optionDisabled] : !!asObj.disabled;
16152
- const icon = typeof config.optionIcon === "function" ? config.optionIcon(raw) : typeof config.optionIcon === "string" ? asObj[config.optionIcon] : asObj.icon;
16153
- const key = typeof config.optionKey === "function" ? config.optionKey(raw, index) : typeof config.optionKey === "string" ? (_i = (_h = asObj[config.optionKey]) != null ? _h : value) != null ? _i : index : (_k = (_j = asObj.key) != null ? _j : value) != null ? _k : index;
16154
- return {
16155
- key: String(key),
16156
- value,
16157
- labelNode,
16158
- labelText,
16159
- description,
16160
- disabled,
16161
- icon,
16162
- raw
16163
- };
16164
- });
16165
- }
16166
- function capitalizeFirst3(label) {
16167
- if (!label) return label;
16168
- return label.charAt(0).toUpperCase() + label.slice(1);
16169
- }
16170
16287
  function normalizeOptions(opts, config) {
16171
16288
  return globalNormalizeOptions(opts, config);
16172
16289
  }
@@ -16220,6 +16337,8 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16220
16337
  contentClassName,
16221
16338
  renderOption,
16222
16339
  renderValue,
16340
+ // Mode
16341
+ mode = "default",
16223
16342
  // Icons & controls
16224
16343
  leadingIcons,
16225
16344
  trailingIcons,
@@ -16233,11 +16352,15 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16233
16352
  trailingControlClassName,
16234
16353
  joinControls = true,
16235
16354
  extendBoxToControls = true,
16355
+ // Button mode only
16356
+ button,
16357
+ children,
16236
16358
  // Virtual scroll / incremental render
16237
16359
  virtualScroll = false,
16238
16360
  virtualScrollPageSize = 50,
16239
16361
  virtualScrollThreshold = 48
16240
16362
  } = props;
16363
+ const isButtonMode = mode === "button";
16241
16364
  const [open, setOpen] = React10__namespace.useState(false);
16242
16365
  const [query, setQuery] = React10__namespace.useState("");
16243
16366
  const items = React10__namespace.useMemo(
@@ -16330,18 +16453,19 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16330
16453
  const padCls = triggerPadding(density);
16331
16454
  const showClear = clearable && value != null;
16332
16455
  const resolvedLeadingIcons = (() => {
16456
+ if (isButtonMode) return [];
16333
16457
  if (leadingIcons && leadingIcons.length) return leadingIcons;
16334
16458
  if (icon) return [icon];
16335
16459
  return [];
16336
16460
  })();
16337
- const resolvedTrailingIcons = trailingIcons != null ? trailingIcons : [];
16461
+ const resolvedTrailingIcons = isButtonMode ? [] : trailingIcons != null ? trailingIcons : [];
16338
16462
  const baseIconGap = iconGap != null ? iconGap : 4;
16339
16463
  const leadingGap = leadingIconSpacing != null ? leadingIconSpacing : baseIconGap;
16340
16464
  const trailingGap = trailingIconSpacing != null ? trailingIconSpacing : baseIconGap;
16341
16465
  const hasLeadingIcons = resolvedLeadingIcons.length > 0;
16342
16466
  const hasTrailingIcons = resolvedTrailingIcons.length > 0;
16343
- const hasLeadingControl = !!leadingControl;
16344
- const hasTrailingControl = !!trailingControl;
16467
+ const hasLeadingControl = !isButtonMode && !!leadingControl;
16468
+ const hasTrailingControl = !isButtonMode && !!trailingControl;
16345
16469
  const hasControls = hasLeadingControl || hasTrailingControl;
16346
16470
  const triggerInner = renderValue ? renderValue({
16347
16471
  selectedItem,
@@ -16356,7 +16480,57 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16356
16480
  "focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
16357
16481
  "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive"
16358
16482
  );
16359
- const TriggerBody = /* @__PURE__ */ jsxRuntime.jsx(
16483
+ const ButtonModeTrigger = React10__namespace.useMemo(() => {
16484
+ if (!isButtonMode) return null;
16485
+ const selectedValue = value;
16486
+ const renderable = button != null ? button : children;
16487
+ const content = (() => {
16488
+ var _a2, _b2, _c, _d;
16489
+ if (typeof renderable === "function") {
16490
+ return renderable({
16491
+ open,
16492
+ selectedItem,
16493
+ selectedValue,
16494
+ placeholder
16495
+ });
16496
+ }
16497
+ if (renderable != null) return renderable;
16498
+ const iconNode = (_c = (_b2 = selectedItem == null ? void 0 : selectedItem.icon) != null ? _b2 : (_a2 = items.find((it) => it.icon)) == null ? void 0 : _a2.icon) != null ? _c : null;
16499
+ if (iconNode) {
16500
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center", children: iconNode });
16501
+ }
16502
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: (_d = selectedItem == null ? void 0 : selectedItem.labelNode) != null ? _d : placeholder != null ? placeholder : "Select..." });
16503
+ })();
16504
+ return /* @__PURE__ */ jsxRuntime.jsx(
16505
+ "button",
16506
+ {
16507
+ ref: _ref,
16508
+ type: "button",
16509
+ disabled: disabled || readOnly,
16510
+ className: cn(
16511
+ "inline-flex items-center justify-center",
16512
+ "focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50",
16513
+ triggerClassName
16514
+ ),
16515
+ "aria-label": (selectedItem == null ? void 0 : selectedItem.labelText) ? `Selected: ${selectedItem.labelText}` : "Select",
16516
+ children: content
16517
+ }
16518
+ );
16519
+ }, [
16520
+ isButtonMode,
16521
+ button,
16522
+ children,
16523
+ open,
16524
+ selectedItem,
16525
+ value,
16526
+ placeholder,
16527
+ items,
16528
+ disabled,
16529
+ readOnly,
16530
+ triggerClassName,
16531
+ _ref
16532
+ ]);
16533
+ const TriggerBody = isButtonMode ? /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { asChild: true, children: ButtonModeTrigger }) : /* @__PURE__ */ jsxRuntime.jsx(
16360
16534
  SelectTrigger,
16361
16535
  {
16362
16536
  onPointerDown: (e) => {
@@ -16449,7 +16623,7 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16449
16623
  /* @__PURE__ */ jsxRuntime.jsxs(
16450
16624
  SelectContent,
16451
16625
  {
16452
- className: cn("min-w-[8rem]", contentClassName),
16626
+ className: cn("min-w-32", contentClassName),
16453
16627
  children: [
16454
16628
  searchable && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-1", children: /* @__PURE__ */ jsxRuntime.jsx(
16455
16629
  Input,
@@ -16475,6 +16649,7 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16475
16649
  onScroll: handleListScroll,
16476
16650
  children: [
16477
16651
  renderedItems.map((item, index) => {
16652
+ var _a2;
16478
16653
  const optionNode = /* @__PURE__ */ jsxRuntime.jsx(
16479
16654
  SelectItem,
16480
16655
  {
@@ -16490,8 +16665,9 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16490
16665
  },
16491
16666
  item.key
16492
16667
  );
16493
- if (!renderOption) return optionNode;
16494
- return renderOption({
16668
+ const renderer = (_a2 = item.render) != null ? _a2 : renderOption;
16669
+ if (!renderer) return optionNode;
16670
+ return renderer({
16495
16671
  item,
16496
16672
  selected: selectedItem != null && String(selectedItem.value) === String(item.value),
16497
16673
  index,
@@ -16516,7 +16692,7 @@ var ShadcnSelectVariant = React10__namespace.forwardRef(function ShadcnSelectVar
16516
16692
  ]
16517
16693
  }
16518
16694
  );
16519
- if (!hasControls) {
16695
+ if (isButtonMode || !hasControls) {
16520
16696
  return /* @__PURE__ */ jsxRuntime.jsx(
16521
16697
  "div",
16522
16698
  {
@@ -17287,6 +17463,7 @@ var ShadcnMultiSelectVariant = React10__namespace.forwardRef(function ShadcnMult
17287
17463
  }
17288
17464
  ),
17289
17465
  filteredItems.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-xs text-muted-foreground", children: emptySearchText != null ? emptySearchText : "No results found" }) : filteredItems.map((item, index) => {
17466
+ var _a2;
17290
17467
  const selected = selectedValues.has(item.value);
17291
17468
  const row = /* @__PURE__ */ jsxRuntime.jsxs(
17292
17469
  "button",
@@ -17319,8 +17496,9 @@ var ShadcnMultiSelectVariant = React10__namespace.forwardRef(function ShadcnMult
17319
17496
  },
17320
17497
  item.key
17321
17498
  );
17322
- if (!renderOption) return row;
17323
- return renderOption({
17499
+ const renderer = (_a2 = item.render) != null ? _a2 : renderOption;
17500
+ if (!renderer) return row;
17501
+ return renderer({
17324
17502
  item,
17325
17503
  selected,
17326
17504
  index,
@@ -18539,52 +18717,6 @@ var customVariant = {
18539
18717
  Variant: ShadcnCustomVariant
18540
18718
  };
18541
18719
  var custom_default = customVariant;
18542
- function capitalizeFirst4(label) {
18543
- if (!label) return label;
18544
- return label.charAt(0).toUpperCase() + label.slice(1);
18545
- }
18546
- function normalizeTree(opts, config, level = 0, parentValue, path = []) {
18547
- if (!opts || !opts.length) return [];
18548
- return opts.map((raw, index) => {
18549
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
18550
- const asObj = typeof raw === "string" || typeof raw === "number" ? { label: String(raw), value: raw } : raw;
18551
- const value = typeof config.optionValue === "function" ? config.optionValue(raw) : typeof config.optionValue === "string" ? asObj[config.optionValue] : (_c = (_b = (_a = asObj.value) != null ? _a : asObj.id) != null ? _b : asObj.key) != null ? _c : String(index);
18552
- let labelNode = typeof config.optionLabel === "function" ? config.optionLabel(raw) : typeof config.optionLabel === "string" ? (_e = (_d = asObj[config.optionLabel]) != null ? _d : asObj.label) != null ? _e : String(value) : (_f = asObj.label) != null ? _f : String(value);
18553
- if (config.autoCap && typeof labelNode === "string") {
18554
- labelNode = capitalizeFirst4(labelNode);
18555
- }
18556
- const labelText = typeof labelNode === "string" ? labelNode : typeof labelNode === "number" ? String(labelNode) : (_g = asObj.labelText) != null ? _g : String(value);
18557
- const description = typeof config.optionDescription === "function" ? config.optionDescription(raw) : typeof config.optionDescription === "string" ? asObj[config.optionDescription] : asObj.description;
18558
- const disabled = typeof config.optionDisabled === "function" ? config.optionDisabled(raw) : typeof config.optionDisabled === "string" ? !!asObj[config.optionDisabled] : !!asObj.disabled;
18559
- const icon = typeof config.optionIcon === "function" ? config.optionIcon(raw) : typeof config.optionIcon === "string" ? asObj[config.optionIcon] : asObj.icon;
18560
- const key = typeof config.optionKey === "function" ? config.optionKey(raw, index) : typeof config.optionKey === "string" ? (_i = (_h = asObj[config.optionKey]) != null ? _h : value) != null ? _i : index : (_k = (_j = asObj.key) != null ? _j : value) != null ? _k : index;
18561
- const childrenRaw = asObj.children;
18562
- const nextPath = [...path, value];
18563
- const children = normalizeTree(
18564
- childrenRaw != null ? childrenRaw : [],
18565
- config,
18566
- level + 1,
18567
- value,
18568
- nextPath
18569
- );
18570
- return {
18571
- key: String(key),
18572
- value,
18573
- labelNode,
18574
- labelText,
18575
- description,
18576
- disabled,
18577
- icon,
18578
- level,
18579
- parentValue,
18580
- path,
18581
- // ancestors only
18582
- hasChildren: !!children.length,
18583
- children,
18584
- raw
18585
- };
18586
- });
18587
- }
18588
18720
  function flattenTree(nodes) {
18589
18721
  const result = [];
18590
18722
  function recurse(list) {
@@ -18989,6 +19121,7 @@ var ShadcnTreeSelectVariant = React10__namespace.forwardRef(function ShadcnTreeS
18989
19121
  emptyLabel && tree.length === 0 && !query && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 text-sm text-center text-muted-foreground", children: emptyLabel }),
18990
19122
  tree.length > 0 && displayedNodes.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-3 text-sm text-center text-muted-foreground", children: emptySearchText != null ? emptySearchText : "No results found" }),
18991
19123
  displayedNodes.map((item, index) => {
19124
+ var _a;
18992
19125
  const selected = selectedValues.includes(item.value);
18993
19126
  const isExpanded = expanded.has(item.value);
18994
19127
  const parentInLeafOnly = leafOnly && item.hasChildren;
@@ -19052,10 +19185,11 @@ var ShadcnTreeSelectVariant = React10__namespace.forwardRef(function ShadcnTreeS
19052
19185
  ]
19053
19186
  }
19054
19187
  );
19055
- if (!renderOption) {
19188
+ const renderer = (_a = item.render) != null ? _a : renderOption;
19189
+ if (!renderer) {
19056
19190
  return /* @__PURE__ */ jsxRuntime.jsx(React10__namespace.Fragment, { children: optionNode }, item.key);
19057
19191
  }
19058
- const rendered = renderOption({
19192
+ const rendered = renderer({
19059
19193
  item,
19060
19194
  selected,
19061
19195
  index,
@@ -20413,7 +20547,7 @@ function normalizeValue(val, multiple) {
20413
20547
  if (Array.isArray(val)) return val[0] || "";
20414
20548
  return val || "";
20415
20549
  }
20416
- function capitalizeFirst5(label) {
20550
+ function capitalizeFirst4(label) {
20417
20551
  if (!label) return label;
20418
20552
  return label.charAt(0).toUpperCase() + label.slice(1);
20419
20553
  }
@@ -20439,7 +20573,7 @@ function normalizeOption(input, {
20439
20573
  label2 = String(rawValue != null ? rawValue : value2);
20440
20574
  }
20441
20575
  if (autoCap && typeof label2 === "string") {
20442
- label2 = capitalizeFirst5(label2);
20576
+ label2 = capitalizeFirst4(label2);
20443
20577
  }
20444
20578
  const icon = optionIcon != null ? anyInput[optionIcon] : (_b = anyInput.icon) != null ? _b : void 0;
20445
20579
  const disabled = optionDisabled != null ? !!anyInput[optionDisabled] : !!anyInput.disabled;
@@ -20461,7 +20595,7 @@ function normalizeOption(input, {
20461
20595
  const value2 = String(input);
20462
20596
  let label2 = value2;
20463
20597
  if (autoCap && typeof label2 === "string") {
20464
- label2 = capitalizeFirst5(label2);
20598
+ label2 = capitalizeFirst4(label2);
20465
20599
  }
20466
20600
  return {
20467
20601
  ui: {
@@ -20475,7 +20609,7 @@ function normalizeOption(input, {
20475
20609
  const value = String(baseValue);
20476
20610
  let label = anyInput.label != null ? anyInput.label : String(value);
20477
20611
  if (autoCap && typeof label === "string") {
20478
- label = capitalizeFirst5(label);
20612
+ label = capitalizeFirst4(label);
20479
20613
  }
20480
20614
  return {
20481
20615
  ui: {