@qumra/fanar 0.0.11 → 0.0.13

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.ts CHANGED
@@ -180,6 +180,21 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
180
180
  }
181
181
  declare const Button: react.ForwardRefExoticComponent<ButtonProps & react.RefAttributes<HTMLButtonElement>>;
182
182
 
183
+ /**
184
+ * Sets the display language for every Qumra component in the tree.
185
+ *
186
+ * ── نفس الاسم على المنصّتين ────────────────────────────────────────────
187
+ * النيتف مافيهوش `<html lang>`، فـ`lang.native.ts` بيمسك التبديل في
188
+ * مخزن جوّه الموديول. والويب مصدره الـDOM — فالتبديل هنا **بيكتب في
189
+ * المصدر نفسه** بدل ما يعمل مخزن تاني جنبه.
190
+ *
191
+ * والنتيجة إن `setLang('en-US')` بتشتغل زي بعضها على الاتنين، وإن الويب
192
+ * مافيهوش مصدرين للحقيقة يتخانقوا: `langStore` بيراقب السمة وبيعيد
193
+ * الرسم لوحده.
194
+ *
195
+ * `null` بترجّع للافتراضي (`ar-EG`).
196
+ */
197
+ declare function setLang(tag: string | null): void;
183
198
  /**
184
199
  * لغة الصفحة كاملةً — لا `boolean`.
185
200
  *
@@ -298,6 +313,7 @@ type UITextKey = keyof typeof TEXT;
298
313
  declare function useUIText(): Record<"select" | "search" | "row" | "from" | "close" | "searchEverything" | "noResults" | "searchOrAdd" | "now" | "videoPlayer" | "rating" | "activeFilters" | "clearAll" | "dropImages" | "chooseFromDevice" | "previousPeriod" | "less" | "more" | "totalSales" | "netToYou" | "verifiedAccount" | "grabHint" | "notifications" | "dismiss" | "unread" | "noNotifications" | "noNotificationsDesc" | "markAllRead" | "viewAllNotifications" | "newNotifications" | "reloadPreview" | "previousMonth" | "nextMonth" | "whatIsThisNumber" | "explainToMe" | "clearSearch" | "alerts" | "whatIsThisOption" | "shouldBeHere" | "closeExplainer" | "cancelRecording" | "sendRecording" | "attachFile" | "recordVoice" | "playbackPosition" | "volume" | "hideSuggestions" | "askShehab" | "shehabThinking" | "undo" | "tryAnotherReply" | "helpfulReply" | "unhelpfulReply" | "aiDisclaimer" | "back10" | "forward10" | "playbackSpeed" | "arabic" | "seeMore" | "pictureInPicture", string>;
299
314
 
300
315
  type FieldSize = 'sm' | 'md' | 'lg';
316
+
301
317
  interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {
302
318
  label?: ReactNode;
303
319
  /** فعل ثانوي جنب التسمية — «سجّل بالبريد بدل الهاتف» مثلاً */
@@ -374,13 +390,30 @@ declare function Switch({ checked, onCheckedChange, label, description, disabled
374
390
  id?: string;
375
391
  }): react.JSX.Element;
376
392
 
