@mobielnl/elements 0.5.0 → 0.7.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.
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { r as pt, t as Z, i as Re, a as q, n as De, p as mt, b as fn, c as Ve, d as pn, v as mn, e as gn, f as x, g as le, s as vn, h as yn, j as Ie, k as H, l as gt, m as Y, o as bn, q as Tn, u as te, w as ue, x as I, y as ne, z as Vn, A as An, B as vt, C as Ne, D as Sn, E as wn, F as Pn, G as D, H as yt, I as bt, J as Tt, K as je, L as Vt, M as xn, N as Cn, O as Mn, P as ze, Q as Fn, R as On, S as Rn, T as Dn, U as In, V as Nn, W as Kn, X as En, Y as Bn, Z as Ln, _ as kn } from "./index-Bqq_Hib9.js";
2
+ import { r as pt, t as Z, i as Re, a as q, n as De, p as mt, b as fn, c as Ve, d as pn, v as mn, e as gn, f as x, g as le, s as vn, h as yn, j as Ie, k as H, l as gt, m as Y, o as bn, q as Tn, u as te, w as ue, x as I, y as ne, z as Vn, A as An, B as vt, C as Ne, D as Sn, E as wn, F as Pn, G as D, H as yt, I as bt, J as Tt, K as je, L as Vt, M as xn, N as Cn, O as Mn, P as ze, Q as Fn, R as On, S as Rn, T as Dn, U as In, V as Nn, W as Kn, X as En, Y as Bn, Z as Ln, _ as kn } from "./index-C4M3Nf9p.js";
3
3
  import { Fragment as _n } from "react";
4
4
  var ae = typeof globalThis < "u" && globalThis.process ? globalThis.process : { env: { NODE_ENV: "production" } };
5
5
  function At(t, e) {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,10 @@
1
+ import { Component } from 'react';
2
+ import { ErrorInfo } from 'react';
1
3
  import { JSX } from 'react/jsx-runtime';
4
+ import { JSXElementConstructor } from 'react';
5
+ import { ReactElement } from 'react';
2
6
  import { ReactNode } from 'react';
7
+ import { ReactPortal } from 'react';
3
8
  import { z } from 'zod';
4
9
  import * as z_2 from 'zod';
5
10
 
@@ -96,6 +101,57 @@ export declare type ElementsRootProps = {
96
101
  };
97
102
  };
98
103
 
104
+ export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
105
+ state: ErrorBoundaryState;
106
+ static getDerivedStateFromError(_error: Error): ErrorBoundaryState;
107
+ componentDidCatch(error: Error, _errorInfo: ErrorInfo): void;
108
+ render(): string | number | bigint | boolean | Iterable<ReactNode> | Promise<string | number | bigint | boolean | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | JSX.Element | null | undefined;
109
+ }
110
+
111
+ export declare type ErrorBoundaryProps = {
112
+ /** The content to be wrapped by the ErrorBoundary */
113
+ children: ReactNode;
114
+ /** Callback function called when an error is caught */
115
+ onError?: (error: Error) => void;
116
+ /** Custom fallback UI to render when an error occurs */
117
+ fallback?: ReactNode;
118
+ };
119
+
120
+ export declare type ErrorBoundaryState = {
121
+ hasError: boolean;
122
+ };
123
+
124
+ export declare function ErrorComponent({ classNames }: ErrorComponentProps): JSX.Element;
125
+
126
+ export declare type ErrorComponentClassNames = {
127
+ /** Main wrapper container for the error component */
128
+ base?: string;
129
+ /** Alert component class styling slots */
130
+ alert?: {
131
+ /** Alert container */
132
+ base?: string;
133
+ /** Alert title text */
134
+ title?: string;
135
+ /** Alert description text */
136
+ description?: string;
137
+ /** Alert main content wrapper */
138
+ mainWrapper?: string;
139
+ /** Alert close button */
140
+ closeButton?: string;
141
+ /** Alert icon wrapper */
142
+ iconWrapper?: string;
143
+ /** Alert icon */
144
+ alertIcon?: string;
145
+ };
146
+ /** Refresh page button */
147
+ button?: string;
148
+ };
149
+
150
+ export declare type ErrorComponentProps = {
151
+ /** Class slots for styling */
152
+ classNames?: ErrorComponentClassNames;
153
+ };
154
+
99
155
  export declare function FilterChip({ filter, filterOption, onRemove, classNames, }: FilterChipProps): JSX.Element | null;
