myoperator-ui 0.0.188 → 0.0.190-beta.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.
Files changed (2) hide show
  1. package/dist/index.js +261 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8188,16 +8188,25 @@ export const AutoPaySetup = React.forwardRef<HTMLDivElement, AutoPaySetupProps>(
8188
8188
  loading = false,
8189
8189
  disabled = false,
8190
8190
  defaultOpen = true,
8191
+ open,
8192
+ onOpenChange,
8191
8193
  className,
8192
8194
  },
8193
8195
  ref
8194
8196
  ) => {
8197
+ const isControlled = open !== undefined;
8198
+
8195
8199
  return (
8196
8200
  <div ref={ref} className={cn("w-full", className)}>
8197
8201
  <Accordion
8198
8202
  type="single"
8199
8203
  variant="bordered"
8200
- defaultValue={defaultOpen ? ["auto-pay-setup"] : []}
8204
+ {...(isControlled
8205
+ ? {
8206
+ value: open ? ["auto-pay-setup"] : [],
8207
+ onValueChange: (val) => onOpenChange?.(val.length > 0),
8208
+ }
8209
+ : { defaultValue: defaultOpen ? ["auto-pay-setup"] : [] })}
8201
8210
  >
8202
8211
  <AccordionItem value="auto-pay-setup">
8203
8212
  <AccordionTrigger className="px-4 py-4">
@@ -8306,8 +8315,12 @@ export interface AutoPaySetupProps {
8306
8315
  disabled?: boolean;
8307
8316
 
8308
8317
  // Accordion
8309
- /** Whether the accordion is open by default */
8318
+ /** Whether the accordion is open by default (uncontrolled) */
8310
8319
  defaultOpen?: boolean;
8320
+ /** Controlled open state \u2014 use with onOpenChange for exclusive accordion behavior */
8321
+ open?: boolean;
8322
+ /** Callback fired when the panel is toggled \u2014 receives new open state */
8323
+ onOpenChange?: (open: boolean) => void;
8311
8324
 
8312
8325
  // Styling
8313
8326
  /** Additional className for the root element */
@@ -11535,6 +11548,252 @@ export interface WalletTopupProps {
11535
11548
  name: "index.ts",
11536
11549
  content: prefixTailwindClasses(`export { WalletTopup } from "./wallet-topup";
11537
11550
  export type { WalletTopupProps, AmountOption } from "./types";
11551
+ `, prefix)
11552
+ }
11553
+ ]
11554
+ },
11555
+ "contact-form-modal": {
11556
+ name: "contact-form-modal",
11557
+ description: "A modal dialog for adding a new contact with phone number, country code, channel selector, and Start Conversation CTA",
11558
+ category: "custom",
11559
+ dependencies: [
11560
+ "clsx",
11561
+ "tailwind-merge",
11562
+ "lucide-react"
11563
+ ],
11564
+ internalDependencies: [
11565
+ "dialog",
11566
+ "select",
11567
+ "input",
11568
+ "button"
11569
+ ],
11570
+ isMultiFile: true,
11571
+ directory: "contact-form-modal",
11572
+ mainFile: "contact-form-modal.tsx",
11573
+ files: [
11574
+ {
11575
+ name: "contact-form-modal.tsx",
11576
+ content: prefixTailwindClasses(`import * as React from "react";
11577
+ import { ChevronDown } from "lucide-react";
11578
+
11579
+ import { cn } from "../../../lib/utils";
11580
+ import {
11581
+ Dialog,
11582
+ DialogContent,
11583
+ DialogTitle,
11584
+ } from "../dialog";
11585
+ import {
11586
+ Select,
11587
+ SelectContent,
11588
+ SelectItem,
11589
+ SelectTrigger,
11590
+ SelectValue,
11591
+ } from "../select";
11592
+ import { Input } from "../input";
11593
+ import { Button } from "../button";
11594
+ import { DEFAULT_COUNTRY_CODE_OPTIONS } from "./types";
11595
+ import type { ContactFormModalProps } from "./types";
11596
+
11597
+ const ContactFormModal = React.forwardRef<HTMLDivElement, ContactFormModalProps>(
11598
+ (
11599
+ {
11600
+ open,
11601
+ onOpenChange,
11602
+ channelOptions = [],
11603
+ selectedChannel,
11604
+ onChannelChange,
11605
+ countryCodeOptions = DEFAULT_COUNTRY_CODE_OPTIONS,
11606
+ countryCode = "+91",
11607
+ onCountryCodeChange,
11608
+ phoneNumber = "",
11609
+ onPhoneNumberChange,
11610
+ contactName = "",
11611
+ onContactNameChange,
11612
+ onStartConversation,
11613
+ startConversationDisabled,
11614
+ loading = false,
11615
+ className,
11616
+ },
11617
+ ref
11618
+ ) => {
11619
+ const isDisabled =
11620
+ startConversationDisabled ?? phoneNumber.trim().length === 0;
11621
+
11622
+ return (
11623
+ <Dialog open={open} onOpenChange={onOpenChange}>
11624
+ <DialogContent
11625
+ ref={ref}
11626
+ size="sm"
11627
+ className={cn("gap-6 p-6", className)}
11628
+ aria-describedby={undefined}
11629
+ >
11630
+ {/* Header */}
11631
+ <div className="flex items-center gap-2">
11632
+ <DialogTitle className="flex-1 text-lg font-semibold text-semantic-text-primary leading-tight">
11633
+ Add New Contact
11634
+ </DialogTitle>
11635
+
11636
+ {channelOptions.length > 0 && (
11637
+ <Select value={selectedChannel} onValueChange={onChannelChange}>
11638
+ <SelectTrigger className="h-8 w-auto min-w-[72px] gap-1.5 border border-semantic-border-input bg-background px-2 py-1 text-sm font-semibold text-semantic-text-primary rounded">
11639
+ <SelectValue placeholder="Channel" />
11640
+ <ChevronDown className="h-[18px] w-[18px] shrink-0 opacity-60" />
11641
+ </SelectTrigger>
11642
+ <SelectContent>
11643
+ {channelOptions.map((opt) => (
11644
+ <SelectItem key={opt.value} value={opt.value}>
11645
+ {opt.label}
11646
+ </SelectItem>
11647
+ ))}
11648
+ </SelectContent>
11649
+ </Select>
11650
+ )}
11651
+ </div>
11652
+
11653
+ {/* Fields */}
11654
+ <div className="flex flex-col gap-4">
11655
+ {/* Phone */}
11656
+ <div className="flex flex-col gap-1.5">
11657
+ <label className="text-sm font-semibold text-semantic-text-primary tracking-[0.014px]">
11658
+ Phone
11659
+ <span className="ml-0.5 text-xs text-semantic-error-primary">*</span>
11660
+ </label>
11661
+ <div className="flex items-center gap-3">
11662
+ <Select value={countryCode} onValueChange={onCountryCodeChange}>
11663
+ <SelectTrigger className="h-10 w-auto min-w-[90px] shrink-0 border border-semantic-border-input bg-background px-4 py-2.5 text-sm font-semibold text-semantic-text-secondary rounded gap-2">
11664
+ <SelectValue />
11665
+ <ChevronDown className="h-[18px] w-[18px] shrink-0 opacity-60" />
11666
+ </SelectTrigger>
11667
+ <SelectContent>
11668
+ {countryCodeOptions.map((opt) => (
11669
+ <SelectItem key={opt.code} value={opt.code}>
11670
+ {opt.label}
11671
+ </SelectItem>
11672
+ ))}
11673
+ </SelectContent>
11674
+ </Select>
11675
+
11676
+ <Input
11677
+ type="tel"
11678
+ placeholder="Enter phone number"
11679
+ value={phoneNumber}
11680
+ onChange={(e) => onPhoneNumberChange?.(e.target.value)}
11681
+ className="flex-1"
11682
+ />
11683
+ </div>
11684
+ </div>
11685
+
11686
+ {/* Contact name */}
11687
+ <div className="flex flex-col gap-1.5">
11688
+ <label className="text-sm font-semibold text-semantic-text-primary tracking-[0.014px]">
11689
+ Save contact as
11690
+ </label>
11691
+ <Input
11692
+ type="text"
11693
+ placeholder="Enter name"
11694
+ value={contactName}
11695
+ onChange={(e) => onContactNameChange?.(e.target.value)}
11696
+ />
11697
+ </div>
11698
+ </div>
11699
+
11700
+ {/* Footer */}
11701
+ <div className="flex items-center justify-end">
11702
+ <Button
11703
+ variant="primary"
11704
+ disabled={isDisabled}
11705
+ loading={loading}
11706
+ onClick={onStartConversation}
11707
+ >
11708
+ Start Conversation
11709
+ </Button>
11710
+ </div>
11711
+ </DialogContent>
11712
+ </Dialog>
11713
+ );
11714
+ }
11715
+ );
11716
+
11717
+ ContactFormModal.displayName = "ContactFormModal";
11718
+
11719
+ export { ContactFormModal };
11720
+ `, prefix)
11721
+ },
11722
+ {
11723
+ name: "types.ts",
11724
+ content: prefixTailwindClasses(`export interface ChannelOption {
11725
+ value: string;
11726
+ label: string;
11727
+ }
11728
+
11729
+ export interface CountryCodeOption {
11730
+ /** Dial code, e.g. "+91" */
11731
+ code: string;
11732
+ /** Display label shown in dropdown, e.g. "\u{1F1EE}\u{1F1F3} +91" */
11733
+ label: string;
11734
+ }
11735
+
11736
+ export const DEFAULT_COUNTRY_CODE_OPTIONS = [
11737
+ { code: "+91", label: "\u{1F1EE}\u{1F1F3} +91" },
11738
+ { code: "+1", label: "\u{1F1FA}\u{1F1F8} +1" },
11739
+ { code: "+44", label: "\u{1F1EC}\u{1F1E7} +44" },
11740
+ { code: "+971", label: "\u{1F1E6}\u{1F1EA} +971" },
11741
+ { code: "+65", label: "\u{1F1F8}\u{1F1EC} +65" },
11742
+ ];
11743
+
11744
+ export interface ContactFormModalProps {
11745
+ /** Controls modal visibility */
11746
+ open: boolean;
11747
+ /** Callback when open state changes */
11748
+ onOpenChange: (open: boolean) => void;
11749
+
11750
+ /** Channel selector options (e.g. MY01, MY02). Pass empty array to hide the selector. */
11751
+ channelOptions?: ChannelOption[];
11752
+ /** Currently selected channel value */
11753
+ selectedChannel?: string;
11754
+ /** Callback when channel changes */
11755
+ onChannelChange?: (value: string) => void;
11756
+
11757
+ /** Country code options for the phone field */
11758
+ countryCodeOptions?: CountryCodeOption[];
11759
+ /** Currently selected country code (e.g. "+91") */
11760
+ countryCode?: string;
11761
+ /** Callback when country code changes */
11762
+ onCountryCodeChange?: (code: string) => void;
11763
+
11764
+ /** Current phone number value */
11765
+ phoneNumber?: string;
11766
+ /** Callback when phone number changes */
11767
+ onPhoneNumberChange?: (phone: string) => void;
11768
+
11769
+ /** Current contact name value */
11770
+ contactName?: string;
11771
+ /** Callback when contact name changes */
11772
+ onContactNameChange?: (name: string) => void;
11773
+
11774
+ /** Callback when "Start Conversation" is clicked */
11775
+ onStartConversation?: () => void;
11776
+ /** Disable the Start Conversation button (auto-disabled when phoneNumber is empty) */
11777
+ startConversationDisabled?: boolean;
11778
+ /** Show loading state on Start Conversation button */
11779
+ loading?: boolean;
11780
+
11781
+ /** Additional className for the dialog content */
11782
+ className?: string;
11783
+ }
11784
+ `, prefix)
11785
+ },
11786
+ {
11787
+ name: "index.ts",
11788
+ content: prefixTailwindClasses(`export { ContactFormModal } from "./contact-form-modal";
11789
+ export {
11790
+ DEFAULT_COUNTRY_CODE_OPTIONS,
11791
+ } from "./types";
11792
+ export type {
11793
+ ContactFormModalProps,
11794
+ ChannelOption,
11795
+ CountryCodeOption,
11796
+ } from "./types";
11538
11797
  `, prefix)
11539
11798
  }
11540
11799
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-ui",
3
- "version": "0.0.188",
3
+ "version": "0.0.190-beta.0",
4
4
  "description": "CLI for adding myOperator UI components to your project",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",