smartsell-ui-kit 0.0.6 → 0.1.0

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
@@ -1,10 +1,10 @@
1
1
  import {
2
- Modal
3
- } from "./chunk-UIFTQDYM.js";
2
+ Modal,
3
+ withAlpha
4
+ } from "./chunk-YWH2VIAD.js";
4
5
 
5
6
  // src/components/Button.tsx
6
7
  import { useState } from "react";
7
- import { withAlpha as withAlpha2 } from "smartsell-sales-sdk";
8
8
 
9
9
  // src/components/controlSize.ts
10
10
  var CONTROL_METRICS_BY_SIZE = {
@@ -65,13 +65,60 @@ var getButtonSizeStyles = (size) => {
65
65
 
66
66
  // src/theme.ts
67
67
  import { useMemo } from "react";
68
- import {
69
- useSalesTheme,
70
- withAlpha
71
- } from "smartsell-sales-sdk";
72
- function useUiKitTheme(sdk) {
73
- const { theme } = useSalesTheme(sdk);
68
+ import { useThemeValue } from "smartsell-theme";
69
+ var DEFAULT_THEME_COLORS = {
70
+ primary: "#111827",
71
+ secondary: "#6b7280",
72
+ background: "#f8fafc",
73
+ surface: "#ffffff",
74
+ text: "#111827",
75
+ textLight: "#6b7280",
76
+ positive: "#16a34a",
77
+ negative: "#dc2626",
78
+ warning: "#d97706",
79
+ info: "#2563eb",
80
+ onPrimary: "#ffffff"
81
+ };
82
+ function normalizeUiKitTheme(theme) {
83
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v;
84
+ const colors = theme.colors;
85
+ const primary = (_a = colors.primary) != null ? _a : DEFAULT_THEME_COLORS.primary;
86
+ const background = (_b = colors.background) != null ? _b : DEFAULT_THEME_COLORS.background;
87
+ const surface = (_c = colors.surface) != null ? _c : background;
88
+ const text = (_f = (_e = (_d = colors.text) != null ? _d : colors.onSurface) != null ? _e : colors.onBackground) != null ? _f : DEFAULT_THEME_COLORS.text;
89
+ const textLight = (_h = (_g = colors.textLight) != null ? _g : colors.onSurfaceLight) != null ? _h : text;
90
+ const normalizedColors = {
91
+ ...theme.colors,
92
+ primary,
93
+ primaryLight: (_i = colors.primaryLight) != null ? _i : primary,
94
+ primaryDark: (_j = colors.primaryDark) != null ? _j : primary,
95
+ secondary: (_k = colors.secondary) != null ? _k : DEFAULT_THEME_COLORS.secondary,
96
+ background,
97
+ backgroundLight: (_l = colors.backgroundLight) != null ? _l : background,
98
+ surface,
99
+ text,
100
+ textLight,
101
+ positive: (_m = colors.positive) != null ? _m : DEFAULT_THEME_COLORS.positive,
102
+ negative: (_n = colors.negative) != null ? _n : DEFAULT_THEME_COLORS.negative,
103
+ warning: (_o = colors.warning) != null ? _o : DEFAULT_THEME_COLORS.warning,
104
+ info: (_p = colors.info) != null ? _p : DEFAULT_THEME_COLORS.info,
105
+ onPrimary: (_q = colors.onPrimary) != null ? _q : DEFAULT_THEME_COLORS.onPrimary,
106
+ onSecondary: (_r = colors.onSecondary) != null ? _r : text,
107
+ onBackground: (_s = colors.onBackground) != null ? _s : text,
108
+ onSurface: (_t = colors.onSurface) != null ? _t : text,
109
+ onSurfaceLight: (_u = colors.onSurfaceLight) != null ? _u : textLight,
110
+ onWarning: (_v = colors.onWarning) != null ? _v : text
111
+ };
112
+ return {
113
+ ...theme,
114
+ colors: normalizedColors,
115
+ color: normalizedColors
116
+ };
117
+ }
118
+ function useUiKitTheme() {
119
+ const activeTheme = useThemeValue();
74
120
  return useMemo(() => {
121
+ const theme = normalizeUiKitTheme(activeTheme);
75
122
  return {
76
123
  theme,
77
124
  borderSoft: withAlpha(theme.colors.onSurface, 0.1),
@@ -82,13 +129,12 @@ function useUiKitTheme(sdk) {
82
129
  focusRing: withAlpha(theme.colors.primary, 0.22),
83
130
  mutedText: withAlpha(theme.colors.onSurface, 0.72)
84
131
  };
85
- }, [theme]);
132
+ }, [activeTheme]);
86
133
  }
87
134
 
88
135
  // src/components/Button.tsx
89
136
  import { jsxs } from "react/jsx-runtime";
90
137
  function Button({
91
- sdk,
92
138
  variant = "solid",
93
139
  size = "md",
94
140
  fullWidth = false,
@@ -110,18 +156,18 @@ function Button({
110
156
  onTouchCancel,
111
157
  ...rest
112
158
  }) {
113
- const { theme } = useUiKitTheme(sdk);
159
+ const { theme } = useUiKitTheme();
114
160
  const [isHovered, setIsHovered] = useState(false);
115
161
  const [isPressed, setIsPressed] = useState(false);
116
162
  const variantStyles = {
117
163
  solid: {
118
164
  backgroundColor: theme.colors.primary,
119
- borderColor: withAlpha2(theme.colors.primary, 0.5),
165
+ borderColor: withAlpha(theme.colors.primary, 0.5),
120
166
  color: theme.colors.onPrimary
121
167
  },
122
168
  outline: {
123
169
  backgroundColor: "transparent",
124
- borderColor: withAlpha2(theme.colors.text, 0.5),
170
+ borderColor: withAlpha(theme.colors.text, 0.5),
125
171
  color: theme.colors.onSurface
126
172
  },
127
173
  ghost: {
@@ -140,12 +186,12 @@ function Button({
140
186
  },
141
187
  outline: {
142
188
  transform: isPressed ? "translateY(1px) scale(0.985)" : isHovered ? "translateY(-1px)" : "translateY(0)",
143
- backgroundColor: isPressed ? withAlpha2(interactiveColor, 0.14) : isHovered ? withAlpha2(interactiveColor, 0.08) : "transparent",
189
+ backgroundColor: isPressed ? withAlpha(interactiveColor, 0.14) : isHovered ? withAlpha(interactiveColor, 0.08) : "transparent",
144
190
  boxShadow: "none"
145
191
  },
146
192
  ghost: {
147
193
  transform: isPressed ? "translateY(1px) scale(0.985)" : isHovered ? "translateY(-1px)" : "translateY(0)",
148
- backgroundColor: isPressed ? withAlpha2(interactiveColor, 0.12) : isHovered ? withAlpha2(interactiveColor, 0.06) : "transparent",
194
+ backgroundColor: isPressed ? withAlpha(interactiveColor, 0.12) : isHovered ? withAlpha(interactiveColor, 0.06) : "transparent",
149
195
  boxShadow: "none"
150
196
  }
151
197
  };
@@ -234,10 +280,8 @@ function Button({
234
280
  }
235
281
 
236
282
  // src/components/Card.tsx
237
- import { withAlpha as withAlpha3 } from "smartsell-sales-sdk";
238
283
  import { jsx, jsxs as jsxs2 } from "react/jsx-runtime";
239
284
  function Card({
240
- sdk,
241
285
  children,
242
286
  eyebrow,
243
287
  title,
@@ -246,15 +290,15 @@ function Card({
246
290
  style,
247
291
  ...rest
248
292
  }) {
249
- const { theme } = useUiKitTheme(sdk);
293
+ const { theme } = useUiKitTheme();
250
294
  return /* @__PURE__ */ jsxs2(
251
295
  "div",
252
296
  {
253
297
  ...rest,
254
298
  style: {
255
299
  borderRadius: 28,
256
- border: `1px solid ${withAlpha3(theme.colors.text, 0.5)}`,
257
- background: `${withAlpha3(theme.colors.background, 0.7)}`,
300
+ border: `1px solid ${withAlpha(theme.colors.text, 0.5)}`,
301
+ background: `${withAlpha(theme.colors.background, 0.7)}`,
258
302
  color: theme.colors.text,
259
303
  padding: padded ? 24 : void 0,
260
304
  ...style
@@ -308,22 +352,265 @@ function Card({
308
352
  );
309
353
  }
310
354
 
355
+ // src/components/Checkbox.tsx
356
+ import { useEffect, useId, useRef, useState as useState2 } from "react";
357
+ import { jsx as jsx2, jsxs as jsxs3 } from "react/jsx-runtime";
358
+ var CHECKBOX_SIZE_BY_CONTROL_SIZE = {
359
+ sm: 18,
360
+ md: 20,
361
+ lg: 22
362
+ };
363
+ var getCheckboxSize = (controlSize) => CHECKBOX_SIZE_BY_CONTROL_SIZE[controlSize];
364
+ function CheckIcon({ size, color }) {
365
+ return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2(
366
+ "path",
367
+ {
368
+ d: "M5.75 10.25L8.5 13l5.75-6",
369
+ stroke: color,
370
+ strokeWidth: "1.8",
371
+ strokeLinecap: "round",
372
+ strokeLinejoin: "round"
373
+ }
374
+ ) });
375
+ }
376
+ function MixedIcon({ size, color }) {
377
+ return /* @__PURE__ */ jsx2("svg", { width: size, height: size, viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ jsx2("path", { d: "M5.5 10H14.5", stroke: color, strokeWidth: "1.8", strokeLinecap: "round" }) });
378
+ }
379
+ function CheckboxIndicator({
380
+ checked,
381
+ indeterminate = false,
382
+ disabled = false,
383
+ size = 20,
384
+ checkedColor,
385
+ iconColor,
386
+ uncheckedBorderColor,
387
+ uncheckedBackgroundColor = "transparent",
388
+ style
389
+ }) {
390
+ const isActive = checked || indeterminate;
391
+ return /* @__PURE__ */ jsxs3(
392
+ "span",
393
+ {
394
+ "aria-hidden": "true",
395
+ style: {
396
+ width: size,
397
+ height: size,
398
+ borderRadius: 999,
399
+ boxSizing: "border-box",
400
+ flexShrink: 0,
401
+ display: "inline-flex",
402
+ alignItems: "center",
403
+ justifyContent: "center",
404
+ border: `1.5px solid ${isActive ? checkedColor : uncheckedBorderColor}`,
405
+ backgroundColor: isActive ? checkedColor : uncheckedBackgroundColor,
406
+ opacity: disabled ? 0.45 : 1,
407
+ transition: "background-color 140ms ease, border-color 140ms ease, opacity 140ms ease",
408
+ ...style
409
+ },
410
+ children: [
411
+ indeterminate ? /* @__PURE__ */ jsx2(MixedIcon, { size: Math.max(10, size - 6), color: iconColor }) : null,
412
+ !indeterminate && checked ? /* @__PURE__ */ jsx2(CheckIcon, { size: Math.max(10, size - 6), color: iconColor }) : null
413
+ ]
414
+ }
415
+ );
416
+ }
417
+ function Checkbox({
418
+ label,
419
+ hint,
420
+ error,
421
+ controlSize = "md",
422
+ id,
423
+ checked,
424
+ defaultChecked,
425
+ disabled,
426
+ indeterminate = false,
427
+ required,
428
+ className,
429
+ style,
430
+ onChange,
431
+ onFocus,
432
+ onBlur,
433
+ ...rest
434
+ }) {
435
+ const { theme, mutedText } = useUiKitTheme();
436
+ const controlMetrics = getControlMetrics(controlSize);
437
+ const indicatorSize = getCheckboxSize(controlSize);
438
+ const resolvedId = id != null ? id : `ss-checkbox-${useId().replace(/:/g, "")}`;
439
+ const inputRef = useRef(null);
440
+ const [isFocused, setIsFocused] = useState2(false);
441
+ const [internalChecked, setInternalChecked] = useState2(Boolean(defaultChecked));
442
+ const isControlled = checked !== void 0;
443
+ const resolvedChecked = isControlled ? Boolean(checked) : internalChecked;
444
+ useEffect(() => {
445
+ if (!inputRef.current) {
446
+ return;
447
+ }
448
+ inputRef.current.indeterminate = indeterminate;
449
+ }, [indeterminate, resolvedChecked]);
450
+ return /* @__PURE__ */ jsx2(
451
+ "div",
452
+ {
453
+ className,
454
+ style: {
455
+ width: "100%",
456
+ display: "flex",
457
+ flexDirection: "column",
458
+ gap: 6,
459
+ ...style
460
+ },
461
+ children: /* @__PURE__ */ jsxs3(
462
+ "label",
463
+ {
464
+ htmlFor: resolvedId,
465
+ style: {
466
+ display: "inline-flex",
467
+ alignItems: label || hint ? "flex-start" : "center",
468
+ gap: 10,
469
+ width: label || hint || error ? "100%" : "auto",
470
+ cursor: disabled ? "not-allowed" : "pointer",
471
+ opacity: disabled ? 0.7 : 1,
472
+ userSelect: "none"
473
+ },
474
+ children: [
475
+ /* @__PURE__ */ jsxs3(
476
+ "span",
477
+ {
478
+ style: {
479
+ position: "relative",
480
+ display: "inline-flex",
481
+ alignItems: "center",
482
+ justifyContent: "center",
483
+ flexShrink: 0,
484
+ padding: 2,
485
+ marginTop: label || hint ? 1 : 0,
486
+ borderRadius: 999,
487
+ boxShadow: isFocused ? `0 0 0 3px ${withAlpha(theme.colors.primary, 0.16)}` : "none",
488
+ transition: "box-shadow 140ms ease"
489
+ },
490
+ children: [
491
+ /* @__PURE__ */ jsx2(
492
+ "input",
493
+ {
494
+ ...rest,
495
+ ref: inputRef,
496
+ id: resolvedId,
497
+ type: "checkbox",
498
+ checked: resolvedChecked,
499
+ disabled,
500
+ required,
501
+ onChange: (event) => {
502
+ if (!isControlled) {
503
+ setInternalChecked(event.currentTarget.checked);
504
+ }
505
+ onChange == null ? void 0 : onChange(event);
506
+ },
507
+ onFocus: (event) => {
508
+ setIsFocused(true);
509
+ onFocus == null ? void 0 : onFocus(event);
510
+ },
511
+ onBlur: (event) => {
512
+ setIsFocused(false);
513
+ onBlur == null ? void 0 : onBlur(event);
514
+ },
515
+ style: {
516
+ position: "absolute",
517
+ inset: 0,
518
+ width: "100%",
519
+ height: "100%",
520
+ margin: 0,
521
+ opacity: 0,
522
+ cursor: disabled ? "not-allowed" : "pointer"
523
+ }
524
+ }
525
+ ),
526
+ /* @__PURE__ */ jsx2(
527
+ CheckboxIndicator,
528
+ {
529
+ checked: resolvedChecked,
530
+ indeterminate,
531
+ disabled,
532
+ size: indicatorSize,
533
+ checkedColor: theme.colors.primary,
534
+ iconColor: theme.colors.onPrimary,
535
+ uncheckedBorderColor: withAlpha(theme.colors.onSurface, 0.24),
536
+ uncheckedBackgroundColor: theme.colors.surface
537
+ }
538
+ )
539
+ ]
540
+ }
541
+ ),
542
+ label || hint || error ? /* @__PURE__ */ jsxs3(
543
+ "span",
544
+ {
545
+ style: {
546
+ display: "flex",
547
+ flexDirection: "column",
548
+ gap: 4,
549
+ minWidth: 0
550
+ },
551
+ children: [
552
+ label ? /* @__PURE__ */ jsxs3(
553
+ "span",
554
+ {
555
+ style: {
556
+ color: theme.colors.onSurface,
557
+ fontSize: controlMetrics.fontSize,
558
+ lineHeight: controlMetrics.lineHeight,
559
+ fontWeight: 600
560
+ },
561
+ children: [
562
+ label,
563
+ required ? /* @__PURE__ */ jsx2("span", { style: { color: theme.colors.negative, marginLeft: 4 }, children: "*" }) : null
564
+ ]
565
+ }
566
+ ) : null,
567
+ hint ? /* @__PURE__ */ jsx2(
568
+ "span",
569
+ {
570
+ style: {
571
+ color: mutedText,
572
+ fontSize: 13,
573
+ lineHeight: 1.45
574
+ },
575
+ children: hint
576
+ }
577
+ ) : null,
578
+ error ? /* @__PURE__ */ jsx2(
579
+ "span",
580
+ {
581
+ style: {
582
+ color: theme.colors.negative,
583
+ fontSize: 13,
584
+ lineHeight: 1.45,
585
+ fontWeight: 600
586
+ },
587
+ children: error
588
+ }
589
+ ) : null
590
+ ]
591
+ }
592
+ ) : null
593
+ ]
594
+ }
595
+ )
596
+ }
597
+ );
598
+ }
599
+
311
600
  // src/components/ComposableModal.tsx
312
601
  import { useMemo as useMemo2 } from "react";
313
- import { SlotRenderer } from "smartsell-sales-sdk";
314
- import { Fragment, jsx as jsx2, jsxs as jsxs3 } from "react/jsx-runtime";
602
+ import { Fragment, jsx as jsx3, jsxs as jsxs4 } from "react/jsx-runtime";
315
603
  var createModalSlotIds = (slotBaseId) => ({
316
604
  header: `${slotBaseId}:modal-header`,
317
605
  body: `${slotBaseId}:modal-body`,
318
606
  footer: `${slotBaseId}:modal-footer`
319
607
  });
320
608
  function ComposableModal({
321
- sdk,
322
609
  isOpen,
323
610
  onClose,
324
611
  title,
325
- description,
326
612
  slotBaseId,
613
+ renderSlot,
327
614
  payload,
328
615
  onConfirm,
329
616
  confirmLabel = "Confirm",
@@ -339,12 +626,11 @@ function ComposableModal({
339
626
  footerFallback,
340
627
  children
341
628
  }) {
342
- const theme = useUiKitTheme(sdk);
629
+ const theme = useUiKitTheme();
343
630
  const slotIds = createModalSlotIds(slotBaseId);
344
631
  const context = useMemo2(
345
632
  () => ({
346
633
  title,
347
- description,
348
634
  payload,
349
635
  close: onClose,
350
636
  confirm: onConfirm,
@@ -353,48 +639,44 @@ function ComposableModal({
353
639
  isOpen,
354
640
  isBusy
355
641
  }),
356
- [cancelLabel, confirmLabel, description, isBusy, isOpen, onClose, onConfirm, payload, title]
642
+ [cancelLabel, confirmLabel, isBusy, isOpen, onClose, onConfirm, payload, title]
357
643
  );
358
- const defaultFooter = hideDefaultFooter ? void 0 : footerFallback != null ? footerFallback : /* @__PURE__ */ jsxs3(Fragment, { children: [
359
- /* @__PURE__ */ jsx2(Button, { sdk, variant: "outline", onClick: onClose, disabled: isBusy, children: cancelLabel }),
360
- onConfirm ? /* @__PURE__ */ jsx2(Button, { sdk, onClick: onConfirm, disabled: isBusy, children: confirmLabel }) : null
361
- ] });
362
- const defaultHeader = headerFallback != null ? headerFallback : /* @__PURE__ */ jsxs3("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
363
- /* @__PURE__ */ jsx2(
364
- "h2",
365
- {
366
- style: {
367
- margin: 0,
368
- fontSize: 30,
369
- fontWeight: 800,
370
- lineHeight: 1.1
371
- },
372
- children: title
373
- }
374
- ),
375
- description ? /* @__PURE__ */ jsx2(
376
- "p",
377
- {
378
- style: {
379
- margin: 0,
380
- fontSize: 15,
381
- lineHeight: 1.6,
382
- opacity: 0.78
383
- },
384
- children: description
385
- }
386
- ) : null
644
+ const defaultFooter = hideDefaultFooter ? void 0 : footerFallback != null ? footerFallback : /* @__PURE__ */ jsxs4(Fragment, { children: [
645
+ /* @__PURE__ */ jsx3(Button, { variant: "outline", onClick: onClose, disabled: isBusy, children: cancelLabel }),
646
+ onConfirm ? /* @__PURE__ */ jsx3(Button, { onClick: onConfirm, disabled: isBusy, children: confirmLabel }) : null
387
647
  ] });
388
- const headerContent = /* @__PURE__ */ jsx2(SlotRenderer, { id: slotIds.header, sdk, context, children: defaultHeader });
389
- const bodyContent = /* @__PURE__ */ jsx2(SlotRenderer, { id: slotIds.body, sdk, context, children });
390
- const footerContent = /* @__PURE__ */ jsx2(SlotRenderer, { id: slotIds.footer, sdk, context, children: defaultFooter });
391
- return /* @__PURE__ */ jsx2(
648
+ const defaultHeader = headerFallback != null ? headerFallback : /* @__PURE__ */ jsx3(
649
+ "h2",
650
+ {
651
+ style: {
652
+ margin: 0,
653
+ fontSize: 30,
654
+ fontWeight: 800,
655
+ lineHeight: 1.1
656
+ },
657
+ children: title
658
+ }
659
+ );
660
+ const renderSlotContent = (id, slotChildren) => {
661
+ if (!renderSlot) {
662
+ return slotChildren;
663
+ }
664
+ return renderSlot({
665
+ id,
666
+ context,
667
+ children: slotChildren
668
+ });
669
+ };
670
+ const headerContent = renderSlotContent(slotIds.header, defaultHeader);
671
+ const bodyContent = renderSlotContent(slotIds.body, children);
672
+ const footerContent = renderSlotContent(slotIds.footer, defaultFooter);
673
+ return /* @__PURE__ */ jsx3(
392
674
  Modal,
393
675
  {
394
676
  isOpen,
395
677
  onClose,
396
678
  title,
397
- description,
679
+ isBusy,
398
680
  headerContent,
399
681
  footer: footerContent,
400
682
  theme,
@@ -408,10 +690,17 @@ function ComposableModal({
408
690
  );
409
691
  }
410
692
 
693
+ // src/components/DatePicker.tsx
694
+ import {
695
+ useEffect as useEffect2,
696
+ useMemo as useMemo3,
697
+ useRef as useRef2,
698
+ useState as useState4
699
+ } from "react";
700
+
411
701
  // src/components/Input.tsx
412
- import { useState as useState2 } from "react";
413
- import { withAlpha as withAlpha4 } from "smartsell-sales-sdk";
414
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs4 } from "react/jsx-runtime";
702
+ import { useState as useState3 } from "react";
703
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs5 } from "react/jsx-runtime";
415
704
  var PASSWORD_TOGGLE_METRICS_BY_SIZE = {
416
705
  sm: {
417
706
  buttonSize: 18,
@@ -434,7 +723,6 @@ var PASSWORD_TOGGLE_METRICS_BY_SIZE = {
434
723
  };
435
724
  var getPasswordToggleMetrics = (size) => PASSWORD_TOGGLE_METRICS_BY_SIZE[size];
436
725
  function ControlFrame({
437
- sdk,
438
726
  label,
439
727
  hint,
440
728
  error,
@@ -444,10 +732,10 @@ function ControlFrame({
444
732
  children,
445
733
  style
446
734
  }) {
735
+ const { theme, mutedText } = useUiKitTheme();
447
736
  if (!label && !hint && !error) {
448
- return /* @__PURE__ */ jsx3(Fragment2, { children });
737
+ return /* @__PURE__ */ jsx4(Fragment2, { children });
449
738
  }
450
- const { theme, mutedText } = useUiKitTheme(sdk);
451
739
  const labelStyle = {
452
740
  color: theme.colors.onSurface,
453
741
  fontSize: 14,
@@ -462,13 +750,13 @@ function ControlFrame({
462
750
  ...style
463
751
  };
464
752
  if (!useLabelWrapper) {
465
- return /* @__PURE__ */ jsxs4("div", { style: wrapperStyle, children: [
466
- label || hint ? /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
467
- label ? /* @__PURE__ */ jsxs4("label", { htmlFor, style: labelStyle, children: [
753
+ return /* @__PURE__ */ jsxs5("div", { style: wrapperStyle, children: [
754
+ label || hint ? /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
755
+ label ? /* @__PURE__ */ jsxs5("label", { htmlFor, style: labelStyle, children: [
468
756
  label,
469
- required ? /* @__PURE__ */ jsx3("span", { style: { color: theme.colors.negative, marginLeft: 4 }, children: "*" }) : null
757
+ required ? /* @__PURE__ */ jsx4("span", { style: { color: theme.colors.negative, marginLeft: 4 }, children: "*" }) : null
470
758
  ] }) : null,
471
- hint ? /* @__PURE__ */ jsx3(
759
+ hint ? /* @__PURE__ */ jsx4(
472
760
  "span",
473
761
  {
474
762
  style: {
@@ -481,7 +769,7 @@ function ControlFrame({
481
769
  ) : null
482
770
  ] }) : null,
483
771
  children,
484
- error ? /* @__PURE__ */ jsx3(
772
+ error ? /* @__PURE__ */ jsx4(
485
773
  "span",
486
774
  {
487
775
  style: {
@@ -495,13 +783,13 @@ function ControlFrame({
495
783
  ) : null
496
784
  ] });
497
785
  }
498
- return /* @__PURE__ */ jsxs4("label", { htmlFor, style: wrapperStyle, children: [
499
- label || hint ? /* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
500
- label ? /* @__PURE__ */ jsxs4("span", { style: labelStyle, children: [
786
+ return /* @__PURE__ */ jsxs5("label", { htmlFor, style: wrapperStyle, children: [
787
+ label || hint ? /* @__PURE__ */ jsxs5("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [
788
+ label ? /* @__PURE__ */ jsxs5("span", { style: labelStyle, children: [
501
789
  label,
502
- required ? /* @__PURE__ */ jsx3("span", { style: { color: theme.colors.negative, marginLeft: 4 }, children: "*" }) : null
790
+ required ? /* @__PURE__ */ jsx4("span", { style: { color: theme.colors.negative, marginLeft: 4 }, children: "*" }) : null
503
791
  ] }) : null,
504
- hint ? /* @__PURE__ */ jsx3(
792
+ hint ? /* @__PURE__ */ jsx4(
505
793
  "span",
506
794
  {
507
795
  style: {
@@ -514,7 +802,7 @@ function ControlFrame({
514
802
  ) : null
515
803
  ] }) : null,
516
804
  children,
517
- error ? /* @__PURE__ */ jsx3(
805
+ error ? /* @__PURE__ */ jsx4(
518
806
  "span",
519
807
  {
520
808
  style: {
@@ -529,7 +817,6 @@ function ControlFrame({
529
817
  ] });
530
818
  }
531
819
  function Input({
532
- sdk,
533
820
  label,
534
821
  hint,
535
822
  error,
@@ -541,10 +828,10 @@ function Input({
541
828
  type = "text",
542
829
  ...rest
543
830
  }) {
544
- const { theme, borderSoft, focusRing, surfaceMuted } = useUiKitTheme(sdk);
831
+ const { theme, focusRing } = useUiKitTheme();
545
832
  const controlMetrics = getControlMetrics(controlSize);
546
833
  const passwordToggleMetrics = getPasswordToggleMetrics(controlSize);
547
- const [isPasswordVisible, setIsPasswordVisible] = useState2(false);
834
+ const [isPasswordVisible, setIsPasswordVisible] = useState3(false);
548
835
  const isPasswordField = type === "password";
549
836
  const canTogglePasswordVisibility = isPasswordField && showPasswordToggle;
550
837
  const passwordToggleInset = Math.max(
@@ -558,7 +845,7 @@ function Input({
558
845
  boxSizing: "border-box",
559
846
  height: controlMetrics.height,
560
847
  borderRadius: 16,
561
- border: `1px solid ${error ? theme.colors.negative : withAlpha4(theme.colors.textLight, 0.5)}`,
848
+ border: `1px solid ${error ? theme.colors.negative : withAlpha(theme.colors.textLight, 0.5)}`,
562
849
  backgroundColor: theme.colors.surface,
563
850
  color: theme.colors.text,
564
851
  cursor: disabled ? "not-allowed" : "text",
@@ -567,12 +854,12 @@ function Input({
567
854
  outline: "none",
568
855
  fontSize: controlMetrics.fontSize,
569
856
  lineHeight: controlMetrics.lineHeight,
570
- boxShadow: error ? `0 0 0 3px ${withAlpha4(theme.colors.negative, 0.12)}` : `0 0 0 0 ${focusRing}`,
857
+ boxShadow: error ? `0 0 0 3px ${withAlpha(theme.colors.negative, 0.12)}` : `0 0 0 0 ${focusRing}`,
571
858
  transition: "border-color 160ms ease, box-shadow 160ms ease, background-color 160ms ease",
572
859
  ...style
573
860
  };
574
- const input = canTogglePasswordVisibility ? /* @__PURE__ */ jsxs4("div", { style: { position: "relative", width: "100%" }, children: [
575
- /* @__PURE__ */ jsx3(
861
+ const input = canTogglePasswordVisibility ? /* @__PURE__ */ jsxs5("div", { style: { position: "relative", width: "100%" }, children: [
862
+ /* @__PURE__ */ jsx4(
576
863
  "button",
577
864
  {
578
865
  type: "button",
@@ -605,7 +892,7 @@ function Input({
605
892
  cursor: disabled ? "not-allowed" : "pointer",
606
893
  opacity: disabled ? 0.5 : 1
607
894
  },
608
- children: isPasswordVisible ? /* @__PURE__ */ jsxs4(
895
+ children: isPasswordVisible ? /* @__PURE__ */ jsxs5(
609
896
  "svg",
610
897
  {
611
898
  width: passwordToggleMetrics.iconSize,
@@ -614,7 +901,7 @@ function Input({
614
901
  fill: "none",
615
902
  "aria-hidden": "true",
616
903
  children: [
617
- /* @__PURE__ */ jsx3(
904
+ /* @__PURE__ */ jsx4(
618
905
  "path",
619
906
  {
620
907
  d: "M2.5 3.5L17.5 16.5",
@@ -623,7 +910,7 @@ function Input({
623
910
  strokeLinecap: "round"
624
911
  }
625
912
  ),
626
- /* @__PURE__ */ jsx3(
913
+ /* @__PURE__ */ jsx4(
627
914
  "path",
628
915
  {
629
916
  d: "M8.825 8.786a2 2 0 0 0 2.389 2.389",
@@ -633,7 +920,7 @@ function Input({
633
920
  strokeLinejoin: "round"
634
921
  }
635
922
  ),
636
- /* @__PURE__ */ jsx3(
923
+ /* @__PURE__ */ jsx4(
637
924
  "path",
638
925
  {
639
926
  d: "M4.42 6.774C3.422 7.73 2.777 8.815 2.5 9.375c1.182 2.39 3.934 5.625 7.5 5.625 1.155 0 2.224-.34 3.166-.847",
@@ -643,7 +930,7 @@ function Input({
643
930
  strokeLinejoin: "round"
644
931
  }
645
932
  ),
646
- /* @__PURE__ */ jsx3(
933
+ /* @__PURE__ */ jsx4(
647
934
  "path",
648
935
  {
649
936
  d: "M7.043 4.455A7.7 7.7 0 0 1 10 3.75c3.566 0 6.318 3.235 7.5 5.625-.39.787-1.504 2.588-3.259 3.986",
@@ -655,7 +942,7 @@ function Input({
655
942
  )
656
943
  ]
657
944
  }
658
- ) : /* @__PURE__ */ jsxs4(
945
+ ) : /* @__PURE__ */ jsxs5(
659
946
  "svg",
660
947
  {
661
948
  width: passwordToggleMetrics.iconSize,
@@ -664,7 +951,7 @@ function Input({
664
951
  fill: "none",
665
952
  "aria-hidden": "true",
666
953
  children: [
667
- /* @__PURE__ */ jsx3(
954
+ /* @__PURE__ */ jsx4(
668
955
  "path",
669
956
  {
670
957
  d: "M2.5 10c1.182-2.39 3.934-5.625 7.5-5.625S16.318 7.61 17.5 10c-1.182 2.39-3.934 5.625-7.5 5.625S3.682 12.39 2.5 10Z",
@@ -674,28 +961,605 @@ function Input({
674
961
  strokeLinejoin: "round"
675
962
  }
676
963
  ),
677
- /* @__PURE__ */ jsx3("circle", { cx: "10", cy: "10", r: "2.25", stroke: "currentColor", strokeWidth: "1.8" })
964
+ /* @__PURE__ */ jsx4("circle", { cx: "10", cy: "10", r: "2.25", stroke: "currentColor", strokeWidth: "1.8" })
678
965
  ]
679
966
  }
680
967
  )
681
968
  }
682
969
  ),
683
- /* @__PURE__ */ jsx3("input", { ...rest, id, type: resolvedType, disabled, style: inputStyle })
684
- ] }) : /* @__PURE__ */ jsx3("input", { ...rest, id, type: resolvedType, disabled, style: inputStyle });
685
- return /* @__PURE__ */ jsx3(ControlFrame, { sdk, label, hint, error, htmlFor: id, required: rest.required, children: input });
970
+ /* @__PURE__ */ jsx4("input", { ...rest, id, type: resolvedType, disabled, style: inputStyle })
971
+ ] }) : /* @__PURE__ */ jsx4("input", { ...rest, id, type: resolvedType, disabled, style: inputStyle });
972
+ return /* @__PURE__ */ jsx4(ControlFrame, { label, hint, error, htmlFor: id, required: rest.required, children: input });
973
+ }
974
+
975
+ // src/components/DatePicker.tsx
976
+ import { jsx as jsx5, jsxs as jsxs6 } from "react/jsx-runtime";
977
+ var DEFAULT_FORMAT_BY_MODE = {
978
+ date: "DD/MM/YYYY",
979
+ datetime: "DD/MM/YYYY HH:mm"
980
+ };
981
+ var HTML_DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
982
+ var HTML_DATETIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::\d{2})?$/;
983
+ var FORMAT_TOKENS = [
984
+ {
985
+ token: "YYYY",
986
+ key: "year",
987
+ pattern: "(\\d{4})",
988
+ formatter: (date) => String(date.getFullYear())
989
+ },
990
+ {
991
+ token: "MM",
992
+ key: "month",
993
+ pattern: "(\\d{1,2})",
994
+ formatter: (date) => padNumber(date.getMonth() + 1)
995
+ },
996
+ {
997
+ token: "DD",
998
+ key: "day",
999
+ pattern: "(\\d{1,2})",
1000
+ formatter: (date) => padNumber(date.getDate())
1001
+ },
1002
+ {
1003
+ token: "HH",
1004
+ key: "hour",
1005
+ pattern: "(\\d{1,2})",
1006
+ formatter: (date) => padNumber(date.getHours())
1007
+ },
1008
+ {
1009
+ token: "mm",
1010
+ key: "minute",
1011
+ pattern: "(\\d{1,2})",
1012
+ formatter: (date) => padNumber(date.getMinutes())
1013
+ }
1014
+ ];
1015
+ var ACCESSORY_METRICS_BY_SIZE = {
1016
+ sm: {
1017
+ buttonSize: 18,
1018
+ iconSize: 14,
1019
+ rightOffset: 8,
1020
+ clusterGap: 6,
1021
+ contentGap: 8
1022
+ },
1023
+ md: {
1024
+ buttonSize: 20,
1025
+ iconSize: 16,
1026
+ rightOffset: 10,
1027
+ clusterGap: 8,
1028
+ contentGap: 10
1029
+ },
1030
+ lg: {
1031
+ buttonSize: 22,
1032
+ iconSize: 18,
1033
+ rightOffset: 12,
1034
+ clusterGap: 8,
1035
+ contentGap: 12
1036
+ }
1037
+ };
1038
+ function padNumber(value, length = 2) {
1039
+ return String(value).padStart(length, "0");
1040
+ }
1041
+ function escapeRegExp(value) {
1042
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1043
+ }
1044
+ function isValidDateInstance(value) {
1045
+ return !Number.isNaN(value.getTime());
1046
+ }
1047
+ function createValidatedDate(year, month, day, hour = 0, minute = 0) {
1048
+ const nextDate = new Date(year, month - 1, day, hour, minute, 0, 0);
1049
+ if (!isValidDateInstance(nextDate)) {
1050
+ return null;
1051
+ }
1052
+ if (nextDate.getFullYear() !== year || nextDate.getMonth() !== month - 1 || nextDate.getDate() !== day || nextDate.getHours() !== hour || nextDate.getMinutes() !== minute) {
1053
+ return null;
1054
+ }
1055
+ return nextDate;
1056
+ }
1057
+ function normalizeDatePrecision(date, mode) {
1058
+ if (mode === "date") {
1059
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0);
1060
+ }
1061
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), 0, 0);
1062
+ }
1063
+ function toLocalInputValue(date, mode) {
1064
+ const normalizedDate = normalizeDatePrecision(date, mode);
1065
+ const datePart = `${normalizedDate.getFullYear()}-${padNumber(normalizedDate.getMonth() + 1)}-${padNumber(normalizedDate.getDate())}`;
1066
+ if (mode === "date") {
1067
+ return datePart;
1068
+ }
1069
+ return `${datePart}T${padNumber(normalizedDate.getHours())}:${padNumber(normalizedDate.getMinutes())}`;
1070
+ }
1071
+ function parseHtmlDateLikeValue(value) {
1072
+ const trimmedValue = value.trim();
1073
+ const dateMatch = HTML_DATE_PATTERN.exec(trimmedValue);
1074
+ if (dateMatch) {
1075
+ return createValidatedDate(
1076
+ Number(dateMatch[1]),
1077
+ Number(dateMatch[2]),
1078
+ Number(dateMatch[3])
1079
+ );
1080
+ }
1081
+ const datetimeMatch = HTML_DATETIME_PATTERN.exec(trimmedValue);
1082
+ if (datetimeMatch) {
1083
+ return createValidatedDate(
1084
+ Number(datetimeMatch[1]),
1085
+ Number(datetimeMatch[2]),
1086
+ Number(datetimeMatch[3]),
1087
+ Number(datetimeMatch[4]),
1088
+ Number(datetimeMatch[5])
1089
+ );
1090
+ }
1091
+ return null;
1092
+ }
1093
+ function parseFormattedDateValue(value, format, mode) {
1094
+ const orderedParts = [];
1095
+ let expression = "^";
1096
+ for (let index = 0; index < format.length; ) {
1097
+ const token = FORMAT_TOKENS.find(({ token: currentToken }) => format.startsWith(currentToken, index));
1098
+ if (token) {
1099
+ expression += token.pattern;
1100
+ orderedParts.push(token.key);
1101
+ index += token.token.length;
1102
+ continue;
1103
+ }
1104
+ expression += escapeRegExp(format[index]);
1105
+ index += 1;
1106
+ }
1107
+ expression += "$";
1108
+ const match = new RegExp(expression).exec(value.trim());
1109
+ if (!match) {
1110
+ return null;
1111
+ }
1112
+ const resolvedParts = {
1113
+ year: 0,
1114
+ month: 1,
1115
+ day: 1,
1116
+ hour: 0,
1117
+ minute: 0
1118
+ };
1119
+ orderedParts.forEach((key, index) => {
1120
+ resolvedParts[key] = Number(match[index + 1]);
1121
+ });
1122
+ if (!resolvedParts.year || !resolvedParts.month || !resolvedParts.day) {
1123
+ return null;
1124
+ }
1125
+ return createValidatedDate(
1126
+ resolvedParts.year,
1127
+ resolvedParts.month,
1128
+ resolvedParts.day,
1129
+ mode === "datetime" ? resolvedParts.hour : 0,
1130
+ mode === "datetime" ? resolvedParts.minute : 0
1131
+ );
1132
+ }
1133
+ function parseDateValue(value, mode, format) {
1134
+ if (value == null || value === "") {
1135
+ return null;
1136
+ }
1137
+ if (value instanceof Date) {
1138
+ return isValidDateInstance(value) ? normalizeDatePrecision(value, mode) : null;
1139
+ }
1140
+ if (typeof value !== "string") {
1141
+ return null;
1142
+ }
1143
+ const parsedFormattedDate = parseFormattedDateValue(value, format, mode);
1144
+ if (parsedFormattedDate) {
1145
+ return normalizeDatePrecision(parsedFormattedDate, mode);
1146
+ }
1147
+ const parsedHtmlDate = parseHtmlDateLikeValue(value);
1148
+ if (parsedHtmlDate) {
1149
+ return normalizeDatePrecision(parsedHtmlDate, mode);
1150
+ }
1151
+ const parsedNativeDate = new Date(value);
1152
+ return isValidDateInstance(parsedNativeDate) ? normalizeDatePrecision(parsedNativeDate, mode) : null;
1153
+ }
1154
+ function formatDateValue(date, format) {
1155
+ return FORMAT_TOKENS.reduce((currentFormat, token) => {
1156
+ return currentFormat.split(token.token).join(token.formatter(date));
1157
+ }, format);
1158
+ }
1159
+ function getLaterDate(leftDate, rightDate) {
1160
+ if (!leftDate) return rightDate;
1161
+ if (!rightDate) return leftDate;
1162
+ return leftDate.getTime() >= rightDate.getTime() ? leftDate : rightDate;
1163
+ }
1164
+ function getEarlierDate(leftDate, rightDate) {
1165
+ if (!leftDate) return rightDate;
1166
+ if (!rightDate) return leftDate;
1167
+ return leftDate.getTime() <= rightDate.getTime() ? leftDate : rightDate;
1168
+ }
1169
+ function CalendarIcon({ size }) {
1170
+ return /* @__PURE__ */ jsxs6("svg", { width: size, height: size, viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: [
1171
+ /* @__PURE__ */ jsx5("rect", { x: "3", y: "4.5", width: "14", height: "12.5", rx: "3", stroke: "currentColor", strokeWidth: "1.6" }),
1172
+ /* @__PURE__ */ jsx5("path", { d: "M6.25 2.75V6", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" }),
1173
+ /* @__PURE__ */ jsx5("path", { d: "M13.75 2.75V6", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" }),
1174
+ /* @__PURE__ */ jsx5("path", { d: "M3 7.5H17", stroke: "currentColor", strokeWidth: "1.6" }),
1175
+ /* @__PURE__ */ jsx5("circle", { cx: "10", cy: "11.5", r: "1.2", fill: "currentColor" })
1176
+ ] });
1177
+ }
1178
+ function ClearIcon({ size }) {
1179
+ return /* @__PURE__ */ jsxs6("svg", { width: size, height: size, viewBox: "0 0 20 20", fill: "none", "aria-hidden": "true", children: [
1180
+ /* @__PURE__ */ jsx5("path", { d: "M5 5L15 15", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" }),
1181
+ /* @__PURE__ */ jsx5("path", { d: "M15 5L5 15", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round" })
1182
+ ] });
1183
+ }
1184
+ function DatePicker({
1185
+ label,
1186
+ hint,
1187
+ error,
1188
+ controlSize = "md",
1189
+ value,
1190
+ defaultValue,
1191
+ onChange,
1192
+ mode = "date",
1193
+ format,
1194
+ allowPastDates = true,
1195
+ allowFutureDates = true,
1196
+ minDate,
1197
+ maxDate,
1198
+ minuteStep = 5,
1199
+ clearable = true,
1200
+ showPickerButton = true,
1201
+ isDateUnavailable,
1202
+ invalidDateMessage,
1203
+ unavailableDateMessage,
1204
+ pickerButtonLabel,
1205
+ clearButtonLabel,
1206
+ id,
1207
+ name,
1208
+ disabled,
1209
+ readOnly,
1210
+ required,
1211
+ style,
1212
+ className,
1213
+ placeholder,
1214
+ onBlur,
1215
+ onFocus,
1216
+ onKeyDown,
1217
+ ...rest
1218
+ }) {
1219
+ var _a;
1220
+ const { theme, focusRing } = useUiKitTheme();
1221
+ const controlMetrics = getControlMetrics(controlSize);
1222
+ const accessoryMetrics = ACCESSORY_METRICS_BY_SIZE[controlSize];
1223
+ const generatedIdRef = useRef2();
1224
+ const visibleInputRef = useRef2(null);
1225
+ const nativeInputRef = useRef2(null);
1226
+ const [internalError, setInternalError] = useState4();
1227
+ const resolvedFormat = (format == null ? void 0 : format.trim()) ? format : DEFAULT_FORMAT_BY_MODE[mode];
1228
+ const isControlled = value !== void 0;
1229
+ const nativePickerType = mode === "datetime" ? "datetime-local" : "date";
1230
+ if (!generatedIdRef.current) {
1231
+ generatedIdRef.current = `ss-date-picker-${Math.random().toString(36).slice(2, 10)}`;
1232
+ }
1233
+ const resolvedId = id != null ? id : generatedIdRef.current;
1234
+ const normalizedDefaultValue = useMemo3(() => {
1235
+ const parsedDefaultValue = parseDateValue(defaultValue, mode, resolvedFormat);
1236
+ return parsedDefaultValue ? toLocalInputValue(parsedDefaultValue, mode) : null;
1237
+ }, [defaultValue, mode, resolvedFormat]);
1238
+ const [uncontrolledValue, setUncontrolledValue] = useState4(normalizedDefaultValue);
1239
+ const committedDate = useMemo3(() => {
1240
+ const sourceValue = isControlled ? value : uncontrolledValue;
1241
+ return parseDateValue(sourceValue, mode, resolvedFormat);
1242
+ }, [isControlled, mode, resolvedFormat, uncontrolledValue, value]);
1243
+ const committedValue = committedDate ? toLocalInputValue(committedDate, mode) : null;
1244
+ const committedDisplayValue = committedDate ? formatDateValue(committedDate, resolvedFormat) : "";
1245
+ const [draftValue, setDraftValue] = useState4(committedDisplayValue);
1246
+ useEffect2(() => {
1247
+ setDraftValue(committedDisplayValue);
1248
+ setInternalError(void 0);
1249
+ }, [committedDisplayValue]);
1250
+ useEffect2(() => {
1251
+ if (!isControlled) {
1252
+ setUncontrolledValue((currentValue) => {
1253
+ if (currentValue == null) {
1254
+ return currentValue;
1255
+ }
1256
+ const parsedCurrentValue = parseDateValue(currentValue, mode, resolvedFormat);
1257
+ return parsedCurrentValue ? toLocalInputValue(parsedCurrentValue, mode) : null;
1258
+ });
1259
+ }
1260
+ }, [isControlled, mode, resolvedFormat]);
1261
+ const parsedMinDate = useMemo3(() => {
1262
+ const explicitMinDate = parseDateValue(minDate, mode, resolvedFormat);
1263
+ const guardedMinDate = allowPastDates ? null : normalizeDatePrecision(/* @__PURE__ */ new Date(), mode);
1264
+ return getLaterDate(explicitMinDate, guardedMinDate);
1265
+ }, [allowPastDates, minDate, mode, resolvedFormat]);
1266
+ const parsedMaxDate = useMemo3(() => {
1267
+ const explicitMaxDate = parseDateValue(maxDate, mode, resolvedFormat);
1268
+ const guardedMaxDate = allowFutureDates ? null : normalizeDatePrecision(/* @__PURE__ */ new Date(), mode);
1269
+ return getEarlierDate(explicitMaxDate, guardedMaxDate);
1270
+ }, [allowFutureDates, maxDate, mode, resolvedFormat]);
1271
+ const hasExternalError = error !== void 0 && error !== null && error !== "";
1272
+ const hasConfigurationConflict = Boolean(parsedMinDate && parsedMaxDate && parsedMinDate.getTime() > parsedMaxDate.getTime());
1273
+ const derivedError = hasConfigurationConflict ? "Current date rules do not allow any selection." : internalError;
1274
+ const resolvedError = hasExternalError ? error : derivedError;
1275
+ const hasAnyValue = draftValue.trim().length > 0 || Boolean(committedValue);
1276
+ const canOpenPicker = showPickerButton && !disabled && !readOnly && !hasConfigurationConflict;
1277
+ const canClear = clearable && !disabled && !readOnly && !required && hasAnyValue;
1278
+ const visibleButtonCount = Number(canOpenPicker) + Number(canClear);
1279
+ const trailingInset = visibleButtonCount > 0 ? Math.max(
1280
+ 0,
1281
+ accessoryMetrics.rightOffset + visibleButtonCount * accessoryMetrics.buttonSize + (visibleButtonCount - 1) * accessoryMetrics.clusterGap + accessoryMetrics.contentGap - controlMetrics.paddingX
1282
+ ) : 0;
1283
+ const getValidationMessage = (parsedDate) => {
1284
+ if (parsedMinDate && parsedDate.getTime() < parsedMinDate.getTime()) {
1285
+ return `Choose a value on or after ${formatDateValue(parsedMinDate, resolvedFormat)}.`;
1286
+ }
1287
+ if (parsedMaxDate && parsedDate.getTime() > parsedMaxDate.getTime()) {
1288
+ return `Choose a value on or before ${formatDateValue(parsedMaxDate, resolvedFormat)}.`;
1289
+ }
1290
+ if (mode === "datetime" && minuteStep > 1 && parsedDate.getMinutes() % minuteStep !== 0) {
1291
+ return `Minutes must use ${minuteStep}-minute intervals.`;
1292
+ }
1293
+ if (isDateUnavailable == null ? void 0 : isDateUnavailable(parsedDate)) {
1294
+ return unavailableDateMessage != null ? unavailableDateMessage : "This date is not available.";
1295
+ }
1296
+ return void 0;
1297
+ };
1298
+ const emitChange = (nextValue, context) => {
1299
+ onChange == null ? void 0 : onChange(nextValue, context);
1300
+ };
1301
+ const commitValue = (nextValue, reason) => {
1302
+ if (hasConfigurationConflict) {
1303
+ setInternalError("Current date rules do not allow any selection.");
1304
+ return false;
1305
+ }
1306
+ if (!nextValue) {
1307
+ if (!isControlled) {
1308
+ setUncontrolledValue(null);
1309
+ }
1310
+ setDraftValue("");
1311
+ setInternalError(void 0);
1312
+ emitChange(null, {
1313
+ reason,
1314
+ date: null,
1315
+ nativeValue: "",
1316
+ displayValue: ""
1317
+ });
1318
+ return true;
1319
+ }
1320
+ const parsedDate = parseHtmlDateLikeValue(nextValue);
1321
+ if (!parsedDate) {
1322
+ setInternalError(invalidDateMessage != null ? invalidDateMessage : `Enter a valid value using ${resolvedFormat}.`);
1323
+ return false;
1324
+ }
1325
+ const normalizedDate = normalizeDatePrecision(parsedDate, mode);
1326
+ const validationMessage = getValidationMessage(normalizedDate);
1327
+ if (validationMessage) {
1328
+ setInternalError(validationMessage);
1329
+ return false;
1330
+ }
1331
+ const normalizedValue = toLocalInputValue(normalizedDate, mode);
1332
+ const displayValue = formatDateValue(normalizedDate, resolvedFormat);
1333
+ if (!isControlled) {
1334
+ setUncontrolledValue(normalizedValue);
1335
+ }
1336
+ setDraftValue(displayValue);
1337
+ setInternalError(void 0);
1338
+ emitChange(normalizedValue, {
1339
+ reason,
1340
+ date: normalizedDate,
1341
+ nativeValue: normalizedValue,
1342
+ displayValue
1343
+ });
1344
+ return true;
1345
+ };
1346
+ const commitDraftValue = () => {
1347
+ var _a2, _b;
1348
+ const trimmedDraftValue = draftValue.trim();
1349
+ if (!trimmedDraftValue) {
1350
+ return commitValue(null, "clear");
1351
+ }
1352
+ const parsedDraftDate = (_b = (_a2 = parseFormattedDateValue(trimmedDraftValue, resolvedFormat, mode)) != null ? _a2 : parseHtmlDateLikeValue(trimmedDraftValue)) != null ? _b : parseDateValue(trimmedDraftValue, mode, resolvedFormat);
1353
+ if (!parsedDraftDate) {
1354
+ setInternalError(invalidDateMessage != null ? invalidDateMessage : `Enter a valid value using ${resolvedFormat}.`);
1355
+ return false;
1356
+ }
1357
+ return commitValue(toLocalInputValue(parsedDraftDate, mode), "input");
1358
+ };
1359
+ const openNativePicker = () => {
1360
+ var _a2, _b;
1361
+ if (!canOpenPicker || !nativeInputRef.current) {
1362
+ return;
1363
+ }
1364
+ const parsedDraftDate = draftValue.trim() ? (_a2 = parseFormattedDateValue(draftValue, resolvedFormat, mode)) != null ? _a2 : parseHtmlDateLikeValue(draftValue) : null;
1365
+ if (parsedDraftDate) {
1366
+ nativeInputRef.current.value = toLocalInputValue(parsedDraftDate, mode);
1367
+ }
1368
+ const pickerInput = nativeInputRef.current;
1369
+ try {
1370
+ if (pickerInput.showPicker) {
1371
+ pickerInput.showPicker();
1372
+ return;
1373
+ }
1374
+ pickerInput.focus();
1375
+ } catch {
1376
+ (_b = visibleInputRef.current) == null ? void 0 : _b.focus();
1377
+ }
1378
+ };
1379
+ const inputStyle = {
1380
+ width: "100%",
1381
+ boxSizing: "border-box",
1382
+ height: controlMetrics.height,
1383
+ borderRadius: 16,
1384
+ border: `1px solid ${resolvedError ? theme.colors.negative : withAlpha(theme.colors.textLight, 0.5)}`,
1385
+ backgroundColor: theme.colors.surface,
1386
+ color: theme.colors.text,
1387
+ cursor: disabled ? "not-allowed" : readOnly ? "default" : "text",
1388
+ opacity: disabled ? 0.7 : 1,
1389
+ padding: getTextInputPadding(controlSize, { trailingInset }),
1390
+ outline: "none",
1391
+ fontSize: controlMetrics.fontSize,
1392
+ lineHeight: controlMetrics.lineHeight,
1393
+ boxShadow: resolvedError ? `0 0 0 3px ${withAlpha(theme.colors.negative, 0.12)}` : `0 0 0 0 ${focusRing}`,
1394
+ transition: "border-color 160ms ease, box-shadow 160ms ease, background-color 160ms ease",
1395
+ ...style
1396
+ };
1397
+ const accessoryButtonStyle = {
1398
+ width: accessoryMetrics.buttonSize,
1399
+ height: accessoryMetrics.buttonSize,
1400
+ border: "none",
1401
+ padding: 0,
1402
+ margin: 0,
1403
+ display: "inline-flex",
1404
+ alignItems: "center",
1405
+ justifyContent: "center",
1406
+ borderRadius: 999,
1407
+ backgroundColor: "transparent",
1408
+ color: theme.colors.textLight,
1409
+ cursor: disabled || readOnly ? "not-allowed" : "pointer",
1410
+ opacity: disabled ? 0.5 : 1
1411
+ };
1412
+ const input = /* @__PURE__ */ jsxs6("div", { style: { position: "relative", width: "100%" }, children: [
1413
+ /* @__PURE__ */ jsx5(
1414
+ "input",
1415
+ {
1416
+ ...rest,
1417
+ ref: visibleInputRef,
1418
+ id: resolvedId,
1419
+ className,
1420
+ type: "text",
1421
+ value: draftValue,
1422
+ disabled,
1423
+ readOnly,
1424
+ required,
1425
+ placeholder: placeholder != null ? placeholder : resolvedFormat,
1426
+ autoComplete: (_a = rest.autoComplete) != null ? _a : "off",
1427
+ spellCheck: false,
1428
+ "aria-invalid": Boolean(resolvedError),
1429
+ onChange: (event) => {
1430
+ setDraftValue(event.target.value);
1431
+ setInternalError(void 0);
1432
+ },
1433
+ onFocus: (event) => {
1434
+ setInternalError(void 0);
1435
+ onFocus == null ? void 0 : onFocus(event);
1436
+ },
1437
+ onBlur: (event) => {
1438
+ commitDraftValue();
1439
+ onBlur == null ? void 0 : onBlur(event);
1440
+ },
1441
+ onKeyDown: (event) => {
1442
+ onKeyDown == null ? void 0 : onKeyDown(event);
1443
+ if (event.defaultPrevented) {
1444
+ return;
1445
+ }
1446
+ if (event.key === "Enter") {
1447
+ event.preventDefault();
1448
+ commitDraftValue();
1449
+ return;
1450
+ }
1451
+ if (event.key === "Escape") {
1452
+ event.preventDefault();
1453
+ setDraftValue(committedDisplayValue);
1454
+ setInternalError(void 0);
1455
+ }
1456
+ },
1457
+ style: inputStyle
1458
+ }
1459
+ ),
1460
+ /* @__PURE__ */ jsx5(
1461
+ "input",
1462
+ {
1463
+ ref: nativeInputRef,
1464
+ tabIndex: -1,
1465
+ "aria-hidden": "true",
1466
+ name,
1467
+ type: nativePickerType,
1468
+ value: committedValue != null ? committedValue : "",
1469
+ min: parsedMinDate ? toLocalInputValue(parsedMinDate, mode) : void 0,
1470
+ max: parsedMaxDate ? toLocalInputValue(parsedMaxDate, mode) : void 0,
1471
+ step: mode === "datetime" ? Math.max(1, minuteStep) * 60 : void 0,
1472
+ disabled: disabled || readOnly || hasConfigurationConflict,
1473
+ onChange: (event) => {
1474
+ commitValue(event.target.value || null, "picker");
1475
+ },
1476
+ style: {
1477
+ position: "absolute",
1478
+ width: 1,
1479
+ height: 1,
1480
+ padding: 0,
1481
+ margin: -1,
1482
+ overflow: "hidden",
1483
+ clip: "rect(0, 0, 0, 0)",
1484
+ whiteSpace: "nowrap",
1485
+ border: 0,
1486
+ opacity: 0,
1487
+ pointerEvents: "none"
1488
+ }
1489
+ }
1490
+ ),
1491
+ visibleButtonCount > 0 ? /* @__PURE__ */ jsxs6(
1492
+ "div",
1493
+ {
1494
+ style: {
1495
+ position: "absolute",
1496
+ top: "50%",
1497
+ right: accessoryMetrics.rightOffset,
1498
+ transform: "translateY(-50%)",
1499
+ display: "inline-flex",
1500
+ alignItems: "center",
1501
+ gap: accessoryMetrics.clusterGap
1502
+ },
1503
+ children: [
1504
+ canClear ? /* @__PURE__ */ jsx5(
1505
+ "button",
1506
+ {
1507
+ type: "button",
1508
+ "aria-label": clearButtonLabel != null ? clearButtonLabel : "Clear date",
1509
+ disabled: disabled || readOnly,
1510
+ onMouseDown: (event) => {
1511
+ event.preventDefault();
1512
+ },
1513
+ onClick: () => {
1514
+ var _a2;
1515
+ commitValue(null, "clear");
1516
+ (_a2 = visibleInputRef.current) == null ? void 0 : _a2.focus();
1517
+ },
1518
+ style: accessoryButtonStyle,
1519
+ children: /* @__PURE__ */ jsx5(ClearIcon, { size: accessoryMetrics.iconSize })
1520
+ }
1521
+ ) : null,
1522
+ canOpenPicker ? /* @__PURE__ */ jsx5(
1523
+ "button",
1524
+ {
1525
+ type: "button",
1526
+ "aria-label": pickerButtonLabel != null ? pickerButtonLabel : mode === "datetime" ? "Open date and time picker" : "Open date picker",
1527
+ disabled: disabled || readOnly || hasConfigurationConflict,
1528
+ onMouseDown: (event) => {
1529
+ event.preventDefault();
1530
+ },
1531
+ onClick: openNativePicker,
1532
+ style: accessoryButtonStyle,
1533
+ children: /* @__PURE__ */ jsx5(CalendarIcon, { size: accessoryMetrics.iconSize })
1534
+ }
1535
+ ) : null
1536
+ ]
1537
+ }
1538
+ ) : null
1539
+ ] });
1540
+ return /* @__PURE__ */ jsx5(
1541
+ ControlFrame,
1542
+ {
1543
+ label,
1544
+ hint,
1545
+ error: resolvedError,
1546
+ htmlFor: resolvedId,
1547
+ required,
1548
+ children: input
1549
+ }
1550
+ );
686
1551
  }
687
1552
 
688
1553
  // src/components/Select.tsx
689
1554
  import {
690
1555
  Children,
691
1556
  isValidElement,
692
- useEffect,
693
- useId,
694
- useRef,
695
- useState as useState3
1557
+ useEffect as useEffect3,
1558
+ useId as useId2,
1559
+ useRef as useRef3,
1560
+ useState as useState5
696
1561
  } from "react";
697
- import { withAlpha as withAlpha5 } from "smartsell-sales-sdk";
698
- import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs5 } from "react/jsx-runtime";
1562
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs7 } from "react/jsx-runtime";
699
1563
  var MENU_OFFSET = 8;
700
1564
  var MENU_MAX_HEIGHT = 280;
701
1565
  var getOptionPadding = (size) => {
@@ -815,7 +1679,6 @@ function filterSelectGroups(groups, query) {
815
1679
  })).filter((group) => group.options.length > 0);
816
1680
  }
817
1681
  function Select({
818
- sdk,
819
1682
  label,
820
1683
  hint,
821
1684
  error,
@@ -839,8 +1702,8 @@ function Select({
839
1702
  ...rest
840
1703
  }) {
841
1704
  var _a, _b, _c, _d, _e, _f, _g, _h;
842
- const { theme, borderSoft, mutedText, surfaceMuted, surfaceRaised } = useUiKitTheme(sdk);
843
- const generatedId = useId().replace(/:/g, "");
1705
+ const { theme, mutedText, surfaceRaised } = useUiKitTheme();
1706
+ const generatedId = useId2().replace(/:/g, "");
844
1707
  const resolvedId = id != null ? id : `ss-select-${generatedId}`;
845
1708
  const isMultiSelect = Boolean(isMulti || multiple);
846
1709
  const hasFilter = Boolean(isFilterable);
@@ -849,17 +1712,17 @@ function Select({
849
1712
  const enabledOptions = flatOptions.filter((option) => !option.disabled);
850
1713
  const isControlled = value !== void 0;
851
1714
  const fallbackValues = defaultValue !== void 0 ? normalizeSelectValues(defaultValue) : isMultiSelect ? [] : ((_a = enabledOptions[0]) == null ? void 0 : _a.value) ? [enabledOptions[0].value] : [];
852
- const [uncontrolledValues, setUncontrolledValues] = useState3(fallbackValues);
853
- const [isOpen, setIsOpen] = useState3(false);
854
- const [filterQuery, setFilterQuery] = useState3("");
855
- const [menuPlacement, setMenuPlacement] = useState3("bottom");
856
- const [isPlacementResolved, setIsPlacementResolved] = useState3(false);
857
- const [highlightedValue, setHighlightedValue] = useState3((_d = (_c = fallbackValues[0]) != null ? _c : (_b = enabledOptions[0]) == null ? void 0 : _b.value) != null ? _d : "");
858
- const shellRef = useRef(null);
859
- const buttonRef = useRef(null);
860
- const menuRef = useRef(null);
861
- const searchInputRef = useRef(null);
862
- const hiddenSelectRef = useRef(null);
1715
+ const [uncontrolledValues, setUncontrolledValues] = useState5(fallbackValues);
1716
+ const [isOpen, setIsOpen] = useState5(false);
1717
+ const [filterQuery, setFilterQuery] = useState5("");
1718
+ const [menuPlacement, setMenuPlacement] = useState5("bottom");
1719
+ const [isPlacementResolved, setIsPlacementResolved] = useState5(false);
1720
+ const [highlightedValue, setHighlightedValue] = useState5((_d = (_c = fallbackValues[0]) != null ? _c : (_b = enabledOptions[0]) == null ? void 0 : _b.value) != null ? _d : "");
1721
+ const shellRef = useRef3(null);
1722
+ const buttonRef = useRef3(null);
1723
+ const menuRef = useRef3(null);
1724
+ const searchInputRef = useRef3(null);
1725
+ const hiddenSelectRef = useRef3(null);
863
1726
  const selectedValues = isControlled ? normalizeSelectValues(value) : uncontrolledValues;
864
1727
  const selectedValue = (_e = selectedValues[0]) != null ? _e : "";
865
1728
  const selectedOptions = flatOptions.filter((option) => selectedValues.includes(option.value));
@@ -875,16 +1738,16 @@ function Select({
875
1738
  const indicatorOffset = getSelectIndicatorOffset(controlSize);
876
1739
  const controlMetrics = getControlMetrics(controlSize);
877
1740
  const listboxId = `${resolvedId}-listbox`;
878
- const scrollbarThumbColor = withAlpha5(theme.colors.onSurface, 0.22);
879
- const scrollbarThumbHoverColor = withAlpha5(theme.colors.onSurface, 0.32);
1741
+ const scrollbarThumbColor = withAlpha(theme.colors.onSurface, 0.22);
1742
+ const scrollbarThumbHoverColor = withAlpha(theme.colors.onSurface, 0.32);
880
1743
  const highlightedOption = (_h = visibleOptions.find((option) => option.value === highlightedValue)) != null ? _h : null;
881
- const optionHoverBackground = withAlpha5(theme.colors.primary, 1);
882
- const optionSelectedBackground = withAlpha5(theme.colors.primary, 1);
883
- const triggerShadow = error ? `0 0 0 3px ${withAlpha5(theme.colors.negative, 0.12)}` : "none";
1744
+ const optionHoverBackground = withAlpha(theme.colors.primary, 1);
1745
+ const optionSelectedBackground = withAlpha(theme.colors.primary, 1);
1746
+ const triggerShadow = error ? `0 0 0 3px ${withAlpha(theme.colors.negative, 0.12)}` : "none";
884
1747
  const buttonPassthroughProps = Object.fromEntries(
885
1748
  Object.entries(rest).filter(([key]) => key.startsWith("aria-") || key.startsWith("data-"))
886
1749
  );
887
- useEffect(() => {
1750
+ useEffect3(() => {
888
1751
  var _a2, _b2, _c2, _d2;
889
1752
  if (isControlled) {
890
1753
  return;
@@ -901,7 +1764,7 @@ function Select({
901
1764
  setUncontrolledValues(nextValues);
902
1765
  setHighlightedValue((_d2 = (_c2 = nextValues[0]) != null ? _c2 : (_b2 = enabledOptions[0]) == null ? void 0 : _b2.value) != null ? _d2 : "");
903
1766
  }, [children, defaultValue, enabledOptions, flatOptions, isControlled, isMultiSelect, uncontrolledValues]);
904
- useEffect(() => {
1767
+ useEffect3(() => {
905
1768
  var _a2, _b2, _c2;
906
1769
  if (!isOpen) {
907
1770
  setMenuPlacement("bottom");
@@ -911,14 +1774,14 @@ function Select({
911
1774
  const nextHighlightedValue = (_c2 = (_b2 = [...selectedValues].reverse().find((currentValue) => visibleEnabledValues.includes(currentValue))) != null ? _b2 : (_a2 = visibleEnabledOptions[0]) == null ? void 0 : _a2.value) != null ? _c2 : "";
912
1775
  setHighlightedValue(nextHighlightedValue);
913
1776
  }, [isOpen, selectedValuesKey, visibleEnabledValuesKey]);
914
- useEffect(() => {
1777
+ useEffect3(() => {
915
1778
  var _a2;
916
1779
  if (!isOpen || !hasFilter) {
917
1780
  return;
918
1781
  }
919
1782
  (_a2 = searchInputRef.current) == null ? void 0 : _a2.focus();
920
1783
  }, [hasFilter, isOpen]);
921
- useEffect(() => {
1784
+ useEffect3(() => {
922
1785
  if (!isOpen) {
923
1786
  return;
924
1787
  }
@@ -943,13 +1806,13 @@ function Select({
943
1806
  window.cancelAnimationFrame(frameId);
944
1807
  };
945
1808
  }, [isOpen, visibleOptions.length]);
946
- useEffect(() => {
1809
+ useEffect3(() => {
947
1810
  if (isOpen) {
948
1811
  return;
949
1812
  }
950
1813
  setFilterQuery("");
951
1814
  }, [isOpen]);
952
- useEffect(() => {
1815
+ useEffect3(() => {
953
1816
  if (!isOpen) {
954
1817
  return;
955
1818
  }
@@ -965,7 +1828,7 @@ function Select({
965
1828
  document.removeEventListener("pointerdown", handlePointerDown);
966
1829
  };
967
1830
  }, [isOpen]);
968
- useEffect(() => {
1831
+ useEffect3(() => {
969
1832
  var _a2;
970
1833
  if (isControlled) {
971
1834
  return;
@@ -1064,7 +1927,7 @@ function Select({
1064
1927
  const hasSomeVisibleSelected = visibleSelectedCount > 0 && visibleSelectedCount < visibleEnabledValues.length;
1065
1928
  const hasAllVisibleSelected = visibleEnabledValues.length > 0 && visibleSelectedCount === visibleEnabledValues.length;
1066
1929
  const canToggleVisibleSelection = !disabled && visibleEnabledValues.length > 0;
1067
- const bulkToggleControl = isMultiSelect ? /* @__PURE__ */ jsx4(
1930
+ const bulkToggleControl = isMultiSelect ? /* @__PURE__ */ jsx6(
1068
1931
  "button",
1069
1932
  {
1070
1933
  type: "button",
@@ -1085,39 +1948,27 @@ function Select({
1085
1948
  height: 20,
1086
1949
  padding: 0,
1087
1950
  margin: 0,
1088
- borderRadius: 999,
1089
- border: `1.5px solid ${hasAllVisibleSelected || hasSomeVisibleSelected ? theme.colors.secondary : withAlpha5(theme.colors.onSurface, 0.22)}`,
1090
- backgroundColor: hasAllVisibleSelected || hasSomeVisibleSelected ? theme.colors.secondary : theme.colors.surface,
1091
1951
  display: "inline-flex",
1092
1952
  alignItems: "center",
1093
1953
  justifyContent: "center",
1094
1954
  flexShrink: 0,
1955
+ border: "none",
1956
+ background: "transparent",
1095
1957
  cursor: canToggleVisibleSelection ? "pointer" : "not-allowed",
1096
1958
  opacity: canToggleVisibleSelection ? 1 : 0.45
1097
1959
  },
1098
- children: hasAllVisibleSelected ? /* @__PURE__ */ jsx4(
1099
- "span",
1100
- {
1101
- "aria-hidden": "true",
1102
- style: {
1103
- width: 8,
1104
- height: 8,
1105
- borderRadius: 999,
1106
- backgroundColor: theme.colors.surface
1107
- }
1108
- }
1109
- ) : hasSomeVisibleSelected ? /* @__PURE__ */ jsx4(
1110
- "span",
1960
+ children: /* @__PURE__ */ jsx6(
1961
+ CheckboxIndicator,
1111
1962
  {
1112
- "aria-hidden": "true",
1113
- style: {
1114
- width: 8,
1115
- height: 2,
1116
- borderRadius: 999,
1117
- backgroundColor: theme.colors.surface
1118
- }
1963
+ checked: hasAllVisibleSelected,
1964
+ indeterminate: hasSomeVisibleSelected,
1965
+ disabled: !canToggleVisibleSelection,
1966
+ checkedColor: theme.colors.secondary,
1967
+ iconColor: theme.colors.surface,
1968
+ uncheckedBorderColor: withAlpha(theme.colors.onSurface, 0.22),
1969
+ uncheckedBackgroundColor: theme.colors.surface
1119
1970
  }
1120
- ) : null
1971
+ )
1121
1972
  }
1122
1973
  ) : null;
1123
1974
  const moveHighlight = (direction) => {
@@ -1238,8 +2089,8 @@ function Select({
1238
2089
  setIsOpen(false);
1239
2090
  }
1240
2091
  };
1241
- const select = /* @__PURE__ */ jsxs5("div", { ref: shellRef, style: { position: "relative", width: "100%" }, children: [
1242
- /* @__PURE__ */ jsxs5(
2092
+ const select = /* @__PURE__ */ jsxs7("div", { ref: shellRef, style: { position: "relative", width: "100%" }, children: [
2093
+ /* @__PURE__ */ jsxs7(
1243
2094
  "button",
1244
2095
  {
1245
2096
  ...buttonPassthroughProps,
@@ -1266,7 +2117,7 @@ function Select({
1266
2117
  boxSizing: "border-box",
1267
2118
  height: controlMetrics.height,
1268
2119
  borderRadius: 16,
1269
- border: `1px solid ${error ? theme.colors.negative : withAlpha5(theme.colors.textLight, 0.5)}`,
2120
+ border: `1px solid ${error ? theme.colors.negative : withAlpha(theme.colors.textLight, 0.5)}`,
1270
2121
  backgroundColor: theme.colors.surface,
1271
2122
  color: displayLabel ? theme.colors.onSurface : mutedText,
1272
2123
  cursor: disabled ? "not-allowed" : "pointer",
@@ -1286,7 +2137,7 @@ function Select({
1286
2137
  ...style
1287
2138
  },
1288
2139
  children: [
1289
- /* @__PURE__ */ jsx4(
2140
+ /* @__PURE__ */ jsx6(
1290
2141
  "span",
1291
2142
  {
1292
2143
  style: {
@@ -1300,7 +2151,7 @@ function Select({
1300
2151
  children: displayContent
1301
2152
  }
1302
2153
  ),
1303
- /* @__PURE__ */ jsx4(
2154
+ /* @__PURE__ */ jsx6(
1304
2155
  "span",
1305
2156
  {
1306
2157
  "aria-hidden": "true",
@@ -1310,14 +2161,14 @@ function Select({
1310
2161
  top: "50%",
1311
2162
  transform: `translateY(-50%) rotate(${isOpen ? 180 : 0}deg)`,
1312
2163
  transformOrigin: "center",
1313
- color: disabled ? withAlpha5(theme.colors.onSurface, 0.42) : mutedText,
2164
+ color: disabled ? withAlpha(theme.colors.onSurface, 0.42) : mutedText,
1314
2165
  display: "flex",
1315
2166
  alignItems: "center",
1316
2167
  justifyContent: "center",
1317
2168
  pointerEvents: "none",
1318
2169
  transition: "transform 160ms ease, color 160ms ease"
1319
2170
  },
1320
- children: /* @__PURE__ */ jsx4("svg", { width: "18", height: "18", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx4(
2171
+ children: /* @__PURE__ */ jsx6("svg", { width: "18", height: "18", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx6(
1321
2172
  "path",
1322
2173
  {
1323
2174
  d: "M5.75 7.75L10 12l4.25-4.25",
@@ -1332,7 +2183,7 @@ function Select({
1332
2183
  ]
1333
2184
  }
1334
2185
  ),
1335
- /* @__PURE__ */ jsx4(
2186
+ /* @__PURE__ */ jsx6(
1336
2187
  "select",
1337
2188
  {
1338
2189
  ...rest,
@@ -1359,8 +2210,8 @@ function Select({
1359
2210
  children
1360
2211
  }
1361
2212
  ),
1362
- isOpen ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
1363
- /* @__PURE__ */ jsx4("style", { children: `
2213
+ isOpen ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
2214
+ /* @__PURE__ */ jsx6("style", { children: `
1364
2215
  #${listboxId} {
1365
2216
  scrollbar-width: thin;
1366
2217
  scrollbar-color: ${scrollbarThumbColor} transparent;
@@ -1386,7 +2237,7 @@ function Select({
1386
2237
  background-clip: padding-box;
1387
2238
  }
1388
2239
  ` }),
1389
- /* @__PURE__ */ jsxs5(
2240
+ /* @__PURE__ */ jsxs7(
1390
2241
  "div",
1391
2242
  {
1392
2243
  ref: menuRef,
@@ -1401,7 +2252,7 @@ function Select({
1401
2252
  overflow: "hidden",
1402
2253
  boxSizing: "border-box",
1403
2254
  borderRadius: 20,
1404
- border: `1px solid ${withAlpha5(theme.colors.textLight, 0.5)}`,
2255
+ border: `1px solid ${withAlpha(theme.colors.textLight, 0.5)}`,
1405
2256
  backgroundColor: surfaceRaised,
1406
2257
  // boxShadow: `0 10px 24px ${withAlpha(theme.colors.onSurface, 0.08)}`,
1407
2258
  padding: 8,
@@ -1412,7 +2263,7 @@ function Select({
1412
2263
  gap: 4
1413
2264
  },
1414
2265
  children: [
1415
- hasFilter ? /* @__PURE__ */ jsxs5(
2266
+ hasFilter ? /* @__PURE__ */ jsxs7(
1416
2267
  "div",
1417
2268
  {
1418
2269
  style: {
@@ -1421,12 +2272,12 @@ function Select({
1421
2272
  justifyContent: "flex-start",
1422
2273
  gap: 8,
1423
2274
  padding: "4px 4px 10px",
1424
- borderBottom: `1px solid ${withAlpha5(theme.colors.onSurface, 0.08)}`,
2275
+ borderBottom: `1px solid ${withAlpha(theme.colors.onSurface, 0.08)}`,
1425
2276
  flexShrink: 0
1426
2277
  },
1427
2278
  children: [
1428
2279
  bulkToggleControl,
1429
- /* @__PURE__ */ jsx4(
2280
+ /* @__PURE__ */ jsx6(
1430
2281
  "input",
1431
2282
  {
1432
2283
  ref: searchInputRef,
@@ -1444,7 +2295,7 @@ function Select({
1444
2295
  style: {
1445
2296
  flex: "1 1 auto",
1446
2297
  width: "100%",
1447
- border: `1px solid ${withAlpha5(theme.colors.textLight, 0.5)}`,
2298
+ border: `1px solid ${withAlpha(theme.colors.textLight, 0.5)}`,
1448
2299
  backgroundColor: theme.colors.surface,
1449
2300
  padding: "8px 12px",
1450
2301
  borderRadius: 12,
@@ -1459,7 +2310,7 @@ function Select({
1459
2310
  )
1460
2311
  ]
1461
2312
  }
1462
- ) : isMultiSelect ? /* @__PURE__ */ jsx4(
2313
+ ) : isMultiSelect ? /* @__PURE__ */ jsx6(
1463
2314
  "div",
1464
2315
  {
1465
2316
  style: {
@@ -1467,13 +2318,13 @@ function Select({
1467
2318
  alignItems: "center",
1468
2319
  justifyContent: "flex-start",
1469
2320
  padding: "4px 4px 10px",
1470
- borderBottom: `1px solid ${withAlpha5(theme.colors.onSurface, 0.08)}`,
2321
+ borderBottom: `1px solid ${withAlpha(theme.colors.onSurface, 0.08)}`,
1471
2322
  flexShrink: 0
1472
2323
  },
1473
2324
  children: bulkToggleControl
1474
2325
  }
1475
2326
  ) : null,
1476
- /* @__PURE__ */ jsx4(
2327
+ /* @__PURE__ */ jsx6(
1477
2328
  "div",
1478
2329
  {
1479
2330
  id: listboxId,
@@ -1486,7 +2337,7 @@ function Select({
1486
2337
  minHeight: 0,
1487
2338
  flex: "1 1 auto"
1488
2339
  },
1489
- children: visibleGroups.length === 0 ? /* @__PURE__ */ jsx4(
2340
+ children: visibleGroups.length === 0 ? /* @__PURE__ */ jsx6(
1490
2341
  "div",
1491
2342
  {
1492
2343
  style: {
@@ -1497,7 +2348,7 @@ function Select({
1497
2348
  },
1498
2349
  children: "No options found."
1499
2350
  }
1500
- ) : visibleGroups.map((group) => /* @__PURE__ */ jsxs5(
2351
+ ) : visibleGroups.map((group) => /* @__PURE__ */ jsxs7(
1501
2352
  "div",
1502
2353
  {
1503
2354
  style: {
@@ -1507,7 +2358,7 @@ function Select({
1507
2358
  marginTop: group.label ? 4 : 0
1508
2359
  },
1509
2360
  children: [
1510
- group.label ? /* @__PURE__ */ jsx4(
2361
+ group.label ? /* @__PURE__ */ jsx6(
1511
2362
  "span",
1512
2363
  {
1513
2364
  style: {
@@ -1525,7 +2376,7 @@ function Select({
1525
2376
  const isSelected = selectedValues.includes(option.value);
1526
2377
  const isHighlighted = option.value === highlightedValue;
1527
2378
  const isActive = isSelected || isHighlighted;
1528
- return /* @__PURE__ */ jsxs5(
2379
+ return /* @__PURE__ */ jsxs7(
1529
2380
  "div",
1530
2381
  {
1531
2382
  role: "option",
@@ -1555,13 +2406,13 @@ function Select({
1555
2406
  borderRadius: 14,
1556
2407
  padding: getOptionPadding(controlSize),
1557
2408
  cursor: option.disabled ? "not-allowed" : "pointer",
1558
- color: option.disabled ? withAlpha5(theme.colors.onSurface, 0.38) : isActive ? theme.colors.onPrimary : theme.colors.onSurface,
2409
+ color: option.disabled ? withAlpha(theme.colors.onSurface, 0.38) : isActive ? theme.colors.onPrimary : theme.colors.onSurface,
1559
2410
  backgroundColor: isSelected ? optionSelectedBackground : isHighlighted ? optionHoverBackground : "transparent",
1560
2411
  fontWeight: isSelected ? 700 : 500,
1561
2412
  transition: "background-color 140ms ease, color 140ms ease"
1562
2413
  },
1563
2414
  children: [
1564
- /* @__PURE__ */ jsxs5(
2415
+ /* @__PURE__ */ jsxs7(
1565
2416
  "span",
1566
2417
  {
1567
2418
  style: {
@@ -1572,23 +2423,19 @@ function Select({
1572
2423
  minWidth: 0
1573
2424
  },
1574
2425
  children: [
1575
- isMultiSelect ? /* @__PURE__ */ jsx4(
1576
- "span",
2426
+ isMultiSelect ? /* @__PURE__ */ jsx6(
2427
+ CheckboxIndicator,
1577
2428
  {
1578
- "aria-hidden": "true",
1579
- style: {
1580
- width: 10,
1581
- height: 10,
1582
- borderRadius: 999,
1583
- flexShrink: 0,
1584
- border: `1.5px solid ${isSelected ? theme.colors.secondary : "currentColor"}`,
1585
- backgroundColor: isSelected ? theme.colors.secondary : "transparent",
1586
- opacity: option.disabled ? 0.45 : 1,
1587
- transition: "background-color 140ms ease, border-color 140ms ease, opacity 140ms ease"
1588
- }
2429
+ checked: isSelected,
2430
+ disabled: option.disabled,
2431
+ size: 16,
2432
+ checkedColor: isActive ? theme.colors.onPrimary : theme.colors.primary,
2433
+ iconColor: isActive ? theme.colors.primary : theme.colors.onPrimary,
2434
+ uncheckedBorderColor: isActive ? theme.colors.onPrimary : withAlpha(theme.colors.onSurface, 0.26),
2435
+ uncheckedBackgroundColor: "transparent"
1589
2436
  }
1590
2437
  ) : null,
1591
- /* @__PURE__ */ jsx4(
2438
+ /* @__PURE__ */ jsx6(
1592
2439
  "span",
1593
2440
  {
1594
2441
  style: {
@@ -1605,7 +2452,7 @@ function Select({
1605
2452
  ]
1606
2453
  }
1607
2454
  ),
1608
- isSelected ? /* @__PURE__ */ jsx4(
2455
+ !isMultiSelect && isSelected ? /* @__PURE__ */ jsx6(
1609
2456
  "span",
1610
2457
  {
1611
2458
  "aria-hidden": "true",
@@ -1616,7 +2463,7 @@ function Select({
1616
2463
  color: theme.colors.primary,
1617
2464
  flexShrink: 0
1618
2465
  },
1619
- children: /* @__PURE__ */ jsx4("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx4(
2466
+ children: /* @__PURE__ */ jsx6("svg", { width: "16", height: "16", viewBox: "0 0 20 20", fill: "none", children: /* @__PURE__ */ jsx6(
1620
2467
  "path",
1621
2468
  {
1622
2469
  d: "M5.75 10.25L8.5 13l5.75-6",
@@ -1644,10 +2491,9 @@ function Select({
1644
2491
  )
1645
2492
  ] }) : null
1646
2493
  ] });
1647
- return /* @__PURE__ */ jsx4(
2494
+ return /* @__PURE__ */ jsx6(
1648
2495
  ControlFrame,
1649
2496
  {
1650
- sdk,
1651
2497
  label,
1652
2498
  hint,
1653
2499
  error,
@@ -1660,15 +2506,13 @@ function Select({
1660
2506
  }
1661
2507
 
1662
2508
  // src/components/Textarea.tsx
1663
- import { withAlpha as withAlpha6 } from "smartsell-sales-sdk";
1664
- import { jsx as jsx5 } from "react/jsx-runtime";
2509
+ import { jsx as jsx7 } from "react/jsx-runtime";
1665
2510
  var getPadding = (size) => {
1666
2511
  if (size === "sm") return "10px 12px";
1667
2512
  if (size === "lg") return "16px 18px";
1668
2513
  return "13px 16px";
1669
2514
  };
1670
2515
  function Textarea({
1671
- sdk,
1672
2516
  label,
1673
2517
  hint,
1674
2518
  error,
@@ -1679,9 +2523,9 @@ function Textarea({
1679
2523
  rows = 5,
1680
2524
  ...rest
1681
2525
  }) {
1682
- const { theme, borderSoft, focusRing, surfaceMuted } = useUiKitTheme(sdk);
2526
+ const { theme, focusRing } = useUiKitTheme();
1683
2527
  const textareaStyle = {
1684
- border: `1px solid ${error ? theme.colors.negative : withAlpha6(theme.colors.textLight, 0.5)}`,
2528
+ border: `1px solid ${error ? theme.colors.negative : withAlpha(theme.colors.textLight, 0.5)}`,
1685
2529
  backgroundColor: theme.colors.surface,
1686
2530
  color: theme.colors.text,
1687
2531
  cursor: disabled ? "not-allowed" : "text",
@@ -1691,18 +2535,20 @@ function Textarea({
1691
2535
  borderRadius: 16,
1692
2536
  padding: getPadding(controlSize),
1693
2537
  outline: "none",
1694
- boxShadow: error ? `0 0 0 3px ${withAlpha6(theme.colors.negative, 0.12)}` : `0 0 0 0 ${focusRing}`,
2538
+ boxShadow: error ? `0 0 0 3px ${withAlpha(theme.colors.negative, 0.12)}` : `0 0 0 0 ${focusRing}`,
1695
2539
  transition: "border-color 160ms ease, box-shadow 160ms ease, background-color 160ms ease",
1696
2540
  resize: "vertical",
1697
2541
  ...style
1698
2542
  };
1699
- const textarea = /* @__PURE__ */ jsx5("textarea", { ...rest, id, disabled, rows, style: textareaStyle });
1700
- return /* @__PURE__ */ jsx5(ControlFrame, { sdk, label, hint, error, htmlFor: id, required: rest.required, children: textarea });
2543
+ const textarea = /* @__PURE__ */ jsx7("textarea", { ...rest, id, disabled, rows, style: textareaStyle });
2544
+ return /* @__PURE__ */ jsx7(ControlFrame, { label, hint, error, htmlFor: id, required: rest.required, children: textarea });
1701
2545
  }
1702
2546
  export {
1703
2547
  Button,
1704
2548
  Card,
2549
+ Checkbox,
1705
2550
  ComposableModal,
2551
+ DatePicker,
1706
2552
  Input,
1707
2553
  Modal,
1708
2554
  Select,