100
156
 
101
157
  declare type FilterChipClassNames = {
@@ -234,6 +290,11 @@ declare type GetPageByPathQuery = {
234
290
  } | null;
235
291
  };
236
292
 
293
+ declare type LabelClassNames = {
294
+ wrapper?: string;
295
+ text?: string;
296
+ };
297
+
237
298
  declare type ListBoxClassNames = {
238
299
  base?: string;
239
300
  wrapper?: string;
@@ -282,6 +343,97 @@ declare type ModalClassNames_2 = {
282
343
  closeButton?: string;
283
344
  };
284
345
 
346
+ declare type ModalClassNames_3 = {
347
+ /** The backdrop slot, it is displayed behind the modal */
348
+ backdrop?: string;
349
+ /** The wrapper slot of the modal. It wraps the base and the backdrop slots */
350
+ wrapper?: string;
351
+ /** The main slot of the modal content */
352
+ base?: string;
353
+ /** The header of the modal, it is displayed at the top of the modal */
354
+ header?: string;
355
+ /** The body of the modal, it is displayed in the middle of the modal */
356
+ body?: string;
357
+ /** The footer of the modal, it is displayed at the bottom of the modal */
358
+ footer?: string;
359
+ /** The close button (X) of the modal in top-right corner */
360
+ closeButton?: string;
361
+ };
362
+
363
+ declare type NumberPreservationModalClassNames = {
364
+ /** Modal dialog class styling slots - see type `ModalClassNames` */
365
+ modal?: ModalClassNames_3;
366
+ /** Header section containing icon and title */
367
+ header?: {
368
+ /** Container wrapping the header content */
369
+ container?: string;
370
+ /** Icon wrapper with background (contains "06" text) */
371
+ iconWrapper?: string;
372
+ /** Main title text */
373
+ title?: string;
374
+ /** Description text below title */
375
+ description?: string;
376
+ };
377
+ /** Form section for number input */
378
+ form?: {
379
+ /** Form element container */
380
+ container?: string;
381
+ /** Input field styling slots */
382
+ input?: {
383
+ /** Input wrapper styling */
384
+ inputWrapper?: string;
385
+ /** Input element styling */
386
+ input?: string;
387
+ };
388
+ };
389
+ /** Provider selection section */
390
+ provider?: {
391
+ /** Select component styling */
392
+ select?: {
393
+ /** Select label styling */
394
+ label?: string;
395
+ /** Select trigger button styling */
396
+ trigger?: string;
397
+ /** Provider item container in select */
398
+ itemContainer?: string;
399
+ /** Provider icon styling */
400
+ icon?: string;
401
+ };
402
+ };
403
+ /** Options section (Ja/Nee buttons) */
404
+ options?: {
405
+ /** Container for the option buttons */
406
+ container?: string;
407
+ /** Option button styling */
408
+ button?: string;
409
+ /** Button content wrapper */
410
+ buttonContent?: string;
411
+ /** Button label text */
412
+ buttonLabel?: string;
413
+ /** Button description text */
414
+ buttonDescription?: string;
415
+ /** Button icon styling */
416
+ buttonIcon?: string;
417
+ };
418
+ /** Radio group for subscription type selection */
419
+ radioGroup?: {
420
+ /** Radio group base styling */
421
+ base?: string;
422
+ /** Radio group wrapper styling */
423
+ wrapper?: string;
424
+ /** Radio group label styling */
425
+ label?: string;
426
+ /** Radio group description styling */
427
+ description?: string;
428
+ /** Radio group error message styling */
429
+ errorMessage?: string;
430
+ /** Radio styling */
431
+ radio?: string;
432
+ };
433
+ /** Submit button styling */
434
+ submitButton?: string;
435
+ };
436
+
285
437
  declare type PhoneListContainerClassNames = {
286
438
  base?: string;
287
439
  wrapper?: string;
@@ -445,7 +597,7 @@ export declare type PricingSectionProps = Pick<PropositionCardProps, 'onInfoClic
445
597
 
446
598
  declare type ProductCategory = 'sim-only-proposition' | 'fixed-proposition' | 'smartphone-proposition' | 'smartphone-proposition-extended';
447
599
 
448
- export declare function ProductResults({ productCategory, initialSelectedFilters, limit, classNames, profile, onProfileChange, }: ProductResultsProps): JSX.Element;
600
+ export declare function ProductResults({ productCategory, initialSelectedFilters, limit, classNames, initialProfile, texts, showTopPropositions, onProfileChange, onError, }: ProductResultsProps): JSX.Element;
449
601
 
450
602
  /**
451
603
  * ClassNames for styling different parts of the `ProductResults` component
@@ -462,36 +614,43 @@ export declare type ProductResultsClassNames = {
462
614
  /** Filter button (only on mobile & tablet screens) */
463
615
  filterButton?: string;
464
616
  /** Filter modal class styling slots - see type `ModalClassNames` */
465
- modal?: ModalClassNames;
466
- /** Grid wrapper of the results */
467
- resultsGrid?: string;
468
- /** Credit info component class styling slots - see type `CreditInfoClassNames` */
469
- creditInfo?: CreditInfoClassNames;
470
- /** Load more button */
471
- loadMoreButton?: string;
472
- /** Results not found component class styling slots - see type `ResultsNotFoundClassNames` */
473
- resultsNotFound?: ResultsNotFoundClassNames;
474
- /** Proposition card class styling slots - see type `PropositionCardClassNames` */
475
- propositionCard?: PropositionCardClassNames;
476
- /** PostcodeCheck loading card class styling slots (only for fixed propositions) - see type `PostcodeCheckLoadingClassNames` */
477
- postcodeCheckLoading?: PostcodeCheckLoadingClassNames;
617
+ filterModal?: ModalClassNames;
478
618
  /** Postcode check modal class styling slots - see type `PostcodeCheckModalClassNames` */
479
619
  postcodeCheckModal?: PostcodeCheckModalClassNames;
620
+ /** Number preservation modal class styling slots - see type `NumberPreservationModalClassNames` */
621
+ numberPreservationModal?: NumberPreservationModalClassNames;
622
+ /** Results class styling slots - see type `ResultsClassNames` */
623
+ results?: ResultsClassNames;
480
624
  };
481
625
 
482
626
  export declare type ProductResultsProps = {
483
627
  /** Product type of the results */
484
628
  productCategory: Exclude<ProductCategory, 'smartphone-proposition-extended'>;
629
+ /** Whether to show the dynamic top 3 propositions based on the user's profile
630
+ *
631
+ * Not available for smartphone propositions when no phone is selected */
632
+ showTopPropositions?: boolean;
633
+ /** Customize texts */
634
+ texts?: {
635
+ /** Title above top propositions (only shown when `showTopPropositions` is set to `true`)
636
+ * @default "Beste providers voor jou" */
637
+ topPropositionsTitle: string;
638
+ /** Title above all propositions (only shown when `showTopPropositions` is set to `true`)
639
+ * @default "Alle providers op een rijtje" */
640
+ allPropositionsTitle: string;
641
+ };
485
642
  /** Initial selected filters */
486
643
  initialSelectedFilters?: FilterValue[];
487
644
  /** Limit the number of propositions to display */
488
645
  limit?: number;
489
646
  /** Class slots for styling */
490
647
  classNames?: ProductResultsClassNames;
491
- /** User profile */
492
- profile?: Profile;
648
+ /** Initial user profile */
649
+ initialProfile?: Partial<Profile>;
493
650
  /** Callback function to handle profile changes */
494
651
  onProfileChange?: (profile: Partial<Profile>) => void;
652
+ /** Callback function called when an error occurs */
653
+ onError?: (error: Error) => void;
495
654
  };
496
655
 
497
656
  /**
@@ -547,11 +706,16 @@ export declare type PromotionsListClassNames = {
547
706
  item?: string;
548
707
  /** Checkmark icon for each promotion item */
549
708
  promotionIcon?: string;
709
+ /** Urgent text chip */
710
+ urgentChip?: string;
550
711
  };