393
+ /**
394
+ * قواعد المبالغ ورموزها — **مشتركة بين الويب والنيتف**.
395
+ *
396
+ * التنسيق (`format`) واختيار الشكل (`resolve`) **منطق خالص**، ونسخهم
397
+ * معناه إن مبلغ يتكتب `١٬٢٥٠٫٥٠` على الويب و`1,250.50` على الموبايل.
398
+ * الشرح الكامل لكل قرار في `Money.tsx`.
399
+ */
400
+
401
+ /** الشكل المعروض للوحدة */
402
+ type Base = 'short' | 'word' | 'code' | 'sign';
403
+ /**
404
+ * الشكل المطلوب — و`best` رأي المكتبة لكل عملة.
405
+ *
406
+ * `short` الاختصار العربي · `word` الكلمة · `code` رمز ISO ·
407
+ * `sign` الرمز المرسوم.
408
+ */
409
+ type SymbolStyle = Base | 'best';
377
410
  declare const CURRENCY: {
378
411
  SAR: {
379
412
  short: string;
380
413
  word: string;
381
414
  best: "sign";
382
415
  code: string;
383
- sign: react.JSX.Element;
416
+ sign: "riyal";
384
417
  name: string;
385
418
  en: string;
386
419
  decimals: number;
@@ -440,7 +473,7 @@ declare const CURRENCY: {
440
473
  word: string;
441
474
  best: "word";
442
475
  code: string;
443
- sign: react.JSX.Element;
476
+ sign: "egp";
444
477
  name: string;
445
478
  en: string;
446
479
  decimals: number;
@@ -590,7 +623,7 @@ declare const CURRENCY: {
590
623
  word: string;
591
624
  best: "sign";
592
625
  code: string;
593
- sign: react.JSX.Element;
626
+ sign: "dollar";
594
627
  name: string;
595
628
  en: string;
596
629
  decimals: number;
@@ -600,7 +633,7 @@ declare const CURRENCY: {
600
633
  word: string;
601
634
  best: "sign";
602
635
  code: string;
603
- sign: react.JSX.Element;
636
+ sign: "euro";
604
637
  name: string;
605
638
  en: string;
606
639
  decimals: number;
@@ -610,65 +643,29 @@ declare const CURRENCY: {
610
643
  word: string;
611
644
  best: "sign";
612
645
  code: string;
613
- sign: react.JSX.Element;
646
+ sign: "pound";
614
647
  name: string;
615
648
  en: string;
616
649
  decimals: number;
617
650
  };
618
651
  };
619
- /** The displayed unit form */
620
- /** The explicit forms — each names one exact shape */
621
- type Base = 'short' | 'word' | 'code' | 'sign';
622
- /**
623
- * The displayed unit form.
624
- *
625
- * `short` Arabic abbreviation · `word` the word · `code` the ISO code ·
626
- * `sign` the graphic symbol · `best` whatever the library picks.
627
- *
628
- * ## `best` is an opinion, not an algorithm
629
- *
630
- * Every currency has a row in the table saying which form reads fastest **for
631
- * that currency**, because the answer differs between them:
632
- *
633
- * - Saudi riyal → its symbol, because it has an official one its readers know
634
- * - Pound, dinar, dirham → the word, because they have no official symbol
635
- * and the abbreviation takes two characters before it means anything
636
- * - Dollar, euro, sterling → their symbols, which read worldwide and are
637
- * shorter than spelling them out
638
- *
639
- * Derive these from one rule ("symbol if there is one") and the Egyptian
640
- * pound comes out as `£` — technically correct, and read as *sterling* in
641
- * Egypt. A written opinion per currency is truer than a rule that looks
642
- * tidier.
643
- *
644
- * ## In English
645
- *
646
- * `best` becomes the symbol where one exists and the ISO code otherwise. The
647
- * Arabic word means nothing on an English page, and «جنيه» is not rendered as
648
- * "pound" because that conflates it with sterling.
649
- */
650
- type SymbolStyle = Base | 'best';
651
652
  type Currency = keyof typeof CURRENCY;
652
- /**
653
- * Checks a currency code coming from the server before passing it to `Money`.
654
- *
655
- * ## Why a guard and not `as`
656
- *
657
- * `Money.currency` is a closed union and servers return `string`, so every
658
- * caller was writing `code as Currency` — which **silences rather than
659
- * checks**: an unknown code (`XYZ`, or an empty field) passes through and
660
- * then fails at the table lookup.
661
- *
662
- * The guard turns the unknown into `undefined`, and `Money` then falls back
663
- * to the store currency from `MoneyProvider` — which is the **right**
664
- * behaviour: showing the amount in the dashboard's currency does less damage
665
- * than showing it with the wrong symbol, or none.
666
- *
667
- * ```tsx
668
- * <Money value={total} currency={isCurrency(code) ? code : undefined} />
669
- * ```
670
- */
671
653
  declare function isCurrency(c?: string | null): c is Currency;
654
+ declare const SIZE$1: {
655
+ readonly inherit: "";
656
+ readonly sm: "text-caption";
657
+ readonly md: "text-ui";
658
+ readonly lg: "text-body font-extrabold";
659
+ readonly xl: "text-h2 font-black";
660
+ };
661
+ declare const TONE: {
662
+ readonly inherit: "";
663
+ readonly muted: "text-muted";
664
+ readonly ink: "text-ink";
665
+ readonly green: "text-green";
666
+ readonly red: "text-red";
667
+ };
668
+
672
669
  declare function MoneyProvider({ currency, locale, children, }: {
673
670
  currency: Currency;
674
671
  /**
@@ -689,26 +686,40 @@ declare function MoneyProvider({ currency, locale, children, }: {
689
686
  * header, the "priced in …" line.
690
687
  */
691
688
  declare function useCurrency(): Currency;
692
- declare const SIZE: {
693
- readonly inherit: "";
694
- readonly sm: "text-caption";
695
- readonly md: "text-ui";
696
- readonly lg: "text-body font-extrabold";
697
- readonly xl: "text-h2 font-black";
698
- };
699
- declare const TONE: {
700
- readonly inherit: "";
701
- readonly muted: "text-muted";
702
- readonly ink: "text-ink";
703
- readonly green: "text-green";
704
- readonly red: "text-red";
705
- };
689
+ /**
690
+ * The unit's weight and size for each form.
691
+ *
692
+ * ## The word is two steps lighter than the number
693
+ *
694
+ * "١٢٠ جنيه" at one weight reads as a **sentence**, and the eye passes over
695
+ * the word the way it passes over the number. Two steps lighter it reads as a
696
+ * **mark**: the number is the information and the word is its suffix — which
697
+ * is what the `£` symbol achieves by its shape rather than its weight.
698
+ *
699
+ * ## But not much smaller
700
+ *
701
+ * `0.86`, not `0.7`: the word is four letters, three of them undotted, and
702
+ * shrinking it further turns it into an unreadable smudge. The abbreviation
703
+ * survives being small because it is two characters, and the symbol survives
704
+ * because it is a single shape.
705
+ *
706
+ * ## And the letters are slightly tracked
707
+ *
708
+ * `tracking-wide` separates the word from the number visually without adding
709
+ * a space — so it reads as an attached unit, not as the next word in the line.
710
+ */
711
+ /**
712
+ * Resolves `best` into an explicit form — the one place that holds the opinion.
713
+ *
714
+ * Kept out of `Money` because `currencySymbol` needs it too: a column header
715
+ * and a field suffix have to match what their own rows display.
716
+ */
706
717
  interface MoneyProps {
707
718
  /** The amount in major units — pounds, not piastres */
708
719
  value: number;
709
720
  /** A local override that beats the store currency — a dollar price in an Egyptian store */
710
721
  currency?: Currency;
711
- size?: keyof typeof SIZE;
722
+ size?: keyof typeof SIZE$1;
712
723
  /**
713
724
  * The colour.
714
725
  *
@@ -787,14 +798,19 @@ declare const currencyName: (c?: Currency) => string;
787
798
  */
788
799
  declare function useCurrencySymbol(c?: Currency, style?: SymbolStyle): ReactNode;
789
800
 
790
- type Size = 'sm' | 'md' | 'lg';
801
+ /**
802
+ * أنماط العدّاد — **مشتركة بين الويب والنيتف**.
803
+ * نفس سبب `Display.variants.ts`.
804
+ */
805
+ type StepperSize = 'sm' | 'md' | 'lg';
806
+
791
807
  interface NumberStepperProps {
792
808
  value: number;
793
809
  onChange: (v: number) => void;
794
810
  min?: number;
795
811
  max?: number;
796
812
  step?: number;
797
- size?: Size;
813
+ size?: StepperSize;
798
814
  /** وحدة صغيرة بجانب الرقم — «قطعة»، «كجم» */
799
815
  unit?: ReactNode;
800
816
  /**
@@ -812,22 +828,6 @@ interface NumberStepperProps {
812
828
  }
813
829
  declare function NumberStepper({ value, onChange, min, max, step, size, unit, onRemove, disabled, label, className, }: NumberStepperProps): react.JSX.Element;
814
830
 
815
- /**
816
- * علامة واتساب.
817
- *
818
- * ── لماذا مرسومة ولماذا مصمتة ───────────────────────────────────────────
819
- * كانت `MessageCircle` من lucide، وهي فقاعة كلام عامّة. وفقاعة عامّة
820
- * بجانب فقاعة الرسائل النصّيّة تجعل الزرّين متشابهين، والمستخدم يقرأ
821
- * «رسالة» و«رسالة» فيتردّد قبل كلّ ضغطة.
822
- *
823
- * والعلامة مصمتة بين أيقونات محدّدة الخطوط عن قصد: علامة الخدمة تُعرف
824
- * بشكلها لا بأسلوب المجموعة، وتحويلها إلى خطوط لتناسب البقيّة يفقدها
825
- * الشيء الوحيد الذي تؤدّيه. والمسار من `simple-icons` — لا مرسوم
826
- * بالتقدير، لأن علامة خدمة تُخمَّن تخرج علامةً أخرى.
827
- */
828
- declare function WhatsAppIcon({ size, ...rest }: React.SVGProps<SVGSVGElement> & {
829
- size?: number;
830
- }): react.JSX.Element;
831
831
  interface PhoneParts {
832
832
  /** المفتاح الدوليّ بلا `+` — فارغ إن لم يُعرف */
833
833
  dial: string;
@@ -855,6 +855,44 @@ declare function parsePhone(raw: string, defaultDial?: string): PhoneParts;
855
855
  * و`spaces` لمن يريد الصورة الدوليّة الخام: `101 234 5678`.
856
856
  */
857
857
  type PhoneFormat = 'parens' | 'spaces';
858
+ /**
859
+ * `inherit` لا مقاس ولا وزن ولا لون — للرقم داخل صفّ يحدّد تنسيقه
860
+ * أصلاً. والمكوّن هناك للاتّجاه والتقطيع لا للحجم.
861
+ */
862
+ declare const SIZE: {
863
+ readonly inherit: "";
864
+ readonly sm: "text-caption";
865
+ readonly md: "text-ui";
866
+ };
867
+ type PhoneSize = keyof typeof SIZE;
868
+
869
+ /**
870
+ * علامة واتساب.
871
+ *
872
+ * ── لماذا مرسومة ولماذا مصمتة ───────────────────────────────────────────
873
+ * كانت `MessageCircle` من lucide، وهي فقاعة كلام عامّة. وفقاعة عامّة
874
+ * بجانب فقاعة الرسائل النصّيّة تجعل الزرّين متشابهين، والمستخدم يقرأ
875
+ * «رسالة» و«رسالة» فيتردّد قبل كلّ ضغطة.
876
+ *
877
+ * والعلامة مصمتة بين أيقونات محدّدة الخطوط عن قصد: علامة الخدمة تُعرف
878
+ * بشكلها لا بأسلوب المجموعة، وتحويلها إلى خطوط لتناسب البقيّة يفقدها
879
+ * الشيء الوحيد الذي تؤدّيه. والمسار من `simple-icons` — لا مرسوم
880
+ * بالتقدير، لأن علامة خدمة تُخمَّن تخرج علامةً أخرى.
881
+ */
882
+ declare function WhatsAppIcon({ size, ...rest }: React.SVGProps<SVGSVGElement> & {
883
+ size?: number;
884
+ }): react.JSX.Element;
885
+ /**
886
+ * قواعد التجميع لكل مفتاح دوليّ.
887
+ *
888
+ * المجموعات من الطول المحلّيّ **بعد** المفتاح وبعد نزع الصفر الوطنيّ:
889
+ * `+20 112 505 2692` محلّيّه `1125052692` فقاعدته `[3, 3, 4]` لا
890
+ * `[3, 4, 4]` — والفرق أن الصفر يُكتب في `01125052692` ولا يُكتب في
891
+ * الصورة الدوليّة، فمن يعدّه في القاعدة يُزيح كل مجموعة بعده.
892
+ *
893
+ * وما زاد على القاعدة يُجمَّع ثلاثات: أفضل من سطر متّصل، وأصدق من
894
+ * ادّعاء قاعدة بلد لا نعرفها.
895
+ */
858
896
  interface PhoneProps {
859
897
  /** الرقم كما هو في البيانات — منسَّقاً أو خاماً */
860
898
  value: string;
@@ -875,7 +913,7 @@ interface PhoneProps {
875
913
  * تنسيقه أصلاً: سطر ثانٍ تحت اسم عميل، أو سطر عنوان فرع.
876
914
  * والمكوّن هناك للاتّجاه والتقطيع لا للحجم.
877
915
  */
878
- size?: 'inherit' | 'sm' | 'md';
916
+ size?: PhoneSize;
879
917
  className?: string;
880
918
  }
881
919
  /**
@@ -892,6 +930,17 @@ interface PhoneProps {
892
930
  */
893
931
  declare function Phone({ value, defaultDial, format, mask, call, sms, whatsapp, size, className, }: PhoneProps): react.JSX.Element;
894
932
 
933
+ /**
934
+ * قواعد القيم التقنية وأنماطها — **مشتركة بين الويب والنيتف**.
935
+ *
936
+ * `normalizeHex` **منطق خالص** وبيتنادى من المكوّن ومن التطبيق —
937
+ * ونسخته معناها إن `#abc` بتتفكّ لستّ خانات في منصّة وتفضل تلاتة في
938
+ * التانية.
939
+ */
940
+ type TechnicalKind = 'hex' | 'url' | 'slug' | 'code' | 'id';
941
+ /** يرجّع `#RRGGBB` بحروف كبيرة، أو `null` لو القيمة ليست لوناً بعد */
942
+ declare function normalizeHex(input: string): string | null;
943
+
895
944
  /**
896
945
  * القيم التقنية داخل واجهة عربية.
897
946
  *
@@ -913,7 +962,6 @@ declare function Phone({ value, defaultDial, format, mask, call, sms, whatsapp,
913
962
  * `[dir=rtl]_&` لا `rtl:` — لأن `dir="ltr"` موضوع على العنصر نفسه،
914
963
  * فسمة `rtl:` لن تنطبق عليه أبداً؛ والاستعلام لا بدّ أن يسأل عن **جدّه**.
915
964
  */
916
- type TechnicalKind = 'hex' | 'url' | 'slug' | 'code' | 'id';
917
965
  interface TechnicalInputProps extends Omit<InputProps, 'numeric' | 'type' | 'dir'> {
918
966
  /** نوع القيمة — يضبط لوحة المفاتيح والتلميح فقط، لا يفرض تحقّقاً */
919
967
  kind?: TechnicalKind;
@@ -947,8 +995,6 @@ declare function ColorField({ label, note, value, onChange, disabled, id: idProp
947
995
  disabled?: boolean;
948
996
  id?: string;
949
997
  }): react.JSX.Element;
950
- /** يرجّع `#RRGGBB` بحروف كبيرة، أو `null` لو القيمة ليست لوناً بعد */
951
- declare function normalizeHex(input: string): string | null;
952
998
 
953
999
  interface Product3DViewerProps {
954
1000
  /** رابط الموديل — GLB أو GLTF */
@@ -992,6 +1038,7 @@ interface TabItem {
992
1038
  count?: number;
993
1039
  icon?: ComponentType<{
994
1040
  size?: number;
1041
+ color?: string;
995
1042
  }>;
996
1043
  }
997
1044
  /**
@@ -1029,6 +1076,23 @@ declare function FilterChips({ chips, onClearAll, label, clearAllLabel, }: {
1029
1076
  clearAllLabel?: string;
1030
1077
  }): react.JSX.Element | null;
1031
1078
 
1079
+ /**
1080
+ * أنماط الأسطح — **مشتركة بين الويب والنيتف**.
1081
+ * نفس سبب `Display.variants.ts`.
1082
+ *
1083
+ * ── واللي بيخصّ الويب مفصول صراحةً ───────────────────────────────────────
1084
+ * التموضع الثابت (`fixed inset-0 z-50`) والتبلير والحركات كلها بتخصّ
1085
+ * المتصفّح — RN بيرسم الأسطح جوّه `<Modal>` وهو بيتكفّل بالطبقة. الثوابت
1086
+ * اللي فيها `WEB` في اسمها هي دي.
1087
+ */
1088
+
1089
+ declare const MODAL_WIDTHS: {
1090
+ readonly sm: "max-w-md";
1091
+ readonly md: "max-w-xl";
1092
+ readonly lg: "max-w-3xl";
1093
+ };
1094
+ type ModalSize = keyof typeof MODAL_WIDTHS;
1095
+
1032
1096
  /**
1033
1097
  * الـaction sheet — كل حاجة بتطلع من تحت على الموبايل.
1034
1098
  *
@@ -1052,7 +1116,7 @@ declare function Modal({ open, title, description, onClose, footer, children, si
1052
1116
  onClose: () => void;
1053
1117
  footer?: ReactNode;
1054
1118
  children?: ReactNode;
1055
- size?: 'sm' | 'md' | 'lg';
1119
+ size?: ModalSize;
1056
1120
  closeLabel?: string;
1057
1121
  }): react.JSX.Element | null;
1058
1122
  /** بيفتح من inline-end — الشمال في العربي واليمين في الإنجليزي، لوحده */
@@ -1085,13 +1149,20 @@ declare function Toast({ children, action, icon, }: {
1085
1149
  declare function EmptyState({ icon: Icon, title, description, action, }: {
1086
1150
  icon?: ComponentType<{
1087
1151
  size?: number;
1152
+ color?: string;
1088
1153
  }>;
1089
1154
  title: ReactNode;
1090
1155
  description?: ReactNode;
1091
1156
  action?: ReactNode;
1092
1157
  }): react.JSX.Element;
1093
1158
 
1159
+ /**
1160
+ * أنماط التوستات والتلميحة — **مشتركة بين الويب والنيتف**.
1161
+ * نفس سبب `Display.variants.ts`.
1162
+ */
1163
+
1094
1164
  type ToastTone = Extract<Tone, 'brand' | 'green' | 'amber' | 'red'> | 'neutral';
1165
+
1095
1166
  interface ToastItem {
1096
1167
  id: number;
1097
1168
  tone: ToastTone;
@@ -1175,6 +1246,15 @@ declare function Tooltip({ content, children, side, }: {
1175
1246
  side?: 'top' | 'bottom';
1176
1247
  }): react.JSX.Element;
1177
1248
 
1249
+ /**
1250
+ * أنماط القوايم وفلترتها — **مشتركة بين الويب والنيتف**.
1251
+ *
1252
+ * القاعدة اللي المكتبة الأصلية بتقولها في قسم ٠٣:
1253
+ * أقل من ٦ خيارات → أزرار مجزّأة (`Tabs variant="segmented"`)
1254
+ * ٦ لـ١٥ خيار → `Dropdown` من غير بحث
1255
+ * أكتر من ١٥ → `Combobox` ببحث
1256
+ */
1257
+
1178
1258
  interface Option {
1179
1259
  value: string;
1180
1260
  label: string;
@@ -1183,6 +1263,15 @@ interface Option {
1183
1263
  icon?: ReactNode;
1184
1264
  disabled?: boolean;
1185
1265
  }
1266
+ interface CommandItem {
1267
+ id: string;
1268
+ title: string;
1269
+ meta?: string;
1270
+ icon?: ReactNode;
1271
+ group: string;
1272
+ onRun?: () => void;
1273
+ }
1274
+
1186
1275
  declare function Dropdown({ label, value, onChange, options, placeholder, className, }: {
1187
1276
  label?: ReactNode;
1188
1277
  value: string | null;
@@ -1216,14 +1305,6 @@ declare function MultiSelect({ label, values, onChange, options, placeholder, cr
1216
1305
  onCreate?: (query: string) => void;
1217
1306
  className?: string;
1218
1307
  }): react.JSX.Element;
1219
- interface CommandItem {
1220
- id: string;
1221
- title: string;
1222
- meta?: string;
1223
- icon?: ReactNode;
1224
- group: string;
1225
- onRun?: () => void;
1226
- }
1227
1308
  /**
1228
1309
  * لوحة الأوامر — ⌘K.
1229
1310
  *
@@ -1244,6 +1325,7 @@ interface AccordionItem {
1244
1325
  description?: ReactNode;
1245
1326
  icon?: ComponentType<{
1246
1327
  size?: number;
1328
+ color?: string;
1247
1329
  }>;
1248
1330
  children: ReactNode;
1249
1331
  }
@@ -1396,6 +1478,7 @@ declare function presets(today: Date): {
1396
1478
  label: string;
1397
1479
  range: Range;
1398
1480
  }[];
1481
+
1399
1482
  declare function DateRangePicker({ value, onChange, month, onMonthChange, today, className, }: {
1400
1483
  value: Range;
1401
1484
  onChange: (range: Range) => void;
@@ -1407,6 +1490,10 @@ declare function DateRangePicker({ value, onChange, month, onMonthChange, today,
1407
1490
  className?: string;
1408
1491
  }): react.JSX.Element;
1409
1492
 
1493
+ /**
1494
+ * أنماط الرفع وصيغته — **مشتركة بين الويب والنيتف**.
1495
+ * نفس سبب `Display.variants.ts`.
1496
+ */
1410
1497
  type UploadState = 'uploading' | 'done' | 'rejected';
1411
1498
  interface UploadFile {
1412
1499
  id: string;
@@ -1418,10 +1505,11 @@ interface UploadFile {
1418
1505
  progress?: number;
1419
1506
  /** سبب الرفض — لازم يتكتب، «فشل» لوحدها مش معلومة */
1420
1507
  error?: string;
1421
- /** رابط معاينة (object URL أو data URI) */
1508
+ /** رابط معاينة — `object URL` على الويب و`uri` من المنتقي على النيتف */
1422
1509
  preview?: string;
1423
1510
  }
1424
1511
  declare function formatBytes(bytes: number): string;
1512
+
1425
1513
  declare function Dropzone({ onFiles, accept, multiple, disabled, title, hint, buttonLabel, className, }: {
1426
1514
  onFiles: (files: File[]) => void;
1427
1515
  accept?: string;
@@ -1643,6 +1731,8 @@ interface BrowserFrameProps {
1643
1731
  }
1644
1732
  declare function BrowserFrame({ url, device, tab, nav, loading, contentWidth, onScale, onReload, children, className, }: BrowserFrameProps): react.JSX.Element;
1645
1733
 
1734
+ type ShareTone = 'brand' | 'amber' | 'red' | 'muted';
1735
+
1646
1736
  interface BarSeries {
1647
1737
  label: string;
1648
1738
  values: number[];
@@ -1739,7 +1829,7 @@ interface ShareItem {
1739
1829
  */
1740
1830
  trailing?: ReactNode;
1741
1831
  /** لون الشريط — الافتراضي لون العلامة */
1742
- tone?: 'brand' | 'amber' | 'red' | 'muted';
1832
+ tone?: ShareTone;
1743
1833
  }
1744
1834
  /**
1745
1835
  * قائمة بحصص — للفئات المرتّبة (المصادر، المنتجات، المدن).
@@ -1777,6 +1867,14 @@ declare function ShareList({ items, total, layout, showPercent, labelWidth, form
1777
1867
  className?: string;
1778
1868
  }): react.JSX.Element;
1779
1869
 
1870
+ /**
1871
+ * حسابات رسوم التجارة وأنماطها — **مشتركة بين الويب والنيتف**.
1872
+ *
1873
+ * الحسابات هنا **إجابات على أسئلة تاجر**، لا أشكال: «أكبر خصم فين؟»
1874
+ * و«كام صنف بيعمل ٨٠٪؟» و«المخزن هيكفي كام يوم؟». نسخها معناها إن
1875
+ * الرقم اللي التاجر بيتصرّف على أساسه يفرق بين شاشة وشاشة.
1876
+ */
1877
+
1780
1878
  interface WaterfallStep {
1781
1879
  key: string;
1782
1880
  label: ReactNode;
@@ -1785,6 +1883,36 @@ interface WaterfallStep {
1785
1883
  /** سطر يشرح الخصم — «٤٪ عمولة بوّابة الدفع» */
1786
1884
  meta?: ReactNode;
1787
1885
  }
1886
+ interface ParetoItem {
1887
+ key: string;
1888
+ label: ReactNode;
1889
+ value: number;
1890
+ }
1891
+ interface RunwayItem {
1892
+ key: string;
1893
+ label: ReactNode;
1894
+ /** ما في المخزن الآن */
1895
+ stock: number;
1896
+ /** متوسّط ما يُباع في اليوم */
1897
+ perDay: number;
1898
+ }
1899
+
1900
+ /**
1901
+ * الشلّال — من إجمالي البيع إلى ما يصل جيبك.
1902
+ *
1903
+ * ── لماذا هو أهمّ رسم للتاجر ───────────────────────────────────────────
1904
+ * التاجر يعرف كم باع ولا يعرف كم كسب. «بعت ٧١ ألفاً» رقم يُقال، و«وصلك
1905
+ * ٢٧» رقم يُتصرّف بناءً عليه — والفرق بينهما هو الشلّال كلّه.
1906
+ *
1907
+ * ── ولماذا مدرّج لا أعمدة ──────────────────────────────────────────────
1908
+ * كل خطوة تبدأ من حيث انتهت السابقة، فالنزول **يُرى** لا يُحسب. الأعمدة
1909
+ * المستقلّة تجعل العين تطرح الأرقام بنفسها، وهذا بالضبط ما جاء الرسم
1910
+ * ليوفّره.
1911
+ *
1912
+ * ── وأكبر خصم يُعلَّم ──────────────────────────────────────────────────
1913
+ * كما في `FunnelChart`: البند الذي يأكل أكثر من غيره هو المكان الوحيد
1914
+ * الذي يستحقّ عملاً هذا الشهر، والباقي يبقى محايداً حتى لا يزاحمه.
1915
+ */
1788
1916
  declare function WaterfallChart({ total, steps, totalLabel, netLabel, formatValue, className, }: {
1789
1917
  /** نقطة البداية — إجمالي المبيعات قبل أي خصم */
1790
1918
  total: number;
@@ -1813,11 +1941,6 @@ pace, label, formatValue, className, }: {
1813
1941
  formatValue?: (v: number) => string;
1814
1942
  className?: string;
1815
1943
  }): react.JSX.Element;
1816
- interface ParetoItem {
1817
- key: string;
1818
- label: ReactNode;
1819
- value: number;
1820
- }
1821
1944
  /**
1822
1945
  * كم صنفاً يصنع معظم المبيعات.
1823
1946
  *
@@ -1836,14 +1959,6 @@ declare function ParetoChart({ items, height, threshold, formatValue, className,
1836
1959
  formatValue?: (v: number) => string;
1837
1960
  className?: string;
1838
1961
  }): react.JSX.Element;
1839
- interface RunwayItem {
1840
- key: string;
1841
- label: ReactNode;
1842
- /** ما في المخزن الآن */
1843
- stock: number;
1844
- /** متوسّط ما يُباع في اليوم */
1845
- perDay: number;
1846
- }
1847
1962
  /**
1848
1963
  * كم يوماً يكفي المخزون.
1849
1964
  *
@@ -2001,6 +2116,26 @@ declare function useAudioLevel(ref: RefObject<HTMLMediaElement | null>, { bands,
2001
2116
  }): AudioLevel;
2002
2117
 
2003
2118
  type ProviderLevel = 1 | 2 | 3;
2119
+ declare const PROVIDER_LEVEL_LABEL: Record<ProviderLevel, string>;
2120
+ declare const PROVIDER_LEVEL_LABEL_EN: Record<ProviderLevel, string>;
2121
+ /**
2122
+ * المقاسين.
2123
+ *
2124
+ * `sm` أربعة وعشرين — وده **حدّ الهدف اللمسي** لا رقم مختار. الشارة
2125
+ * بتاخد تركيز، واللي بياخد تركيز بيتضغط عليه. وعلى الموبايل ده أهمّ لا أقلّ.
2126
+ */
2127
+ declare const SIZES: {
2128
+ readonly sm: {
2129
+ readonly box: "size-6";
2130
+ readonly mark: 14;
2131
+ };
2132
+ readonly md: {
2133
+ readonly box: "size-7";
2134
+ readonly mark: 16;
2135
+ };
2136
+ };
2137
+ type ProviderBadgeSize = keyof typeof SIZES;
2138
+
2004
2139
  /**
2005
2140
  * التسميات جوّه المكتبة لا في التطبيق.
2006
2141
  *
@@ -2009,8 +2144,6 @@ type ProviderLevel = 1 | 2 | 3;
2009
2144
  * المكوّن زي أسماء العملات في `Money` بالظبط — وهنا هو **الاسم
2010
2145
  * المتاح الوحيد**، فتفرّقه بيدّي شارتين مالهمش علاقة ببعض.
2011
2146
  */
2012
- declare const PROVIDER_LEVEL_LABEL: Record<ProviderLevel, string>;
2013
- declare const PROVIDER_LEVEL_LABEL_EN: Record<ProviderLevel, string>;
2014
2147
  interface ProviderMarkProps {
2015
2148
  level: ProviderLevel;
2016
2149
  /** ضلع المربّع بالبكسل */
@@ -2023,23 +2156,6 @@ interface ProviderMarkProps {
2023
2156
  * بلا `aria-label`: العلامة زينة جوّه `ProviderBadge` اللي بيحمل الاسم.
2024
2157
  */
2025
2158
  declare function ProviderMark({ level, size, className }: ProviderMarkProps): react.JSX.Element;
2026
- /**
2027
- * المقاسين.
2028
- *
2029
- * `sm` أربعة وعشرين — وده **حدّ الهدف اللمسي** لا رقم مختار. الشارة
2030
- * بتاخد تركيز (تحت)، واللي بياخد تركيز بيتضغط عليه.
2031
- */
2032
- declare const SIZES: {
2033
- readonly sm: {
2034
- readonly box: "size-6";
2035
- readonly mark: 14;
2036
- };
2037
- readonly md: {
2038
- readonly box: "size-7";
2039
- readonly mark: 16;
2040
- };
2041
- };
2042
- type ProviderBadgeSize = keyof typeof SIZES;
2043
2159
  interface ProviderBadgeProps {
2044
2160
  level: ProviderLevel;
2045
2161
  /**
@@ -2203,6 +2319,13 @@ declare function Coach({ id, asChild, children, }: {
2203
2319
  children: ReactNode;
2204
2320
  }): react.JSX.Element;
2205
2321
 
2322
+ /**
2323
+ * أنماط كروت الاختيار والسبارك‑لاين — **مشتركة بين الويب والنيتف**.
2324
+ * نفس سبب `Display.variants.ts`.
2325
+ */
2326
+
2327
+ type SparkTone = 'brand' | 'green' | 'red' | 'muted';
2328
+
2206
2329
  interface ChoiceOption {
2207
2330
  value: string;
2208
2331
  label: ReactNode;
@@ -2212,6 +2335,7 @@ interface ChoiceOption {
2212
2335
  icon?: ComponentType<{
2213
2336
  size?: number;
2214
2337
  strokeWidth?: number;
2338
+ color?: string;
2215
2339
  }>;
2216
2340
  disabled?: boolean;
2217
2341
  /** سبب التعطيل — «معطّل» من غير سبب بيسيب المستخدم واقف */
@@ -2273,12 +2397,40 @@ declare function Sparkline({ values, width, height, tone, fluid, className, }: {
2273
2397
  values: number[];
2274
2398
  width?: number;
2275
2399
  height?: number;
2276
- tone?: 'brand' | 'green' | 'red' | 'muted';
2400
+ tone?: SparkTone;
2277
2401
  /** يملا عرض الحاوية بدل المقاس الثابت — `width` بيبقى نسبة الرسم */
2278
2402
  fluid?: boolean;
2279
2403
  className?: string;
2280
2404
  }): react.JSX.Element | null;
2281
2405
 
2406
+ /**
2407
+ * أنماط مكوّنات العرض — **مشتركة بين الويب والنيتف**.
2408
+ *
2409
+ * ══ ليه الملف ده موجود ═══════════════════════════════════════════════════
2410
+ * `buttonClasses` كانت في `lib.ts` من الأول، فـ`Button.tsx` و
2411
+ * `Button.native.tsx` بيوصلوا لنفس السلسلة بلا مجهود.
2412
+ *
2413
+ * باقي المكوّنات مكانتش كده: أنماط `Badge` و`Card` و`Progress` كانت
2414
+ * **مكتوبة جوّه `Display.tsx`** — وهي المكان الصح ما دام فيه منصّة واحدة.
2415
+ *
2416
+ * وأول ما بقى فيه اتنين، الكتابة جوّه المكوّن معناها **نسختين**: تغيير
2417
+ * حشوة الشارة بيتعمل مرتين، وأول مرة حد ينسى واحدة الشارة بتفرق بين
2418
+ * الويب والموبايل — من غير خطأ ولا تحذير.
2419
+ *
2420
+ * ودي بالظبط الحتة اللي الطلب اتكتب عشانها: «تعديل في التوكنز أو
2421
+ * الأنماط أو المقاسات يوصل لكل المنصّات من مصدر واحد».
2422
+ *
2423
+ * ── والملف ده مالوش React ────────────────────────────────────────────────
2424
+ * نصوص وخرايط وبس — زي `lib.ts` بالظبط. يعني بيعدّي حدّ RSC بلا
2425
+ * `"use client"`، والنيتف بياخده من غير ما يجرّ DOM.
2426
+ *
2427
+ * ── والقاعدة: أي نمط بيتشاف على المنصّتين مكانه هنا ─────────────────────
2428
+ * اللي بيفضل جوّه ملف المنصّة هو اللي **بيخصّها هي**: `overflow-clip`
2429
+ * بتاعة الويب مثلاً، أو تخطيط `<Modal>` بتاع RN.
2430
+ */
2431
+
2432
+ type AvatarSize = 'xs' | 'sm' | 'md' | 'lg';
2433
+
2282
2434
  interface BadgeProps {
2283
2435
  children: ReactNode;
2284
2436
  tone?: Tone;
@@ -2295,7 +2447,6 @@ declare function Counter({ value, max }: {
2295
2447
  value: number;
2296
2448
  max?: number;
2297
2449
  }): react.JSX.Element | null;
2298
- type AvatarSize = 'xs' | 'sm' | 'md' | 'lg';
2299
2450
  declare function Avatar({ name, src, size, square, className, }: {
2300
2451
  name: string;
2301
2452
  src?: string;
@@ -2308,6 +2459,7 @@ interface StatCardProps {
2308
2459
  icon?: ComponentType<{
2309
2460
  size?: number;
2310
2461
  strokeWidth?: number;
2462
+ color?: string;
2311
2463
  }>;
2312
2464
  tone?: Tone;
2313
2465
  label: ReactNode;
@@ -2377,4 +2529,4 @@ declare function Skeleton({ variant, width, className, }: {
2377
2529
  className?: string;
2378
2530
  }): react.JSX.Element;
2379
2531
 
2380
- export { ANIMATE_SCALE, Accordion, type AccordionItem, Alert, type Animation, type AudioLevel, AudioPlayer, type AudioPlayerProps, Avatar, type AvatarSize, Badge, type BadgeProps, BarChart, type BarSeries, BrowserFrame, type BrowserFrameProps, Button, type ButtonProps, ButtonSize, ButtonVariant, COLOR_SCALE, CONTAINER_SCALE, Card, CardHeader, Carousel, type CarouselProps, type Chapter, Checkbox, ChoiceCards, type ChoiceOption, type ChoiceProps, Coach, type CoachApi, type CoachAudio, type CoachHint, type CoachItem, type CoachLine, type CoachOrb, CoachProvider, type CoachProviderProps, type CoachRegion, type CoachWhen, type CoachWhere, ColorField, type ColorToken, type Column, Combobox, type CommandItem, CommandPalette, type Container, Counter, type Currency, DARK_TOKENS, DataTable, type DataTableProps, DateRangePicker, Drawer, Dropdown, Dropzone, EmptyState, type FieldSize, FileRow, type FilterChip, FilterChips, FunnelChart, type FunnelStage, Gallery, type GalleryImage, type GalleryProps, GoalBar, Heatmap, Input, type InputProps, Lightbox, type LightboxProps, LocaleCtx, type MediaState, Modal, Money, type MoneyProps, MoneyProvider, MultiSelect, NumberStepper, type NumberStepperProps, type Option, PROVIDER_LEVEL_LABEL, PROVIDER_LEVEL_LABEL_EN, PageHeader, ParetoChart, type ParetoItem, Phone, type PhoneFormat, type PhoneParts, type PhoneProps, Product3DViewer, type Product3DViewerProps, Progress, ProviderBadge, type ProviderBadgeProps, type ProviderBadgeSize, type ProviderLevel, ProviderMark, type ProviderMarkProps, RADIUS_SCALE, Radio, RadioGroup, type Radius, type Range, RatingInput, type RatingInputProps, type RunwayItem, SHADOW_SCALE, Scrubber, SearchInput, Select, type SelectProps, type Shadow, type ShareItem, ShareList, Sheet, Skeleton, type SortableApi, type SortableItemProps, SortableStatus, Sparkline, Stars, type StarsProps, StatCard, type StatCardProps, Stepper, type StepperStep, StockRunway, Switch, type SymbolStyle, TEXT_SCALE, TOKENS, type TabItem, Tabs, TechnicalInput, type TechnicalInputProps, type TechnicalKind, TechnicalText, type TextSize, Textarea, type TextareaProps, Timeline, type TimelineStep, Toast, ToastHost, type ToastInput, type ToastItem, type ToastTone, type TokenName, Tone, Tooltip, TrendChart, type UITextKey, type UploadFile, type UploadState, type UseSortableOptions, VerifiedBadge, type VerifiedBadgeProps, VideoPlayer, type VideoPlayerProps, type VideoSuggestion, WaterfallChart, type WaterfallStep, WhatsAppIcon, coachSeconds, currencyName, currencySymbol, daysBetween, formatBytes, formatDate, formatRange, formatTime, isCurrency, normalizeHex, parsePhone, presets, useAudioLevel, useCoach, useCoachOptional, useCurrency, useCurrencySymbol, useMedia, useMoneyLang, useMoneyLocale, useSortable, useToasts, useUIText };
2532
+ export { ANIMATE_SCALE, Accordion, type AccordionItem, Alert, type Animation, type AudioLevel, AudioPlayer, type AudioPlayerProps, Avatar, type AvatarSize, Badge, type BadgeProps, BarChart, type BarSeries, BrowserFrame, type BrowserFrameProps, Button, type ButtonProps, ButtonSize, ButtonVariant, COLOR_SCALE, CONTAINER_SCALE, Card, CardHeader, Carousel, type CarouselProps, type Chapter, Checkbox, ChoiceCards, type ChoiceOption, type ChoiceProps, Coach, type CoachApi, type CoachAudio, type CoachHint, type CoachItem, type CoachLine, type CoachOrb, CoachProvider, type CoachProviderProps, type CoachRegion, type CoachWhen, type CoachWhere, ColorField, type ColorToken, type Column, Combobox, type CommandItem, CommandPalette, type Container, Counter, type Currency, DARK_TOKENS, DataTable, type DataTableProps, DateRangePicker, Drawer, Dropdown, Dropzone, EmptyState, type FieldSize, FileRow, type FilterChip, FilterChips, FunnelChart, type FunnelStage, Gallery, type GalleryImage, type GalleryProps, GoalBar, Heatmap, Input, type InputProps, Lightbox, type LightboxProps, LocaleCtx, type MediaState, Modal, Money, type MoneyProps, MoneyProvider, MultiSelect, NumberStepper, type NumberStepperProps, type Option, PROVIDER_LEVEL_LABEL, PROVIDER_LEVEL_LABEL_EN, PageHeader, ParetoChart, type ParetoItem, Phone, type PhoneFormat, type PhoneParts, type PhoneProps, Product3DViewer, type Product3DViewerProps, Progress, ProviderBadge, type ProviderBadgeProps, type ProviderBadgeSize, type ProviderLevel, ProviderMark, type ProviderMarkProps, RADIUS_SCALE, Radio, RadioGroup, type Radius, type Range, RatingInput, type RatingInputProps, type RunwayItem, SHADOW_SCALE, Scrubber, SearchInput, Select, type SelectProps, type Shadow, type ShareItem, ShareList, Sheet, Skeleton, type SortableApi, type SortableItemProps, SortableStatus, Sparkline, Stars, type StarsProps, StatCard, type StatCardProps, Stepper, type StepperStep, StockRunway, Switch, type SymbolStyle, TEXT_SCALE, TOKENS, type TabItem, Tabs, TechnicalInput, type TechnicalInputProps, type TechnicalKind, TechnicalText, type TextSize, Textarea, type TextareaProps, Timeline, type TimelineStep, Toast, ToastHost, type ToastInput, type ToastItem, type ToastTone, type TokenName, Tone, Tooltip, TrendChart, type UITextKey, type UploadFile, type UploadState, type UseSortableOptions, VerifiedBadge, type VerifiedBadgeProps, VideoPlayer, type VideoPlayerProps, type VideoSuggestion, WaterfallChart, type WaterfallStep, WhatsAppIcon, coachSeconds, currencyName, currencySymbol, daysBetween, formatBytes, formatDate, formatRange, formatTime, isCurrency, normalizeHex, parsePhone, presets, setLang, useAudioLevel, useCoach, useCoachOptional, useCurrency, useCurrencySymbol, useMedia, useMoneyLang, useMoneyLocale, useSortable, useToasts, useUIText };