@cimplify/sdk 0.13.1 → 0.14.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/react.d.mts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +146 -109
- package/dist/react.mjs +146 -109
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/registry/add-on-selector.json +1 -1
- package/registry/bundle-selector.json +1 -1
- package/registry/composite-selector.json +1 -1
- package/registry/product-card.json +1 -1
- package/registry/variant-selector.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -7972,7 +7972,7 @@ function VariantSelector({
|
|
|
7972
7972
|
if (!variants || variants.length <= 1) {
|
|
7973
7973
|
return null;
|
|
7974
7974
|
}
|
|
7975
|
-
|
|
7975
|
+
basePrice != null ? parsePrice(basePrice) : 0;
|
|
7976
7976
|
if (variantAxes && variantAxes.length > 0) {
|
|
7977
7977
|
return /* @__PURE__ */ jsx("div", { "data-cimplify-variant-selector": true, className: cn("space-y-5", className, classNames?.root), children: variantAxes.map((axis) => {
|
|
7978
7978
|
const labelId = `${idPrefix}-axis-${axis.id}`;
|
|
@@ -8023,14 +8023,16 @@ function VariantSelector({
|
|
|
8023
8023
|
}) });
|
|
8024
8024
|
}
|
|
8025
8025
|
const listLabelId = `${idPrefix}-variant-list`;
|
|
8026
|
-
return /* @__PURE__ */ jsxs("div", { "data-cimplify-variant-selector": true, className: cn(
|
|
8027
|
-
/* @__PURE__ */
|
|
8028
|
-
"
|
|
8026
|
+
return /* @__PURE__ */ jsxs("div", { "data-cimplify-variant-selector": true, className: cn(className, classNames?.root), children: [
|
|
8027
|
+
/* @__PURE__ */ jsxs(
|
|
8028
|
+
"div",
|
|
8029
8029
|
{
|
|
8030
|
-
|
|
8031
|
-
"
|
|
8032
|
-
|
|
8033
|
-
|
|
8030
|
+
"data-cimplify-variant-list-header": true,
|
|
8031
|
+
className: cn("flex items-center justify-between py-3", classNames?.listLabel),
|
|
8032
|
+
children: [
|
|
8033
|
+
/* @__PURE__ */ jsx("label", { id: listLabelId, className: "text-base font-bold", children: "Options" }),
|
|
8034
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-destructive bg-destructive/10 px-2.5 py-1 rounded", children: "Required" })
|
|
8035
|
+
]
|
|
8034
8036
|
}
|
|
8035
8037
|
),
|
|
8036
8038
|
/* @__PURE__ */ jsx(
|
|
@@ -8043,11 +8045,10 @@ function VariantSelector({
|
|
|
8043
8045
|
onVariantChange(variant?.id, variant);
|
|
8044
8046
|
},
|
|
8045
8047
|
"data-cimplify-variant-list": true,
|
|
8046
|
-
className: cn("
|
|
8048
|
+
className: cn("divide-y divide-border", classNames?.list),
|
|
8047
8049
|
children: variants.map((variant) => {
|
|
8048
8050
|
const isSelected = selectedVariantId === variant.id;
|
|
8049
8051
|
const adjustment = parsePrice(variant.price_adjustment);
|
|
8050
|
-
const effectivePrice = basePriceNum + adjustment;
|
|
8051
8052
|
return /* @__PURE__ */ jsxs(
|
|
8052
8053
|
Radio.Root,
|
|
8053
8054
|
{
|
|
@@ -8055,35 +8056,32 @@ function VariantSelector({
|
|
|
8055
8056
|
"data-cimplify-variant-option": true,
|
|
8056
8057
|
"data-selected": isSelected || void 0,
|
|
8057
8058
|
className: cn(
|
|
8058
|
-
"w-full flex items-center
|
|
8059
|
-
isSelected && "bg-primary/5 border-primary",
|
|
8059
|
+
"w-full flex items-center gap-3 py-4 transition-colors cursor-pointer",
|
|
8060
8060
|
isSelected ? classNames?.optionSelected : classNames?.option
|
|
8061
8061
|
),
|
|
8062
8062
|
children: [
|
|
8063
|
+
/* @__PURE__ */ jsx(
|
|
8064
|
+
"span",
|
|
8065
|
+
{
|
|
8066
|
+
"data-cimplify-variant-radio": true,
|
|
8067
|
+
className: cn(
|
|
8068
|
+
"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors",
|
|
8069
|
+
isSelected ? "border-primary" : "border-muted-foreground/30"
|
|
8070
|
+
),
|
|
8071
|
+
children: isSelected && /* @__PURE__ */ jsx("span", { className: "w-2.5 h-2.5 rounded-full bg-primary" })
|
|
8072
|
+
}
|
|
8073
|
+
),
|
|
8063
8074
|
/* @__PURE__ */ jsx(
|
|
8064
8075
|
"span",
|
|
8065
8076
|
{
|
|
8066
8077
|
"data-cimplify-variant-name": true,
|
|
8067
|
-
className: cn("
|
|
8078
|
+
className: cn("flex-1 min-w-0 text-sm", classNames?.name),
|
|
8068
8079
|
children: getVariantDisplayName(variant, productName)
|
|
8069
8080
|
}
|
|
8070
8081
|
),
|
|
8071
|
-
/* @__PURE__ */ jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm
|
|
8072
|
-
adjustment
|
|
8073
|
-
|
|
8074
|
-
{
|
|
8075
|
-
"data-cimplify-variant-adjustment": true,
|
|
8076
|
-
className: cn(
|
|
8077
|
-
adjustment > 0 ? "text-muted-foreground" : "text-green-600",
|
|
8078
|
-
classNames?.adjustment
|
|
8079
|
-
),
|
|
8080
|
-
children: [
|
|
8081
|
-
adjustment > 0 ? "+" : "",
|
|
8082
|
-
/* @__PURE__ */ jsx(Price, { amount: variant.price_adjustment })
|
|
8083
|
-
]
|
|
8084
|
-
}
|
|
8085
|
-
),
|
|
8086
|
-
/* @__PURE__ */ jsx(Price, { amount: effectivePrice, className: "text-muted-foreground" })
|
|
8082
|
+
/* @__PURE__ */ jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
|
|
8083
|
+
adjustment > 0 ? "+" : adjustment < 0 ? "" : "+",
|
|
8084
|
+
/* @__PURE__ */ jsx(Price, { amount: variant.price_adjustment })
|
|
8087
8085
|
] })
|
|
8088
8086
|
]
|
|
8089
8087
|
},
|
|
@@ -8142,54 +8140,46 @@ function AddOnSelector({
|
|
|
8142
8140
|
(id) => addOn.options.some((o) => o.id === id)
|
|
8143
8141
|
).length;
|
|
8144
8142
|
const minMet = !addOn.min_selections || currentSelections >= addOn.min_selections;
|
|
8143
|
+
const isSingleSelect = addOn.is_mutually_exclusive || !addOn.is_multiple_allowed;
|
|
8145
8144
|
return /* @__PURE__ */ jsxs(
|
|
8146
8145
|
"div",
|
|
8147
8146
|
{
|
|
8148
8147
|
"data-cimplify-addon-group": true,
|
|
8149
|
-
className: cn(
|
|
8148
|
+
className: cn(classNames?.group),
|
|
8150
8149
|
children: [
|
|
8151
8150
|
/* @__PURE__ */ jsxs(
|
|
8152
8151
|
"div",
|
|
8153
8152
|
{
|
|
8154
8153
|
"data-cimplify-addon-header": true,
|
|
8155
|
-
className: cn("flex items-center justify-between
|
|
8154
|
+
className: cn("flex items-center justify-between py-3", classNames?.header),
|
|
8156
8155
|
children: [
|
|
8157
8156
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
8158
|
-
/* @__PURE__ */
|
|
8157
|
+
/* @__PURE__ */ jsx(
|
|
8159
8158
|
"span",
|
|
8160
8159
|
{
|
|
8161
8160
|
"data-cimplify-addon-name": true,
|
|
8162
|
-
className: cn("text-
|
|
8163
|
-
children:
|
|
8164
|
-
addOn.name,
|
|
8165
|
-
addOn.is_required && /* @__PURE__ */ jsxs(
|
|
8166
|
-
"span",
|
|
8167
|
-
{
|
|
8168
|
-
"data-cimplify-addon-required": true,
|
|
8169
|
-
className: cn("text-destructive ml-1", classNames?.required),
|
|
8170
|
-
children: [
|
|
8171
|
-
" ",
|
|
8172
|
-
"*"
|
|
8173
|
-
]
|
|
8174
|
-
}
|
|
8175
|
-
)
|
|
8176
|
-
]
|
|
8161
|
+
className: cn("text-base font-bold", classNames?.name),
|
|
8162
|
+
children: addOn.name
|
|
8177
8163
|
}
|
|
8178
8164
|
),
|
|
8179
8165
|
(addOn.min_selections || addOn.max_selections) && /* @__PURE__ */ jsx(
|
|
8180
8166
|
"span",
|
|
8181
8167
|
{
|
|
8182
8168
|
"data-cimplify-addon-constraint": true,
|
|
8183
|
-
className: cn("text-xs text-muted-foreground
|
|
8169
|
+
className: cn("block text-xs text-muted-foreground mt-0.5", classNames?.constraint),
|
|
8184
8170
|
children: addOn.min_selections && addOn.max_selections ? `Choose ${addOn.min_selections}\u2013${addOn.max_selections}` : addOn.min_selections ? `Choose at least ${addOn.min_selections}` : `Choose up to ${addOn.max_selections}`
|
|
8185
8171
|
}
|
|
8186
8172
|
)
|
|
8187
8173
|
] }),
|
|
8188
|
-
!minMet && /* @__PURE__ */ jsx(
|
|
8174
|
+
(addOn.is_required || !minMet) && /* @__PURE__ */ jsx(
|
|
8189
8175
|
"span",
|
|
8190
8176
|
{
|
|
8191
|
-
"data-cimplify-addon-
|
|
8192
|
-
className: cn(
|
|
8177
|
+
"data-cimplify-addon-required": true,
|
|
8178
|
+
className: cn(
|
|
8179
|
+
"text-xs font-semibold px-2.5 py-1 rounded",
|
|
8180
|
+
!minMet ? "text-destructive bg-destructive/10" : "text-destructive bg-destructive/10",
|
|
8181
|
+
classNames?.required
|
|
8182
|
+
),
|
|
8193
8183
|
children: "Required"
|
|
8194
8184
|
}
|
|
8195
8185
|
)
|
|
@@ -8200,7 +8190,7 @@ function AddOnSelector({
|
|
|
8200
8190
|
"div",
|
|
8201
8191
|
{
|
|
8202
8192
|
"data-cimplify-addon-options": true,
|
|
8203
|
-
className: cn("
|
|
8193
|
+
className: cn("divide-y divide-border", classNames?.options),
|
|
8204
8194
|
children: addOn.options.map((option) => {
|
|
8205
8195
|
const isSelected = isOptionSelected(option.id);
|
|
8206
8196
|
return /* @__PURE__ */ jsxs(
|
|
@@ -8212,8 +8202,7 @@ function AddOnSelector({
|
|
|
8212
8202
|
"data-cimplify-addon-option": true,
|
|
8213
8203
|
"data-selected": isSelected || void 0,
|
|
8214
8204
|
className: cn(
|
|
8215
|
-
"w-full flex items-center gap-3
|
|
8216
|
-
isSelected && "bg-primary/5 border-primary",
|
|
8205
|
+
"w-full flex items-center gap-3 py-4 transition-colors text-left cursor-pointer",
|
|
8217
8206
|
isSelected ? classNames?.optionSelected : classNames?.option
|
|
8218
8207
|
),
|
|
8219
8208
|
children: [
|
|
@@ -8224,25 +8213,42 @@ function AddOnSelector({
|
|
|
8224
8213
|
keepMounted: false
|
|
8225
8214
|
}
|
|
8226
8215
|
),
|
|
8216
|
+
isSingleSelect ? /* @__PURE__ */ jsx(
|
|
8217
|
+
"span",
|
|
8218
|
+
{
|
|
8219
|
+
"data-cimplify-addon-radio": true,
|
|
8220
|
+
className: cn(
|
|
8221
|
+
"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors",
|
|
8222
|
+
isSelected ? "border-primary" : "border-muted-foreground/30"
|
|
8223
|
+
),
|
|
8224
|
+
children: isSelected && /* @__PURE__ */ jsx("span", { className: "w-2.5 h-2.5 rounded-full bg-primary" })
|
|
8225
|
+
}
|
|
8226
|
+
) : /* @__PURE__ */ jsx(
|
|
8227
|
+
"span",
|
|
8228
|
+
{
|
|
8229
|
+
"data-cimplify-addon-checkbox": true,
|
|
8230
|
+
className: cn(
|
|
8231
|
+
"w-5 h-5 rounded-sm border-2 flex items-center justify-center shrink-0 transition-colors",
|
|
8232
|
+
isSelected ? "border-primary bg-primary" : "border-muted-foreground/30"
|
|
8233
|
+
),
|
|
8234
|
+
children: isSelected && /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", className: "w-3 h-3 text-primary-foreground", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M2 6l3 3 5-5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
8235
|
+
}
|
|
8236
|
+
),
|
|
8227
8237
|
/* @__PURE__ */ jsx(
|
|
8228
8238
|
"span",
|
|
8229
8239
|
{
|
|
8230
8240
|
"data-cimplify-addon-option-name": true,
|
|
8231
8241
|
className: cn(
|
|
8232
|
-
"flex-1 min-w-0 text-sm
|
|
8233
|
-
isSelected && "text-primary",
|
|
8242
|
+
"flex-1 min-w-0 text-sm",
|
|
8234
8243
|
classNames?.optionName
|
|
8235
8244
|
),
|
|
8236
8245
|
children: option.name
|
|
8237
8246
|
}
|
|
8238
8247
|
),
|
|
8239
|
-
option.default_price != null &&
|
|
8240
|
-
|
|
8241
|
-
{
|
|
8242
|
-
|
|
8243
|
-
prefix: "+"
|
|
8244
|
-
}
|
|
8245
|
-
)
|
|
8248
|
+
option.default_price != null && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground", children: [
|
|
8249
|
+
"+",
|
|
8250
|
+
/* @__PURE__ */ jsx(Price, { amount: option.default_price })
|
|
8251
|
+
] })
|
|
8246
8252
|
]
|
|
8247
8253
|
},
|
|
8248
8254
|
option.id
|
|
@@ -8328,14 +8334,14 @@ function BundleSelector({
|
|
|
8328
8334
|
}
|
|
8329
8335
|
return /* @__PURE__ */ jsxs("div", { "data-cimplify-bundle-selector": true, className: cn("space-y-4", className, classNames?.root), children: [
|
|
8330
8336
|
/* @__PURE__ */ jsx(
|
|
8331
|
-
"
|
|
8337
|
+
"div",
|
|
8332
8338
|
{
|
|
8333
8339
|
"data-cimplify-bundle-heading": true,
|
|
8334
|
-
className: cn("
|
|
8335
|
-
children: "Included in this bundle"
|
|
8340
|
+
className: cn("flex items-center justify-between py-3", classNames?.heading),
|
|
8341
|
+
children: /* @__PURE__ */ jsx("span", { className: "text-base font-bold", children: "Included in this bundle" })
|
|
8336
8342
|
}
|
|
8337
8343
|
),
|
|
8338
|
-
/* @__PURE__ */ jsx("div", { "data-cimplify-bundle-components": true, className: cn("
|
|
8344
|
+
/* @__PURE__ */ jsx("div", { "data-cimplify-bundle-components": true, className: cn("divide-y divide-border", classNames?.components), children: components.map((comp) => /* @__PURE__ */ jsx(
|
|
8339
8345
|
BundleComponentCard,
|
|
8340
8346
|
{
|
|
8341
8347
|
component: comp,
|
|
@@ -8398,20 +8404,20 @@ function BundleComponentCard({
|
|
|
8398
8404
|
"div",
|
|
8399
8405
|
{
|
|
8400
8406
|
"data-cimplify-bundle-component": true,
|
|
8401
|
-
className: cn("
|
|
8407
|
+
className: cn("py-4", classNames?.component),
|
|
8402
8408
|
children: [
|
|
8403
8409
|
/* @__PURE__ */ jsxs(
|
|
8404
8410
|
"div",
|
|
8405
8411
|
{
|
|
8406
8412
|
"data-cimplify-bundle-component-header": true,
|
|
8407
|
-
className: cn("flex items-
|
|
8413
|
+
className: cn("flex items-center justify-between gap-3", classNames?.componentHeader),
|
|
8408
8414
|
children: [
|
|
8409
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
8415
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8410
8416
|
component.quantity > 1 && /* @__PURE__ */ jsxs(
|
|
8411
8417
|
"span",
|
|
8412
8418
|
{
|
|
8413
8419
|
"data-cimplify-bundle-component-qty": true,
|
|
8414
|
-
className: cn("text-xs font-medium text-primary bg-primary/10 px-1.5 py-0.5", classNames?.componentQty),
|
|
8420
|
+
className: cn("text-xs font-medium text-primary bg-primary/10 px-1.5 py-0.5 rounded", classNames?.componentQty),
|
|
8415
8421
|
children: [
|
|
8416
8422
|
"\xD7",
|
|
8417
8423
|
component.quantity
|
|
@@ -8423,12 +8429,12 @@ function BundleComponentCard({
|
|
|
8423
8429
|
{
|
|
8424
8430
|
id: labelId,
|
|
8425
8431
|
"data-cimplify-bundle-component-name": true,
|
|
8426
|
-
className: cn("
|
|
8432
|
+
className: cn("text-sm", classNames?.componentName),
|
|
8427
8433
|
children: component.product_name
|
|
8428
8434
|
}
|
|
8429
8435
|
)
|
|
8430
8436
|
] }),
|
|
8431
|
-
/* @__PURE__ */ jsx(Price, { amount: displayPrice })
|
|
8437
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: /* @__PURE__ */ jsx(Price, { amount: displayPrice }) })
|
|
8432
8438
|
]
|
|
8433
8439
|
}
|
|
8434
8440
|
),
|
|
@@ -8441,7 +8447,7 @@ function BundleComponentCard({
|
|
|
8441
8447
|
onVariantChange(value);
|
|
8442
8448
|
},
|
|
8443
8449
|
"data-cimplify-bundle-variant-picker": true,
|
|
8444
|
-
className: cn("mt-3
|
|
8450
|
+
className: cn("mt-3 divide-y divide-border", classNames?.variantPicker),
|
|
8445
8451
|
children: component.available_variants.map((variant) => {
|
|
8446
8452
|
const isSelected = selectedVariantId === variant.id;
|
|
8447
8453
|
const adjustment = parsePrice(variant.price_adjustment);
|
|
@@ -8452,17 +8458,26 @@ function BundleComponentCard({
|
|
|
8452
8458
|
"data-cimplify-bundle-variant-option": true,
|
|
8453
8459
|
"data-selected": isSelected || void 0,
|
|
8454
8460
|
className: cn(
|
|
8455
|
-
"
|
|
8456
|
-
isSelected && "bg-primary text-primary-foreground border-primary",
|
|
8461
|
+
"w-full flex items-center gap-3 py-3 transition-colors cursor-pointer",
|
|
8457
8462
|
isSelected ? classNames?.variantOptionSelected : classNames?.variantOption
|
|
8458
8463
|
),
|
|
8459
8464
|
children: [
|
|
8460
|
-
|
|
8465
|
+
/* @__PURE__ */ jsx(
|
|
8466
|
+
"span",
|
|
8467
|
+
{
|
|
8468
|
+
className: cn(
|
|
8469
|
+
"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors",
|
|
8470
|
+
isSelected ? "border-primary" : "border-muted-foreground/30"
|
|
8471
|
+
),
|
|
8472
|
+
children: isSelected && /* @__PURE__ */ jsx("span", { className: "w-2.5 h-2.5 rounded-full bg-primary" })
|
|
8473
|
+
}
|
|
8474
|
+
),
|
|
8475
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm", children: variant.display_name }),
|
|
8461
8476
|
adjustment !== 0 && /* @__PURE__ */ jsxs(
|
|
8462
8477
|
"span",
|
|
8463
8478
|
{
|
|
8464
8479
|
"data-cimplify-bundle-variant-adjustment": true,
|
|
8465
|
-
className: cn("
|
|
8480
|
+
className: cn("text-sm text-muted-foreground", classNames?.variantAdjustment),
|
|
8466
8481
|
children: [
|
|
8467
8482
|
adjustment > 0 ? "+" : "",
|
|
8468
8483
|
/* @__PURE__ */ jsx(Price, { amount: variant.price_adjustment })
|
|
@@ -8619,41 +8634,28 @@ function CompositeSelector({
|
|
|
8619
8634
|
"div",
|
|
8620
8635
|
{
|
|
8621
8636
|
"data-cimplify-composite-group": true,
|
|
8622
|
-
className: cn(
|
|
8637
|
+
className: cn(classNames?.group),
|
|
8623
8638
|
children: [
|
|
8624
8639
|
/* @__PURE__ */ jsxs(
|
|
8625
8640
|
"div",
|
|
8626
8641
|
{
|
|
8627
8642
|
"data-cimplify-composite-group-header": true,
|
|
8628
|
-
className: cn("flex items-center justify-between
|
|
8643
|
+
className: cn("flex items-center justify-between py-3", classNames?.groupHeader),
|
|
8629
8644
|
children: [
|
|
8630
8645
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
8631
|
-
/* @__PURE__ */
|
|
8646
|
+
/* @__PURE__ */ jsx(
|
|
8632
8647
|
"span",
|
|
8633
8648
|
{
|
|
8634
8649
|
"data-cimplify-composite-group-name": true,
|
|
8635
|
-
className: cn("text-
|
|
8636
|
-
children:
|
|
8637
|
-
group.name,
|
|
8638
|
-
group.min_selections > 0 && /* @__PURE__ */ jsxs(
|
|
8639
|
-
"span",
|
|
8640
|
-
{
|
|
8641
|
-
"data-cimplify-composite-required": true,
|
|
8642
|
-
className: cn("text-destructive ml-1", classNames?.required),
|
|
8643
|
-
children: [
|
|
8644
|
-
" ",
|
|
8645
|
-
"*"
|
|
8646
|
-
]
|
|
8647
|
-
}
|
|
8648
|
-
)
|
|
8649
|
-
]
|
|
8650
|
+
className: cn("text-base font-bold", classNames?.groupName),
|
|
8651
|
+
children: group.name
|
|
8650
8652
|
}
|
|
8651
8653
|
),
|
|
8652
8654
|
group.description && /* @__PURE__ */ jsx(
|
|
8653
8655
|
"span",
|
|
8654
8656
|
{
|
|
8655
8657
|
"data-cimplify-composite-group-description": true,
|
|
8656
|
-
className: cn("text-xs text-muted-foreground
|
|
8658
|
+
className: cn("block text-xs text-muted-foreground mt-0.5", classNames?.groupDescription),
|
|
8657
8659
|
children: group.description
|
|
8658
8660
|
}
|
|
8659
8661
|
),
|
|
@@ -8661,16 +8663,20 @@ function CompositeSelector({
|
|
|
8661
8663
|
"span",
|
|
8662
8664
|
{
|
|
8663
8665
|
"data-cimplify-composite-group-constraint": true,
|
|
8664
|
-
className: cn("text-xs text-muted-foreground
|
|
8666
|
+
className: cn("block text-xs text-muted-foreground mt-0.5", classNames?.groupConstraint),
|
|
8665
8667
|
children: group.min_selections > 0 && group.max_selections ? `Choose ${group.min_selections}\u2013${group.max_selections}` : group.min_selections > 0 ? `Choose at least ${group.min_selections}` : group.max_selections ? `Choose up to ${group.max_selections}` : "Choose as many as you like"
|
|
8666
8668
|
}
|
|
8667
8669
|
)
|
|
8668
8670
|
] }),
|
|
8669
|
-
|
|
8671
|
+
group.min_selections > 0 && /* @__PURE__ */ jsx(
|
|
8670
8672
|
"span",
|
|
8671
8673
|
{
|
|
8672
|
-
"data-cimplify-composite-
|
|
8673
|
-
className: cn(
|
|
8674
|
+
"data-cimplify-composite-required": true,
|
|
8675
|
+
className: cn(
|
|
8676
|
+
"text-xs font-semibold px-2.5 py-1 rounded shrink-0",
|
|
8677
|
+
!minMet ? "text-destructive bg-destructive/10" : "text-destructive bg-destructive/10",
|
|
8678
|
+
classNames?.required
|
|
8679
|
+
),
|
|
8674
8680
|
children: "Required"
|
|
8675
8681
|
}
|
|
8676
8682
|
)
|
|
@@ -8683,7 +8689,7 @@ function CompositeSelector({
|
|
|
8683
8689
|
"data-cimplify-composite-components": true,
|
|
8684
8690
|
role: isSingleSelect ? "radiogroup" : "group",
|
|
8685
8691
|
"aria-label": group.name,
|
|
8686
|
-
className: cn("
|
|
8692
|
+
className: cn("divide-y divide-border", classNames?.components),
|
|
8687
8693
|
children: group.components.filter((c) => c.is_available && !c.is_archived).sort((a, b) => a.display_order - b.display_order).map((component) => {
|
|
8688
8694
|
const qty = groupSels[component.id] || 0;
|
|
8689
8695
|
const isSelected = qty > 0;
|
|
@@ -8697,8 +8703,7 @@ function CompositeSelector({
|
|
|
8697
8703
|
"data-cimplify-composite-component": true,
|
|
8698
8704
|
"data-selected": isSelected || void 0,
|
|
8699
8705
|
className: cn(
|
|
8700
|
-
"w-full flex items-center gap-3
|
|
8701
|
-
isSelected && "bg-primary/5 border-primary",
|
|
8706
|
+
"w-full flex items-center gap-3 py-4 transition-colors text-left cursor-pointer",
|
|
8702
8707
|
isSelected ? classNames?.componentSelected : classNames?.component
|
|
8703
8708
|
),
|
|
8704
8709
|
children: [
|
|
@@ -8709,6 +8714,27 @@ function CompositeSelector({
|
|
|
8709
8714
|
keepMounted: false
|
|
8710
8715
|
}
|
|
8711
8716
|
),
|
|
8717
|
+
isSingleSelect ? /* @__PURE__ */ jsx(
|
|
8718
|
+
"span",
|
|
8719
|
+
{
|
|
8720
|
+
"data-cimplify-composite-radio": true,
|
|
8721
|
+
className: cn(
|
|
8722
|
+
"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors",
|
|
8723
|
+
isSelected ? "border-primary" : "border-muted-foreground/30"
|
|
8724
|
+
),
|
|
8725
|
+
children: isSelected && /* @__PURE__ */ jsx("span", { className: "w-2.5 h-2.5 rounded-full bg-primary" })
|
|
8726
|
+
}
|
|
8727
|
+
) : /* @__PURE__ */ jsx(
|
|
8728
|
+
"span",
|
|
8729
|
+
{
|
|
8730
|
+
"data-cimplify-composite-checkbox": true,
|
|
8731
|
+
className: cn(
|
|
8732
|
+
"w-5 h-5 rounded-sm border-2 flex items-center justify-center shrink-0 transition-colors",
|
|
8733
|
+
isSelected ? "border-primary bg-primary" : "border-muted-foreground/30"
|
|
8734
|
+
),
|
|
8735
|
+
children: isSelected && /* @__PURE__ */ jsx("svg", { viewBox: "0 0 12 12", className: "w-3 h-3 text-primary-foreground", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M2 6l3 3 5-5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
8736
|
+
}
|
|
8737
|
+
),
|
|
8712
8738
|
/* @__PURE__ */ jsxs(
|
|
8713
8739
|
"div",
|
|
8714
8740
|
{
|
|
@@ -8719,7 +8745,7 @@ function CompositeSelector({
|
|
|
8719
8745
|
"span",
|
|
8720
8746
|
{
|
|
8721
8747
|
"data-cimplify-composite-component-name": true,
|
|
8722
|
-
className: cn("text-sm
|
|
8748
|
+
className: cn("text-sm", classNames?.componentName),
|
|
8723
8749
|
children: displayName
|
|
8724
8750
|
}
|
|
8725
8751
|
),
|
|
@@ -8743,7 +8769,7 @@ function CompositeSelector({
|
|
|
8743
8769
|
"span",
|
|
8744
8770
|
{
|
|
8745
8771
|
"data-cimplify-composite-component-description": true,
|
|
8746
|
-
className: cn("text-xs text-muted-foreground truncate", classNames?.componentDescription),
|
|
8772
|
+
className: cn("block text-xs text-muted-foreground truncate", classNames?.componentDescription),
|
|
8747
8773
|
children: component.display_description
|
|
8748
8774
|
}
|
|
8749
8775
|
),
|
|
@@ -8751,7 +8777,7 @@ function CompositeSelector({
|
|
|
8751
8777
|
"span",
|
|
8752
8778
|
{
|
|
8753
8779
|
"data-cimplify-composite-component-calories": true,
|
|
8754
|
-
className: cn("text-xs text-muted-foreground/60", classNames?.componentCalories),
|
|
8780
|
+
className: cn("block text-xs text-muted-foreground/60", classNames?.componentCalories),
|
|
8755
8781
|
children: [
|
|
8756
8782
|
component.calories,
|
|
8757
8783
|
" cal"
|
|
@@ -8808,7 +8834,10 @@ function CompositeSelector({
|
|
|
8808
8834
|
)
|
|
8809
8835
|
}
|
|
8810
8836
|
),
|
|
8811
|
-
component.price != null &&
|
|
8837
|
+
component.price != null && /* @__PURE__ */ jsxs("span", { className: "text-sm text-muted-foreground shrink-0", children: [
|
|
8838
|
+
"+",
|
|
8839
|
+
/* @__PURE__ */ jsx(Price, { amount: component.price })
|
|
8840
|
+
] })
|
|
8812
8841
|
]
|
|
8813
8842
|
},
|
|
8814
8843
|
component.id
|
|
@@ -9566,6 +9595,14 @@ function ProductCard({
|
|
|
9566
9595
|
const [isOpen, setIsOpen] = useState(false);
|
|
9567
9596
|
const [shouldFetch, setShouldFetch] = useState(false);
|
|
9568
9597
|
const dialogRef = useRef(null);
|
|
9598
|
+
useEffect(() => {
|
|
9599
|
+
if (!isOpen) return;
|
|
9600
|
+
const original = document.body.style.overflow;
|
|
9601
|
+
document.body.style.overflow = "hidden";
|
|
9602
|
+
return () => {
|
|
9603
|
+
document.body.style.overflow = original;
|
|
9604
|
+
};
|
|
9605
|
+
}, [isOpen]);
|
|
9569
9606
|
const { product: productDetails } = useProduct(
|
|
9570
9607
|
product.slug ?? product.id,
|
|
9571
9608
|
{ enabled: shouldFetch || isOpen }
|
|
@@ -9705,7 +9742,7 @@ function ProductCard({
|
|
|
9705
9742
|
"border-none rounded-2xl p-0 max-w-lg w-full max-h-[85vh] overflow-auto bg-background shadow-2xl backdrop:bg-black/50 backdrop:backdrop-blur-sm open:animate-in open:fade-in-0 open:slide-in-from-bottom-4",
|
|
9706
9743
|
classNames?.modal
|
|
9707
9744
|
),
|
|
9708
|
-
children: isOpen && (productDetails ? renderModal ? renderModal(productDetails) : /* @__PURE__ */ jsx(
|
|
9745
|
+
children: isOpen && (productDetails ? renderModal ? renderModal(productDetails, handleClose) : /* @__PURE__ */ jsx(
|
|
9709
9746
|
ProductSheet,
|
|
9710
9747
|
{
|
|
9711
9748
|
product: productDetails,
|
package/dist/styles.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.container{width:100%}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-\[4\/3\]{aspect-ratio:4/3}.max-h-\[85vh\]{max-height:85vh}.w-3\/5{width:60%}.w-full{width:100%}.flex-1{flex:1}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.\[appearance\:textfield\]{appearance:textfield}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.container{width:100%}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.aspect-\[4\/3\]{aspect-ratio:4/3}.max-h-\[85vh\]{max-height:85vh}.w-3\/5{width:60%}.w-full{width:100%}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-pointer{cursor:pointer}.\[appearance\:textfield\]{appearance:textfield}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:var(--color-border,oklch(90% 0 0))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.rounded{border-radius:var(--radius,.5rem)}.rounded-full{border-radius:3.40282e38px}.border{border-style:var(--tw-border-style);border-width:1px}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-none{--tw-border-style:none;border-style:none}.border-border{border-color:var(--color-border,oklch(90% 0 0))}.border-muted-foreground\/30{border-color:#6363634d}@supports (color:color-mix(in lab, red, red)){.border-muted-foreground\/30{border-color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 30%, transparent)}}.border-primary{border-color:var(--color-primary,oklch(50% .1 35))}.bg-background{background-color:var(--color-background,oklch(99% 0 0))}.bg-destructive\/10{background-color:#bb061e1a}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--color-destructive,oklch(50% .2 25)) 10%, transparent)}}.bg-muted{background-color:var(--color-muted,oklch(95% 0 0))}.bg-primary{background-color:var(--color-primary,oklch(50% .1 35))}.bg-primary\/10{background-color:#934c3a1a}@supports (color:color-mix(in lab, red, red)){.bg-primary\/10{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 10%, transparent)}}.bg-transparent{background-color:#0000}.text-center{text-align:center}.text-left{text-align:left}.font-\[inherit\]{font-family:inherit}.text-\[10px\]{font-size:10px}.text-\[inherit\]{color:inherit}.text-destructive{color:var(--color-destructive,oklch(50% .2 25))}.text-muted-foreground{color:var(--color-muted-foreground,oklch(50% 0 0))}.text-muted-foreground\/60{color:#63636399}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/60{color:color-mix(in oklab, var(--color-muted-foreground,oklch(50% 0 0)) 60%, transparent)}}.text-primary{color:var(--color-primary,oklch(50% .1 35))}.text-primary-foreground{color:var(--color-primary-foreground,oklch(99% 0 0))}.uppercase{text-transform:uppercase}.no-underline{text-decoration-line:none}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,ease);transition-duration:var(--tw-duration,0s)}.outline-none{--tw-outline-style:none;outline-style:none}.\[cimplify\:checkout\]{cimplify:checkout}@media (hover:hover){.hover\:border-primary\/50:hover{border-color:#934c3a80}@supports (color:color-mix(in lab, red, red)){.hover\:border-primary\/50:hover{border-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 50%, transparent)}}.hover\:bg-muted:hover{background-color:var(--color-muted,oklch(95% 0 0))}.hover\:bg-primary\/90:hover{background-color:#934c3ae6}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--color-primary,oklch(50% .1 35)) 90%, transparent)}}.hover\:text-primary:hover{color:var(--color-primary,oklch(50% .1 35))}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}.\[\&\:\:-webkit-inner-spin-button\]\:appearance-none::-webkit-inner-spin-button{appearance:none}.\[\&\:\:-webkit-outer-spin-button\]\:appearance-none::-webkit-outer-spin-button{appearance:none}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
{
|
|
11
11
|
"path": "add-on-selector.tsx",
|
|
12
|
-
"content": "\"use client\";\n\nimport React, { useCallback } from \"react\";\nimport { Checkbox } from \"@base-ui/react/checkbox\";\nimport type { AddOnWithOptions } from \"@cimplify/sdk\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { parsePrice } from \"@cimplify/sdk\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface AddOnSelectorClassNames {\n root?: string;\n group?: string;\n header?: string;\n name?: string;\n required?: string;\n constraint?: string;\n validation?: string;\n options?: string;\n option?: string;\n optionSelected?: string;\n optionName?: string;\n optionDescription?: string;\n}\n\nexport interface AddOnSelectorProps {\n addOns: AddOnWithOptions[];\n selectedOptions: string[];\n onOptionsChange: (optionIds: string[]) => void;\n className?: string;\n classNames?: AddOnSelectorClassNames;\n}\n\nexport function AddOnSelector({\n addOns,\n selectedOptions,\n onOptionsChange,\n className,\n classNames,\n}: AddOnSelectorProps): React.ReactElement | null {\n const isOptionSelected = useCallback(\n (optionId: string) => selectedOptions.includes(optionId),\n [selectedOptions],\n );\n\n const handleCheckedChange = useCallback(\n (addOn: AddOnWithOptions, optionId: string, checked: boolean) => {\n const isSelected = selectedOptions.includes(optionId);\n\n if (addOn.is_mutually_exclusive || !addOn.is_multiple_allowed) {\n const groupOptionIds = new Set(addOn.options.map((o) => o.id));\n const withoutGroup = selectedOptions.filter((id) => !groupOptionIds.has(id));\n\n if (isSelected) {\n if (!addOn.is_required) {\n onOptionsChange(withoutGroup);\n }\n } else {\n onOptionsChange([...withoutGroup, optionId]);\n }\n } else {\n if (isSelected) {\n onOptionsChange(selectedOptions.filter((id) => id !== optionId));\n } else {\n const currentCount = selectedOptions.filter((id) =>\n addOn.options.some((o) => o.id === id),\n ).length;\n\n if (addOn.max_selections && currentCount >= addOn.max_selections) {\n return;\n }\n\n onOptionsChange([...selectedOptions, optionId]);\n }\n }\n },\n [selectedOptions, onOptionsChange],\n );\n\n if (!addOns || addOns.length === 0) {\n return null;\n }\n\n return (\n <div data-cimplify-addon-selector className={cn(\"space-y-6\", className, classNames?.root)}>\n {addOns.map((addOn) => {\n const currentSelections = selectedOptions.filter((id) =>\n addOn.options.some((o) => o.id === id),\n ).length;\n const minMet = !addOn.min_selections || currentSelections >= addOn.min_selections;\n\n return (\n <div\n key={addOn.id}\n data-cimplify-addon-group\n className={cn(
|
|
12
|
+
"content": "\"use client\";\n\nimport React, { useCallback } from \"react\";\nimport { Checkbox } from \"@base-ui/react/checkbox\";\nimport type { AddOnWithOptions } from \"@cimplify/sdk\";\nimport { Price } from \"@cimplify/sdk/react\";\nimport { parsePrice } from \"@cimplify/sdk\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface AddOnSelectorClassNames {\n root?: string;\n group?: string;\n header?: string;\n name?: string;\n required?: string;\n constraint?: string;\n validation?: string;\n options?: string;\n option?: string;\n optionSelected?: string;\n optionName?: string;\n optionDescription?: string;\n}\n\nexport interface AddOnSelectorProps {\n addOns: AddOnWithOptions[];\n selectedOptions: string[];\n onOptionsChange: (optionIds: string[]) => void;\n className?: string;\n classNames?: AddOnSelectorClassNames;\n}\n\nexport function AddOnSelector({\n addOns,\n selectedOptions,\n onOptionsChange,\n className,\n classNames,\n}: AddOnSelectorProps): React.ReactElement | null {\n const isOptionSelected = useCallback(\n (optionId: string) => selectedOptions.includes(optionId),\n [selectedOptions],\n );\n\n const handleCheckedChange = useCallback(\n (addOn: AddOnWithOptions, optionId: string, checked: boolean) => {\n const isSelected = selectedOptions.includes(optionId);\n\n if (addOn.is_mutually_exclusive || !addOn.is_multiple_allowed) {\n const groupOptionIds = new Set(addOn.options.map((o) => o.id));\n const withoutGroup = selectedOptions.filter((id) => !groupOptionIds.has(id));\n\n if (isSelected) {\n if (!addOn.is_required) {\n onOptionsChange(withoutGroup);\n }\n } else {\n onOptionsChange([...withoutGroup, optionId]);\n }\n } else {\n if (isSelected) {\n onOptionsChange(selectedOptions.filter((id) => id !== optionId));\n } else {\n const currentCount = selectedOptions.filter((id) =>\n addOn.options.some((o) => o.id === id),\n ).length;\n\n if (addOn.max_selections && currentCount >= addOn.max_selections) {\n return;\n }\n\n onOptionsChange([...selectedOptions, optionId]);\n }\n }\n },\n [selectedOptions, onOptionsChange],\n );\n\n if (!addOns || addOns.length === 0) {\n return null;\n }\n\n return (\n <div data-cimplify-addon-selector className={cn(\"space-y-6\", className, classNames?.root)}>\n {addOns.map((addOn) => {\n const currentSelections = selectedOptions.filter((id) =>\n addOn.options.some((o) => o.id === id),\n ).length;\n const minMet = !addOn.min_selections || currentSelections >= addOn.min_selections;\n const isSingleSelect = addOn.is_mutually_exclusive || !addOn.is_multiple_allowed;\n\n return (\n <div\n key={addOn.id}\n data-cimplify-addon-group\n className={cn(classNames?.group)}\n >\n <div\n data-cimplify-addon-header\n className={cn(\"flex items-center justify-between py-3\", classNames?.header)}\n >\n <div>\n <span\n data-cimplify-addon-name\n className={cn(\"text-base font-bold\", classNames?.name)}\n >\n {addOn.name}\n </span>\n {(addOn.min_selections || addOn.max_selections) && (\n <span\n data-cimplify-addon-constraint\n className={cn(\"block text-xs text-muted-foreground mt-0.5\", classNames?.constraint)}\n >\n {addOn.min_selections && addOn.max_selections\n ? `Choose ${addOn.min_selections}\\u2013${addOn.max_selections}`\n : addOn.min_selections\n ? `Choose at least ${addOn.min_selections}`\n : `Choose up to ${addOn.max_selections}`}\n </span>\n )}\n </div>\n {(addOn.is_required || !minMet) && (\n <span\n data-cimplify-addon-required\n className={cn(\n \"text-xs font-semibold px-2.5 py-1 rounded\",\n !minMet\n ? \"text-destructive bg-destructive/10\"\n : \"text-destructive bg-destructive/10\",\n classNames?.required,\n )}\n >\n Required\n </span>\n )}\n </div>\n\n <div\n data-cimplify-addon-options\n className={cn(\"divide-y divide-border\", classNames?.options)}\n >\n {addOn.options.map((option) => {\n const isSelected = isOptionSelected(option.id);\n\n return (\n <Checkbox.Root\n key={option.id}\n checked={isSelected}\n onCheckedChange={(checked) =>\n handleCheckedChange(addOn, option.id, checked)\n }\n value={option.id}\n data-cimplify-addon-option\n data-selected={isSelected || undefined}\n className={cn(\n \"w-full flex items-center gap-3 py-4 transition-colors text-left cursor-pointer\",\n isSelected ? classNames?.optionSelected : classNames?.option,\n )}\n >\n <Checkbox.Indicator\n className=\"hidden\"\n keepMounted={false}\n />\n\n {/* Visual indicator: radio circle for single-select, checkbox square for multi-select */}\n {isSingleSelect ? (\n <span\n data-cimplify-addon-radio\n className={cn(\n \"w-5 h-5 rounded-full border-2 flex items-center justify-center shrink-0 transition-colors\",\n isSelected ? \"border-primary\" : \"border-muted-foreground/30\",\n )}\n >\n {isSelected && <span className=\"w-2.5 h-2.5 rounded-full bg-primary\" />}\n </span>\n ) : (\n <span\n data-cimplify-addon-checkbox\n className={cn(\n \"w-5 h-5 rounded-sm border-2 flex items-center justify-center shrink-0 transition-colors\",\n isSelected ? \"border-primary bg-primary\" : \"border-muted-foreground/30\",\n )}\n >\n {isSelected && (\n <svg viewBox=\"0 0 12 12\" className=\"w-3 h-3 text-primary-foreground\" fill=\"none\">\n <path d=\"M2 6l3 3 5-5\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\"/>\n </svg>\n )}\n </span>\n )}\n\n <span\n data-cimplify-addon-option-name\n className={cn(\n \"flex-1 min-w-0 text-sm\",\n classNames?.optionName,\n )}\n >\n {option.name}\n </span>\n\n {option.default_price != null && (\n <span className=\"text-sm text-muted-foreground\">\n +<Price amount={option.default_price} />\n </span>\n )}\n </Checkbox.Root>\n );\n })}\n </div>\n </div>\n );\n })}\n </div>\n );\n}\n"
|
|
13
13
|
}
|
|
14
14
|
]
|
|
15
15
|
}
|