551
712
 
552
713
  export declare type PromotionsListProps = {
553
714
  /** Promotions to display */
554
715
  promotions: string[];
716
+ /** Urgent text to display as a chip above promotions
717
+ * @example "Actie nog 6 dagen" */
718
+ urgentText?: string;
555
719
  /** Class slots for styling */
556
720
  classNames?: PromotionsListClassNames;
557
721
  };
@@ -597,21 +761,24 @@ export declare type PropositionCardClassNames = {
597
761
  /** Call To Action button
598
762
  * @example "Bekijk" */
599
763
  button?: string;
764
+ /** Card wrapper (container for the label and card) */
765
+ cardWrapper?: string;
766
+ /** Label class styling slots - see type `LabelClassNames` */
767
+ label?: LabelClassNames;
600
768
  };
601
769
 
602
770
  export declare type PropositionCardProps = {
771
+ /** Click handler on the card */
772
+ onClick: (e: {
773
+ target: Element;
774
+ }) => void;
603
775
  /** Click handler to open the details modal */
604
776
  onInfoClick: (tab: 'general' | 'conditions' | 'channels' | 'costs') => void;
605
777
  /** Whether the proposition is disabled */
606
778
  disabled?: boolean;
607
- /** Link to the proposition page */
608
- href: string;
609
- /** Product title
610
- * @example "iPhone 17" */
779
+ /** Product title - should include brand + phone name
780
+ * @example "Apple iPhone 17" */
611
781
  productTitle?: string;
612
- /** Product subtitle (brand)
613
- * @example "Apple" */
614
- productSubtitle?: string;
615
782
  /** Product image URL */
616
783
  productImageUrl?: string;
617
784
  /** Product image alt text */
@@ -658,6 +825,8 @@ export declare type PropositionCardProps = {
658
825
  /** Urgent text for urgent special promotion
659
826
  * @example "Actie nog 6 dagen" */
660
827
  urgentText?: string;
828
+ /** Label properties to display above the card */
829
+ label?: Pick<PropositionLabel, 'displayName' | 'color'>;
661
830
  /** Class slots for styling */
662
831
  classNames?: PropositionCardClassNames;
663
832
  horizontal?: boolean;
@@ -681,28 +850,51 @@ export declare type PropositionHeaderClassNames = {
681
850
  * @example "Onbp min / sms"
682
851
  * @example "Glasvezel" */
683
852
  subtitle?: string;
853
+ /** Specifications container */
854
+ specifications?: string;
684
855
  };
685
856
 
686
857
  export declare type PropositionHeaderProps = {
858
+ /** Product title (for smartphone propositions) - should include brand + phone name
859
+ * @example "Apple iPhone 17" */
860
+ productTitle?: string;
687
861
  /** Proposition title text
688
862
  * @example "30 GB"
689
863
  * @example "100 Mb/s" */
690
- title: string;
864
+ propositionTitle: string;
691
865
  /** Proposition subtitle text
692
866
  * @example "Onbp min / sms"
693
867
  * @example "Glasvezel" */
694
- subtitle: string;
868
+ propositionSubtitle: string;
695
869
  /** Proposition provider image URL */
696
870
  imageUrl?: string;
697
871
  /** Proposition provider image alt text */
698
872
  imageAlt?: string;
699
873
  /** Whether the proposition has a product/phone */
700
874
  hasProduct: boolean;
875
+ /** Proposition specifications */
876
+ propositionSpecifications?: {
877
+ slug: string;
878
+ title: string;
879
+ }[];
880
+ /** Click handler to open the details modal */
881
+ onInfoClick?: (tab: 'general' | 'conditions' | 'channels' | 'costs') => void;
701
882
  /** Class slots for styling */
702
883
  classNames?: PropositionHeaderClassNames;
703
884
  horizontal?: boolean;
704
885
  };
705
886
 
887
+ declare type PropositionLabel = {
888
+ type: PropositionLabelType;
889
+ displayName: string;
890
+ rank: number;
891
+ color: PropositionLabelColor;
892
+ };
893
+
894
+ declare type PropositionLabelColor = 'primary' | 'secondary' | 'default';
895
+
896
+ declare type PropositionLabelType = 'isRetention' | 'isCheapestPhone' | 'isBudget' | 'isBudgetFiber' | 'isCombi' | 'isFastestInternet' | 'isBudgetOwnNetwork' | 'isBudgetNetwork';
897
+
706
898
  export declare function RadioFilter({ id, options, value, onChange, classNames, }: RadioFilterProps): JSX.Element;
707
899
 
708
900
  /**
@@ -756,6 +948,29 @@ export declare type RadioFilterProps = {
756
948
 
757
949
  export declare function RangeFilter({ min, max, step, value, options, maxOptionValue, marks, formatType, onChange, classNames, }: SliderFilterProps): JSX.Element;
758
950
 
951
+ declare type ResultsClassNames = {
952
+ /** Title above top propositions (only shown when `showTopPropositions` is set to `true`)
953
+ * @example "Beste providers voor jou" */
954
+ topPropositionsTitle?: string;
955
+ /** Title above all propositions (only shown when `showTopPropositions` is set to `true`)
956
+ * @example "Alle providers op een rijtje" */
957
+ allPropositionsTitle?: string;
958
+ /** Grid wrapper of the top propositions */
959
+ topPropositionsGrid?: string;
960
+ /** Grid wrapper of the all propositions */
961
+ allPropositionsGrid?: string;
962
+ /** Results not found component class styling slots - see type `ResultsNotFoundClassNames` */
963
+ resultsNotFound?: ResultsNotFoundClassNames;
964
+ /** Credit info component class styling slots - see type `CreditInfoClassNames` */
965
+ creditInfo?: CreditInfoClassNames;
966
+ /** Load more button */
967
+ loadMoreButton?: string;
968
+ /** Proposition card class styling slots - see type `PropositionCardClassNames` */
969
+ propositionCard?: PropositionCardClassNames;
970
+ /** PostcodeCheck loading card class styling slots (only for fixed propositions) - see type `PostcodeCheckLoadingClassNames` */
971
+ postcodeCheckLoading?: PostcodeCheckLoadingClassNames;
972
+ };
973
+
759
974
  declare type ResultsNotFoundClassNames = {
760
975
  filterChips?: ActiveFilterChipsClassNames & {
761
976
  /** The title element above the filter chips
@@ -862,6 +1077,58 @@ export declare type SelectFilterProps = {
862
1077
  classNames?: SelectFilterClassNames;
863
1078
  };
864
1079
 
1080
+ export declare function Selector({ classNames, onClick, disabled, title, description, imageUrl, imageAlt, Icon, avatarName, selected, }: SelectorProps): JSX.Element;
1081
+
1082
+ /**
1083
+ * ClassNames for styling different parts of the `Selector` component
1084
+ */
1085
+ export declare type SelectorClassNames = {
1086
+ /** Title text styling */
1087
+ title?: string;
1088
+ /** Description text styling */
1089
+ description?: string;
1090
+ /** Main button wrapper */
1091
+ button?: string;
1092
+ /** Badge component (visible when not selected) */
1093
+ badge?: string;
1094
+ /** Avatar component displaying the image or icon */
1095
+ avatar?: {
1096
+ /** Base wrapper styling for the avatar container */
1097
+ base?: string;
1098
+ /** Image element styling */
1099
+ img?: string;
1100
+ /** Name text styling (when displaying initials) */
1101
+ name?: string;
1102
+ /** Icon wrapper styling */
1103
+ icon?: string;
1104
+ /** Fallback content styling (when no image is available) */
1105
+ fallback?: string;
1106
+ };
1107
+ };
1108
+
1109
+ export declare type SelectorProps = {
1110
+ /** Class slots for styling */
1111
+ classNames?: SelectorClassNames;
1112
+ /** Main title text */
1113
+ title: string;
1114
+ /** Optional description text below the title */
1115
+ description?: string;
1116
+ /** Whether the selector is in selected state */
1117
+ selected?: boolean;
1118
+ /** Click handler for the selector */
1119
+ onClick: () => void;
1120
+ /** Icon component to display as fallback when no image is provided */
1121
+ Icon?: React.ElementType;
1122
+ /** Name to display as initials in the avatar when no image is available */
1123
+ avatarName?: string;
1124
+ /** Image URL for the avatar */
1125
+ imageUrl?: string | null;
1126
+ /** Alt text for the image */
1127
+ imageAlt?: string | null;
1128
+ /** Whether the selector is disabled */
1129
+ disabled?: boolean;
1130
+ };
1131
+
865
1132
  /**
866
1133
  * ClassNames for styling different parts of the `RangeFilter`, `MinFilter` and `MaxFilter` component
867
1134
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mobielnl/elements",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "Mobiel.nl Elements - React component library for partner websites",
5
5
  "private": false,
6
6
  "type": "module",
@@ -73,6 +73,7 @@
73
73
  "@react-stately/flags": "^3.1.2",
74
74
  "@storybook/addon-a11y": "^9.1.2",
75
75
  "@storybook/addon-docs": "^9.1.2",
76
+ "@storybook/blocks": "^8.6.14",
76
77
  "@storybook/react-vite": "^9.1.2",
77
78
  "@tailwindcss/vite": "^4.1.11",
78
79
  "@types/jest": "^30.0.0",