cekat-ui 1.3.13 → 1.3.14

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.d.mts CHANGED
@@ -5,6 +5,7 @@ import { ClassValue } from 'clsx';
5
5
  import { ColumnProps as ColumnProps_2 } from 'react-aria-components';
6
6
  import { ColumnResizerProps as ColumnResizerProps_2 } from 'react-aria-components';
7
7
  import { ComboBoxProps as ComboBoxProps_2 } from 'react-aria-components';
8
+ import { CountryCode } from 'libphonenumber-js/min';
8
9
  import { default as default_2 } from 'react';
9
10
  import { DialogProps } from 'react-aria-components';
10
11
  import { GroupProps } from 'react-aria-components';
@@ -243,6 +244,53 @@ export declare type BadgeSize = 'sm' | 'md' | 'lg';
243
244
 
244
245
  export declare type BadgeVariant = 'solid' | 'outline';
245
246
 
247
+ /**
248
+ * The shared foundation every Input-family component is built on — see
249
+ * `RFC-input-family.md` (Decision #0) for the full rationale. Anatomy is exactly three parts:
250
+ * `leftSlot`, the native `<input>`, `rightSlot`. No other structural surface — a component that
251
+ * needs a divider, a dropdown trigger, or a button renders that INSIDE its own slot content;
252
+ * `BaseInput` never grows new props to accommodate it (that's the exact prop-list-per-Type-variant
253
+ * growth this primitive exists to stop).
254
+ *
255
+ * Internally built on `react-aria-components`' `Group` + `Input` (not `TextField`): `Group` is a
256
+ * bare bordered-container primitive with hover/focus-within/focus-visible/disabled/invalid state
257
+ * for free, and no forced field-level semantics (label association, description slot, validation
258
+ * state machine) the way `TextField` has — `TextField` would force a wrapper `<div>` we'd then
259
+ * have to fight or double up on. Same choice `ComboBoxTrigger` already made for an analogous
260
+ * "bordered shell holding an input plus other stuff" role (see `ComboBox.tsx`).
261
+ *
262
+ * The PUBLIC API stays 100% native-DOM-shaped on purpose (`onChange: ChangeEventHandler`,
263
+ * `error: boolean`, `disabled: boolean`, `required: boolean`) even though the internals are RAC —
264
+ * RAC's own shape for the same concepts (`onChange: (value: string) => void`, `isInvalid`,
265
+ * `isDisabled`, `isRequired`) is intentionally not exposed. This keeps `BaseInput` a drop-in
266
+ * sibling of the existing native `Input` rather than introducing a second, incompatible prop
267
+ * shape into the same family.
268
+ *
269
+ * Forwards its ref to the inner `<input>`, matching `Input`'s existing ref contract.
270
+ */
271
+ export declare const BaseInput: React_2.ForwardRefExoticComponent<BaseInputProps & React_2.RefAttributes<HTMLInputElement>>;
272
+
273
+ export declare interface BaseInputProps extends Omit<React_2.InputHTMLAttributes<HTMLInputElement>, 'size' | 'className' | 'style'> {
274
+ label?: string;
275
+ required?: boolean;
276
+ hint?: string;
277
+ size?: InputSize;
278
+ error?: boolean;
279
+ disabled?: boolean;
280
+ /** Tighter padding/height/radius and a smaller semibold label, independent of `size`'s font scale. Opt-in, mirrors `Input`'s `compact`. */
281
+ compact?: boolean;
282
+ /**
283
+ * Anything mounted at the start of the field — icon, fixed text, dropdown trigger, whatever
284
+ * the derived component needs. Pure `ReactNode`: `BaseInput` has no opinion on the slot's
285
+ * internal layout, border, or divider — that's the slot content's own responsibility.
286
+ */
287
+ leftSlot?: React_2.ReactNode;
288
+ /** Same contract as `leftSlot`, mounted at the end of the field. */
289
+ rightSlot?: React_2.ReactNode;
290
+ className?: ClassValue;
291
+ wrapperClassName?: ClassValue;
292
+ }
293
+
246
294
  /**
247
295
  * Wraps RAC's `<Breadcrumb>` (an `<li>`). RAC computes `isCurrent` from the item's position
248
296
  * in the collection — the last item gets it — so the trailing separator is suppressed
@@ -341,23 +389,7 @@ export declare type ButtonTone = 'primary' | 'destructive';
341
389
 
342
390
  export declare type ButtonVariant = 'solid' | 'outline' | 'outline-primary' | 'ghost' | 'ghost-primary' | 'plain' | 'plain-black';
343
391
 
344
- export declare function CardNumberInput({ size, label, required, hint, error, disabled, placeholder, value, onChange, rightIcon, prefix, className, wrapperClassName, }: CardNumberInputProps): JSX_2.Element;
345
-
346
- declare interface CardNumberInputProps {
347
- size?: 'sm' | 'md';
348
- label?: string;
349
- required?: boolean;
350
- hint?: string;
351
- error?: boolean;
352
- disabled?: boolean;
353
- placeholder?: string;
354
- value?: string;
355
- onChange?: default_2.ChangeEventHandler<HTMLInputElement>;
356
- rightIcon?: default_2.ReactNode;
357
- prefix?: default_2.ReactNode;
358
- className?: InputProps['className'];
359
- wrapperClassName?: InputProps['wrapperClassName'];
360
- }
392
+ export declare type CardBrand = 'visa' | 'mastercard' | 'amex' | 'discover' | 'jcb' | 'diners' | 'unionpay';
361
393
 
362
394
  /**
363
395
  * `min-h-[42px]`, never `h-[42px]` — a fixed height plus no truncation would
@@ -530,6 +562,24 @@ export declare interface ComboBoxTriggerProps extends Omit<GroupProps, 'classNam
530
562
  className?: ClassValue;
531
563
  }
532
564
 
565
+ export declare interface CountryOption {
566
+ code: CountryCode;
567
+ dial_code: string;
568
+ name: string;
569
+ flag?: string;
570
+ }
571
+
572
+ export declare interface CurrencyOption {
573
+ /** ISO 4217-shaped code the consumer defines, e.g. 'IDR', 'USD' — not validated against a real ISO list, since this is a consumer-owned/backend-owned shape (see `RFC-input-family.md` Decision #3). */
574
+ code: string;
575
+ /** Displayed in the amount field's leftSlot, e.g. 'Rp', '$'. */
576
+ symbol: string;
577
+ /** Displayed in the currency picker dropdown row, e.g. 'Indonesian Rupiah'. */
578
+ label: string;
579
+ /** BCP 47 locale tag driving thousands/decimal separator formatting, e.g. 'id-ID', 'en-US'. Falls back to the browser's default locale when omitted. */
580
+ locale?: string;
581
+ }
582
+
533
583
  export declare const Dot: {
534
584
  ({ size, outline, className }: DotProps): JSX_2.Element;
535
585
  displayName: string;
@@ -591,6 +641,20 @@ export declare type FeaturedIconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
591
641
  */
592
642
  export declare type FeaturedIconType = 'light' | 'dark' | 'modern' | 'glass';
593
643
 
644
+ /**
645
+ * The country/dial-code list `InputPhone` ships with by default (see `RFC-input-family.md`
646
+ * Decision #2 — this is cekat-ui-owned static data, not fetched, not backend-driven, unlike
647
+ * `InputPrice`'s currency list). Built from `libphonenumber-js`'s own `getCountries()` +
648
+ * `getCountryCallingCode()` (already a dependency, single source of truth for calling codes —
649
+ * no separately hand-maintained dial-code JSON to drift out of sync) plus the runtime's own
650
+ * `Intl.DisplayNames` for localized country names and a pure Unicode transform for flag emoji.
651
+ * Zero bundled data table beyond what the phone-parsing library itself already carries.
652
+ *
653
+ * Computed once and cached — `Intl.DisplayNames` construction and 245 `.of()` calls are cheap
654
+ * individually but unnecessary to repeat across every `InputPhone` instance.
655
+ */
656
+ export declare function getDefaultCountryOptions(): CountryOption[];
657
+
594
658
  export declare const Icon: {
595
659
  ({ icon: IconComponent, size, strokeWidth, label, className, ...rest }: IconProps): JSX_2.Element;
596
660
  displayName: string;
@@ -626,6 +690,52 @@ export declare const Input: InputCompound;
626
690
  */
627
691
  declare const Input_2: default_2.ForwardRefExoticComponent<InputProps & default_2.RefAttributes<HTMLInputElement>>;
628
692
 
693
+ /**
694
+ * Rebuild of the old `CardNumberInput` export slot — the previous implementation was a dead
695
+ * placeholder (hardcoded a static mastercard PNG import regardless of the number typed in, no
696
+ * Luhn check, no brand detection, no digit grouping, 0 real consumers). This version is built on
697
+ * `BaseInput` per `RFC-input-family.md`, matching the Figma `Input field` master's
698
+ * `Type=Payment input` variant (verified via metadata — node `80:8127` etc: a single "Payment
699
+ * method icon" leading slot + text, no trailing element at all).
700
+ *
701
+ * `leftSlot` renders NOTHING by default — RFC Decision #4: shipping trademarked
702
+ * Visa/Mastercard/etc. logos inside a design-system package is legal/brand-guideline exposure
703
+ * this component is not positioned to clear. Brand detection (IIN/BIN prefix regex table) and
704
+ * Luhn validation are genuinely component-owned logic and still run on every keystroke — the
705
+ * detected brand is surfaced via `onChange`'s second argument so a consumer with their own
706
+ * cleared icon set can render it in `leftSlot` themselves.
707
+ */
708
+ export declare function InputCardNumber({ size, label, required, hint, error, disabled, placeholder, value, leftSlot, onChange, className, wrapperClassName, }: InputCardNumberProps): JSX_2.Element;
709
+
710
+ export declare interface InputCardNumberProps {
711
+ size?: InputSize;
712
+ label?: string;
713
+ required?: boolean;
714
+ hint?: string;
715
+ error?: boolean;
716
+ disabled?: boolean;
717
+ placeholder?: string;
718
+ /** Controlled, formatted display value (spaces already inserted per the detected brand's grouping). */
719
+ value?: string;
720
+ /**
721
+ * Consumer-supplied brand mark, mounted in `leftSlot`. Renders nothing by default — see
722
+ * `RFC-input-family.md` Decision #4: shipping trademarked payment-network logos inside a
723
+ * design-system package is legal/brand-guideline exposure this component is not positioned
724
+ * to clear. The detected brand is still surfaced via `onChange`'s second argument, so a
725
+ * consumer with their own cleared icon set (or a generic/licensed asset) can render it here.
726
+ */
727
+ leftSlot?: React_2.ReactNode;
728
+ /**
729
+ * `value` is the formatted display string (spaces inserted). `brand` is the network detected
730
+ * from the IIN/BIN prefix, or `null` if no known prefix matches yet. `isValid` is Luhn check
731
+ * pass AND the digit count matching the detected brand's expected length — always `false`
732
+ * while `brand` is `null` (an undetected prefix can't be validated against a target length).
733
+ */
734
+ onChange?: (value: string, brand: CardBrand | null, isValid: boolean) => void;
735
+ className?: ClassValue;
736
+ wrapperClassName?: ClassValue;
737
+ }
738
+
629
739
  declare type InputCompound = typeof Input_2 & {
630
740
  Prefix: typeof InputPrefix;
631
741
  Suffix: typeof InputSuffix;
@@ -709,10 +819,103 @@ declare interface InputDropdownSlot {
709
819
 
710
820
  export declare type InputDropdownType = 'default' | 'search' | 'tags';
711
821
 
822
+ /**
823
+ * Rebuild of the old `PhoneInput` export slot — the previous implementation was a dead
824
+ * placeholder (hardcoded `"US"` prefix text, no library-backed formatting/validation, 0 real
825
+ * consumers). This version is a genuine port of cekat-dashboard's working freestyle
826
+ * implementation (`RegisterSteps/Step1.tsx` + `phoneUtils.ts`) into the library, built on
827
+ * `BaseInput` per `RFC-input-family.md`.
828
+ *
829
+ * The country picker's trigger shows only the ISO country code ("ID", "US") — the dial code
830
+ * itself (+62, +1) lives inside the input's own text, combined with the national number
831
+ * (e.g. "+62 812 345 6789"), rather than being shown twice. `value`/`onChange` therefore carry
832
+ * the FULL string including the dial code — not just the national number like the picker-shows-
833
+ * dial-code version this replaced.
834
+ *
835
+ * Country list defaults to `getDefaultCountryOptions()` (cekat-ui-owned, generated from
836
+ * `libphonenumber-js` + `Intl.DisplayNames`, see `countryOptions.ts`) — the `countries` prop is
837
+ * an override escape hatch, not the expected path (Decision #2).
838
+ *
839
+ * Formatting/validation is `libphonenumber-js`'s `AsYouType`/`parsePhoneNumberFromString`,
840
+ * matching `phoneUtils.ts`'s exact behavior rather than reinventing phone parsing.
841
+ */
842
+ export declare function InputPhone({ size, label, required, hint, error, disabled, placeholder, value, defaultCountry, countries, onChange, className, wrapperClassName, }: InputPhoneProps): JSX_2.Element;
843
+
844
+ export declare interface InputPhoneProps {
845
+ size?: InputSize;
846
+ label?: string;
847
+ required?: boolean;
848
+ hint?: string;
849
+ error?: boolean;
850
+ disabled?: boolean;
851
+ placeholder?: string;
852
+ /** National-format display value (controlled) — what the user sees/types, not E.164. */
853
+ value?: string;
854
+ /** ISO 3166-1 alpha-2 default country, drives both the picker's initial selection and AsYouType formatting. Default `'ID'`. */
855
+ defaultCountry?: CountryCode;
856
+ /**
857
+ * Overrides the default bundled country/dial-code list (see `RFC-input-family.md` Decision
858
+ * #2 — `getDefaultCountryOptions()` from `countryOptions.ts` is cekat-ui's own owned data,
859
+ * this prop exists purely as an escape hatch, not because swapping it in is the expected
860
+ * path).
861
+ */
862
+ countries?: CountryOption[];
863
+ /**
864
+ * `value` is the national-format display string as typed (AsYouType-formatted).
865
+ * `isValid` is `libphonenumber-js`'s own validation for the currently-selected country.
866
+ * `e164` is only present when `isValid` is true — full `+<countrycode><number>` form,
867
+ * ready to submit to a backend without the consumer re-deriving it.
868
+ */
869
+ onChange?: (value: string, isValid: boolean, e164?: string) => void;
870
+ className?: ClassValue;
871
+ wrapperClassName?: ClassValue;
872
+ }
873
+
712
874
  declare function InputPrefix({ children }: {
713
875
  children: ReactNode;
714
876
  }): JSX_2.Element;
715
877
 
878
+ /**
879
+ * Rebuild of the old `SaleAmountInput` export slot — the previous implementation was a dead
880
+ * placeholder (hardcoded `$` prefix regardless of `currency`, `currency` prop existed but
881
+ * `onCurrencyChange` had no actual dropdown/menu behind it, no locale-aware number formatting,
882
+ * 0 real consumers). This version is built on `BaseInput` per `RFC-input-family.md`: currency
883
+ * symbol in `leftSlot`, currency picker in `rightSlot`, matching the Figma `Input field` master's
884
+ * `Type=Trailing dropdown` variant (verified via Figma metadata — node `80:9230` etc, "Leading
885
+ * text" + "Dropdown" sub-frames).
886
+ *
887
+ * `currencies` is a REQUIRED prop with no bundled default — per RFC Decision #3, the currency
888
+ * list is backend-owned, not cekat-ui's. Formatting is locale-aware per the selected currency's
889
+ * `locale` field (thousands/decimal separators via `Intl.NumberFormat`, see `amountFormat.ts`),
890
+ * not hardcoded to any single currency's conventions.
891
+ */
892
+ export declare function InputPrice({ size, label, required, hint, error, disabled, placeholder, value, currency, currencies, onCurrencyChange, onChange, className, wrapperClassName, }: InputPriceProps): JSX_2.Element;
893
+
894
+ export declare interface InputPriceProps {
895
+ size?: InputSize;
896
+ label?: string;
897
+ required?: boolean;
898
+ hint?: string;
899
+ error?: boolean;
900
+ disabled?: boolean;
901
+ placeholder?: string;
902
+ /** Raw numeric value (controlled) — not a pre-formatted display string. `undefined`/empty renders a blank field. */
903
+ value?: number;
904
+ /** Currently-selected currency's `code`. Must match one entry in `currencies`. */
905
+ currency: string;
906
+ /**
907
+ * REQUIRED — no bundled default (see `RFC-input-family.md` Decision #3, updated). The
908
+ * currency list is backend-owned; cekat-ui never assumes or hardcodes it. Consumers map
909
+ * whatever shape backend returns into `CurrencyOption[]` before passing it in.
910
+ */
911
+ currencies: CurrencyOption[];
912
+ onCurrencyChange?: (code: string) => void;
913
+ /** Fires with the parsed numeric value on every keystroke that changes it (locale-aware — thousands/decimal separators are stripped per the selected currency's `locale`). */
914
+ onChange?: (value: number) => void;
915
+ className?: ClassValue;
916
+ wrapperClassName?: ClassValue;
917
+ }
918
+
716
919
  declare interface InputProps extends Omit<React_2.InputHTMLAttributes<HTMLInputElement>, 'size' | 'prefix' | 'className'> {
717
920
  label?: string;
718
921
  required?: boolean;
@@ -1041,23 +1244,6 @@ export declare interface NotificationToastProps {
1041
1244
  */
1042
1245
  export declare type NotificationToastType = 'primary-icon' | 'gray-icon' | 'progress' | 'avatar' | 'image' | 'success' | 'warning' | 'error' | 'no-icon';
1043
1246
 
1044
- export declare function PhoneInput({ size, label, required, hint, error, disabled, placeholder, rightIcon, value, onChange, className, wrapperClassName, }: PhoneInputProps): JSX_2.Element;
1045
-
1046
- declare interface PhoneInputProps {
1047
- size?: 'sm' | 'md';
1048
- label?: string;
1049
- required?: boolean;
1050
- hint?: string;
1051
- error?: boolean;
1052
- disabled?: boolean;
1053
- placeholder?: string;
1054
- rightIcon?: default_2.ReactNode;
1055
- value?: string;
1056
- onChange?: default_2.ChangeEventHandler<HTMLInputElement>;
1057
- className?: InputProps['className'];
1058
- wrapperClassName?: InputProps['wrapperClassName'];
1059
- }
1060
-
1061
1247
  /**
1062
1248
  * Overlay foundation for the dropdown family (Menu, Select, ComboBox) and Tooltip. Wraps RAC's
1063
1249
  * `Popover`, which already provides: portal to `document.body`,
@@ -1114,25 +1300,6 @@ export declare const Row: <T extends object>(props: RowProps<T> & {
1114
1300
  export declare interface RowProps<T extends object> extends RowProps_2<T> {
1115
1301
  }
1116
1302
 
1117
- export declare function SaleAmountInput({ size, label, required, hint, error, disabled, value, placeholder, currency, onCurrencyChange, rightIcon, onChange, className, wrapperClassName, }: SaleAmountInputProps): JSX_2.Element;
1118
-
1119
- declare interface SaleAmountInputProps {
1120
- size?: 'sm' | 'md';
1121
- label?: string;
1122
- required?: boolean;
1123
- hint?: string;
1124
- error?: boolean;
1125
- disabled?: boolean;
1126
- value?: string;
1127
- placeholder?: string;
1128
- currency?: string;
1129
- onCurrencyChange?: () => void;
1130
- rightIcon?: default_2.ReactNode;
1131
- onChange?: default_2.ChangeEventHandler<HTMLInputElement>;
1132
- className?: InputProps['className'];
1133
- wrapperClassName?: InputProps['wrapperClassName'];
1134
- }
1135
-
1136
1303
  export declare const Select: <T extends object>(props: SelectProps<T> & {
1137
1304
  ref?: React_2.Ref<HTMLDivElement>;
1138
1305
  }) => React_2.ReactElement;
@@ -1481,6 +1648,20 @@ export declare type TagShape = 'rounded' | 'pill';
1481
1648
 
1482
1649
  export declare type TagSize = 'sm' | 'md' | 'lg';
1483
1650
 
1651
+ /**
1652
+ * Internally built on `react-aria-components`' `Group` + `TextArea` — same directional choice
1653
+ * `BaseInput` made (see `RFC-input-family.md` Decision #0) and for the same reason:
1654
+ * `TextField`'s own multi-line composition would force a wrapper `<div>` and value-based
1655
+ * `onChange` this component doesn't want. RAC's `TextArea` (confirmed via installed
1656
+ * `react-aria-components@1.20.0` types, not assumed from docs) is already native-DOM-shaped by
1657
+ * default (`extends TextareaHTMLAttributes<HTMLTextAreaElement>`, plain `onChange:
1658
+ * ChangeEventHandler`) — unlike `TextField`'s `Input`, it needs no adapter layer at all, so this
1659
+ * migration is a pure internals swap: `Textarea`'s public API is unchanged.
1660
+ *
1661
+ * `Group` gives hover/focus-within/focus-visible/`data-[invalid]`/`data-[disabled]` state for
1662
+ * free instead of hand-rolling it via plain `focus-within:` CSS (the pre-RAC version's approach)
1663
+ * — same accessibility/state-machine benefit `BaseInput` already gets from it.
1664
+ */
1484
1665
  export declare const Textarea: React_2.ForwardRefExoticComponent<TextareaProps & React_2.RefAttributes<HTMLTextAreaElement>>;
1485
1666
 
1486
1667
  export declare interface TextareaProps extends Omit<React_2.TextareaHTMLAttributes<HTMLTextAreaElement>, 'className'> {
@@ -1490,6 +1671,7 @@ export declare interface TextareaProps extends Omit<React_2.TextareaHTMLAttribut
1490
1671
  helpIcon?: React_2.ReactNode;
1491
1672
  error?: boolean;
1492
1673
  disabled?: boolean;
1674
+ /** Whether the resize handle is shown at all — the browser's own CSS `resize` behavior already clamps a drag to never go below the rendered min-height (132px default / rows-driven), so "resize down to no smaller than default height" needs no extra logic beyond that CSS floor. */
1493
1675
  resizable?: boolean;
1494
1676
  /** Tighter padding/min-height and a smaller semibold label, for compact form layouts (e.g. a multi-field grid). Opt-in, does not affect default styling. */
1495
1677
  compact?: boolean;