@proteos/ui 0.56.0 → 0.57.1
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/{chunk-IKAX76MB.js → chunk-NSE4VW3Z.js} +45 -21
- package/dist/chunk-NSE4VW3Z.js.map +1 -0
- package/dist/{chunk-MWAXK66H.cjs → chunk-NWGG5WFL.cjs} +45 -21
- package/dist/chunk-NWGG5WFL.cjs.map +1 -0
- package/dist/index.cjs +346 -352
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -13
- package/dist/index.d.ts +49 -13
- package/dist/index.js +93 -99
- package/dist/index.js.map +1 -1
- package/dist/{pdf-view-MH75RVQP.js → pdf-view-RQ2OZYHJ.js} +3 -3
- package/dist/{pdf-view-MH75RVQP.js.map → pdf-view-RQ2OZYHJ.js.map} +1 -1
- package/dist/{pdf-view-K4MMVHVY.cjs → pdf-view-RRMAUK3L.cjs} +7 -7
- package/dist/{pdf-view-K4MMVHVY.cjs.map → pdf-view-RRMAUK3L.cjs.map} +1 -1
- package/package.json +2 -2
- package/src/components/avatar/avatar.stories.tsx +13 -0
- package/src/components/avatar/avatar.tsx +16 -9
- package/src/components/badge-multi-select/badge-multi-select.tsx +2 -2
- package/src/components/button/button.stories.tsx +202 -97
- package/src/components/button/button.test.tsx +40 -7
- package/src/components/button/button.tsx +71 -18
- package/src/components/combobox/combobox.tsx +2 -2
- package/src/components/currency-input/currency-input.tsx +2 -2
- package/src/components/date-picker/calendar-internals.tsx +1 -1
- package/src/components/date-picker/date-picker.tsx +3 -3
- package/src/components/date-time-picker/date-time-picker.tsx +3 -3
- package/src/components/icon-picker/icon-picker.tsx +2 -2
- package/src/components/image-lightbox/image-lightbox.tsx +2 -2
- package/src/components/menu/menu.tsx +2 -2
- package/src/components/modal/modal.test.tsx +9 -0
- package/src/components/modal/modal.tsx +17 -5
- package/src/components/multi-select/multi-select.tsx +2 -2
- package/src/components/popover/popover.tsx +2 -2
- package/src/components/record-filter/nested-group.tsx +2 -2
- package/src/components/record-filter/record-filter-builder-panel.tsx +11 -23
- package/src/components/record-filter/record-filter-chips.tsx +3 -10
- package/src/components/segmented-control/segmented-control.stories.tsx +134 -8
- package/src/components/segmented-control/segmented-control.test.tsx +81 -8
- package/src/components/segmented-control/segmented-control.tsx +38 -19
- package/src/components/select/select.tsx +2 -2
- package/src/components/time-field/time-field.tsx +1 -1
- package/src/components/toast/toast.tsx +2 -2
- package/src/components/tooltip/tooltip.tsx +2 -2
- package/src/styles.css +58 -0
- package/dist/chunk-IKAX76MB.js.map +0 -1
- package/dist/chunk-MWAXK66H.cjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -113,6 +113,10 @@ declare const avatarStyles: tailwind_variants.TVReturnType<{
|
|
|
113
113
|
terra: string;
|
|
114
114
|
slate: string;
|
|
115
115
|
};
|
|
116
|
+
shape: {
|
|
117
|
+
circle: string;
|
|
118
|
+
square: string;
|
|
119
|
+
};
|
|
116
120
|
}, undefined, string[], {
|
|
117
121
|
size: {
|
|
118
122
|
sm: string;
|
|
@@ -127,6 +131,10 @@ declare const avatarStyles: tailwind_variants.TVReturnType<{
|
|
|
127
131
|
terra: string;
|
|
128
132
|
slate: string;
|
|
129
133
|
};
|
|
134
|
+
shape: {
|
|
135
|
+
circle: string;
|
|
136
|
+
square: string;
|
|
137
|
+
};
|
|
130
138
|
}, undefined, tailwind_variants.TVReturnType<{
|
|
131
139
|
size: {
|
|
132
140
|
sm: string;
|
|
@@ -141,6 +149,10 @@ declare const avatarStyles: tailwind_variants.TVReturnType<{
|
|
|
141
149
|
terra: string;
|
|
142
150
|
slate: string;
|
|
143
151
|
};
|
|
152
|
+
shape: {
|
|
153
|
+
circle: string;
|
|
154
|
+
square: string;
|
|
155
|
+
};
|
|
144
156
|
}, undefined, string[], unknown, unknown, undefined>>;
|
|
145
157
|
type AvatarVariants = VariantProps<typeof avatarStyles>;
|
|
146
158
|
type AvatarProps = HTMLAttributes<HTMLSpanElement> & AvatarVariants & {
|
|
@@ -154,7 +166,7 @@ type AvatarProps = HTMLAttributes<HTMLSpanElement> & AvatarVariants & {
|
|
|
154
166
|
/** Alt text for the image. Defaults to empty — the avatar is decorative. */
|
|
155
167
|
alt?: string;
|
|
156
168
|
};
|
|
157
|
-
declare function Avatar({ size, tone, initials, src, alt, className, children, ...props }: AvatarProps): react_jsx_runtime.JSX.Element;
|
|
169
|
+
declare function Avatar({ size, tone, shape, initials, src, alt, className, children, ...props }: AvatarProps): react_jsx_runtime.JSX.Element;
|
|
158
170
|
|
|
159
171
|
declare const avatarGroupStyles: tailwind_variants.TVReturnType<{
|
|
160
172
|
size: {
|
|
@@ -477,12 +489,14 @@ declare function Breadcrumbs({ items, separator, className, ...props }: Breadcru
|
|
|
477
489
|
|
|
478
490
|
declare const buttonStyles: tailwind_variants.TVReturnType<{
|
|
479
491
|
variant: {
|
|
480
|
-
|
|
492
|
+
cta: string[];
|
|
481
493
|
accent: string[];
|
|
494
|
+
primary: string[];
|
|
482
495
|
secondary: string[];
|
|
483
496
|
ghost: string[];
|
|
484
497
|
subtle: string[];
|
|
485
498
|
link: string[];
|
|
499
|
+
danger: string[];
|
|
486
500
|
};
|
|
487
501
|
size: {
|
|
488
502
|
sm: string;
|
|
@@ -498,12 +512,14 @@ declare const buttonStyles: tailwind_variants.TVReturnType<{
|
|
|
498
512
|
};
|
|
499
513
|
}, undefined, string[], {
|
|
500
514
|
variant: {
|
|
501
|
-
|
|
515
|
+
cta: string[];
|
|
502
516
|
accent: string[];
|
|
517
|
+
primary: string[];
|
|
503
518
|
secondary: string[];
|
|
504
519
|
ghost: string[];
|
|
505
520
|
subtle: string[];
|
|
506
521
|
link: string[];
|
|
522
|
+
danger: string[];
|
|
507
523
|
};
|
|
508
524
|
size: {
|
|
509
525
|
sm: string;
|
|
@@ -519,12 +535,14 @@ declare const buttonStyles: tailwind_variants.TVReturnType<{
|
|
|
519
535
|
};
|
|
520
536
|
}, undefined, tailwind_variants.TVReturnType<{
|
|
521
537
|
variant: {
|
|
522
|
-
|
|
538
|
+
cta: string[];
|
|
523
539
|
accent: string[];
|
|
540
|
+
primary: string[];
|
|
524
541
|
secondary: string[];
|
|
525
542
|
ghost: string[];
|
|
526
543
|
subtle: string[];
|
|
527
544
|
link: string[];
|
|
545
|
+
danger: string[];
|
|
528
546
|
};
|
|
529
547
|
size: {
|
|
530
548
|
sm: string;
|
|
@@ -2100,12 +2118,19 @@ type ModalContentProps = ModalOverlayProps & {
|
|
|
2100
2118
|
children: DialogProps['children'];
|
|
2101
2119
|
/** Visual override for the panel wrapper (affects width, padding, etc.). */
|
|
2102
2120
|
modalClassName?: string;
|
|
2121
|
+
/** Visual override for the dialog element inside the panel — the column the
|
|
2122
|
+
* slots sit in. It hugs its content by default; a panel given a height of
|
|
2123
|
+
* its own needs `grow` here for the slots to fill it. */
|
|
2124
|
+
dialogClassName?: string;
|
|
2125
|
+
/** Accessible name for a dialog WITHOUT a `<ModalTitle>`. A titled dialog is
|
|
2126
|
+
* named by its title and doesn't need this. */
|
|
2127
|
+
'aria-label'?: string;
|
|
2103
2128
|
};
|
|
2104
2129
|
/**
|
|
2105
2130
|
* Portaled overlay + floating panel + dialog role. Backdrop darkens the page
|
|
2106
2131
|
* with a warm ink tint; panel uses vellum bg + rule border + the float shadow.
|
|
2107
2132
|
*/
|
|
2108
|
-
declare function ModalContent({ children, className, modalClassName, isDismissable, ...props }: ModalContentProps): react_jsx_runtime.JSX.Element;
|
|
2133
|
+
declare function ModalContent({ children, className, modalClassName, dialogClassName, isDismissable, 'aria-label': ariaLabel, ...props }: ModalContentProps): react_jsx_runtime.JSX.Element;
|
|
2109
2134
|
/** Padded top block. Contains `<ModalTitle>` and optionally `<ModalDescription>`. */
|
|
2110
2135
|
declare function ModalHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2111
2136
|
/** The modal's accessible name. Uses RAC `<Heading slot="title">` so the
|
|
@@ -2705,10 +2730,12 @@ declare const segmentedControlStyles: tailwind_variants.TVReturnType<{
|
|
|
2705
2730
|
segment: string;
|
|
2706
2731
|
};
|
|
2707
2732
|
};
|
|
2708
|
-
|
|
2709
|
-
|
|
2733
|
+
wrap: {
|
|
2734
|
+
true: {
|
|
2735
|
+
group: string;
|
|
2710
2736
|
segment: string;
|
|
2711
2737
|
};
|
|
2738
|
+
false: {};
|
|
2712
2739
|
};
|
|
2713
2740
|
}, {
|
|
2714
2741
|
group: string;
|
|
@@ -2722,10 +2749,12 @@ declare const segmentedControlStyles: tailwind_variants.TVReturnType<{
|
|
|
2722
2749
|
segment: string;
|
|
2723
2750
|
};
|
|
2724
2751
|
};
|
|
2725
|
-
|
|
2726
|
-
|
|
2752
|
+
wrap: {
|
|
2753
|
+
true: {
|
|
2754
|
+
group: string;
|
|
2727
2755
|
segment: string;
|
|
2728
2756
|
};
|
|
2757
|
+
false: {};
|
|
2729
2758
|
};
|
|
2730
2759
|
}, {
|
|
2731
2760
|
group: string;
|
|
@@ -2739,10 +2768,12 @@ declare const segmentedControlStyles: tailwind_variants.TVReturnType<{
|
|
|
2739
2768
|
segment: string;
|
|
2740
2769
|
};
|
|
2741
2770
|
};
|
|
2742
|
-
|
|
2743
|
-
|
|
2771
|
+
wrap: {
|
|
2772
|
+
true: {
|
|
2773
|
+
group: string;
|
|
2744
2774
|
segment: string;
|
|
2745
2775
|
};
|
|
2776
|
+
false: {};
|
|
2746
2777
|
};
|
|
2747
2778
|
}, {
|
|
2748
2779
|
group: string;
|
|
@@ -2753,12 +2784,17 @@ type SegmentedControlOption<T extends Key$1 = Key$1> = {
|
|
|
2753
2784
|
id: T;
|
|
2754
2785
|
label: ReactNode;
|
|
2755
2786
|
isDisabled?: boolean;
|
|
2787
|
+
/** Accessible name for icon-only segments. */
|
|
2788
|
+
'aria-label'?: string;
|
|
2756
2789
|
};
|
|
2757
2790
|
type SegmentedControlProps<T extends Key$1 = Key$1> = Omit<RadioGroupProps$1, 'children' | 'value' | 'onChange'> & {
|
|
2758
2791
|
options: ReadonlyArray<SegmentedControlOption<T>>;
|
|
2759
|
-
|
|
2792
|
+
/** `null` renders no selected segment. */
|
|
2793
|
+
value: T | null;
|
|
2760
2794
|
onChange: (value: T) => void;
|
|
2761
2795
|
size?: SegmentedControlVariants['size'];
|
|
2796
|
+
/** Flow-wrap long option lists; segments share the line equally. */
|
|
2797
|
+
wrap?: boolean;
|
|
2762
2798
|
/** Focus the selected segment on mount. RAC's RadioGroup doesn't surface
|
|
2763
2799
|
* `autoFocus` itself — it's a per-Radio prop — so we apply it to the
|
|
2764
2800
|
* Radio whose value matches `value`. */
|
|
@@ -2766,7 +2802,7 @@ type SegmentedControlProps<T extends Key$1 = Key$1> = Omit<RadioGroupProps$1, 'c
|
|
|
2766
2802
|
/** Visual override for the group wrapper. */
|
|
2767
2803
|
className?: string;
|
|
2768
2804
|
};
|
|
2769
|
-
declare function SegmentedControl<T extends Key$1>({ options, value, onChange, size, autoFocus, className, orientation, ...props }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
|
|
2805
|
+
declare function SegmentedControl<T extends Key$1>({ options, value, onChange, size, wrap, autoFocus, className, orientation, ...props }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
|
|
2770
2806
|
|
|
2771
2807
|
type SelectOption<T extends Key = Key> = {
|
|
2772
2808
|
id: T;
|
package/dist/index.d.ts
CHANGED
|
@@ -113,6 +113,10 @@ declare const avatarStyles: tailwind_variants.TVReturnType<{
|
|
|
113
113
|
terra: string;
|
|
114
114
|
slate: string;
|
|
115
115
|
};
|
|
116
|
+
shape: {
|
|
117
|
+
circle: string;
|
|
118
|
+
square: string;
|
|
119
|
+
};
|
|
116
120
|
}, undefined, string[], {
|
|
117
121
|
size: {
|
|
118
122
|
sm: string;
|
|
@@ -127,6 +131,10 @@ declare const avatarStyles: tailwind_variants.TVReturnType<{
|
|
|
127
131
|
terra: string;
|
|
128
132
|
slate: string;
|
|
129
133
|
};
|
|
134
|
+
shape: {
|
|
135
|
+
circle: string;
|
|
136
|
+
square: string;
|
|
137
|
+
};
|
|
130
138
|
}, undefined, tailwind_variants.TVReturnType<{
|
|
131
139
|
size: {
|
|
132
140
|
sm: string;
|
|
@@ -141,6 +149,10 @@ declare const avatarStyles: tailwind_variants.TVReturnType<{
|
|
|
141
149
|
terra: string;
|
|
142
150
|
slate: string;
|
|
143
151
|
};
|
|
152
|
+
shape: {
|
|
153
|
+
circle: string;
|
|
154
|
+
square: string;
|
|
155
|
+
};
|
|
144
156
|
}, undefined, string[], unknown, unknown, undefined>>;
|
|
145
157
|
type AvatarVariants = VariantProps<typeof avatarStyles>;
|
|
146
158
|
type AvatarProps = HTMLAttributes<HTMLSpanElement> & AvatarVariants & {
|
|
@@ -154,7 +166,7 @@ type AvatarProps = HTMLAttributes<HTMLSpanElement> & AvatarVariants & {
|
|
|
154
166
|
/** Alt text for the image. Defaults to empty — the avatar is decorative. */
|
|
155
167
|
alt?: string;
|
|
156
168
|
};
|
|
157
|
-
declare function Avatar({ size, tone, initials, src, alt, className, children, ...props }: AvatarProps): react_jsx_runtime.JSX.Element;
|
|
169
|
+
declare function Avatar({ size, tone, shape, initials, src, alt, className, children, ...props }: AvatarProps): react_jsx_runtime.JSX.Element;
|
|
158
170
|
|
|
159
171
|
declare const avatarGroupStyles: tailwind_variants.TVReturnType<{
|
|
160
172
|
size: {
|
|
@@ -477,12 +489,14 @@ declare function Breadcrumbs({ items, separator, className, ...props }: Breadcru
|
|
|
477
489
|
|
|
478
490
|
declare const buttonStyles: tailwind_variants.TVReturnType<{
|
|
479
491
|
variant: {
|
|
480
|
-
|
|
492
|
+
cta: string[];
|
|
481
493
|
accent: string[];
|
|
494
|
+
primary: string[];
|
|
482
495
|
secondary: string[];
|
|
483
496
|
ghost: string[];
|
|
484
497
|
subtle: string[];
|
|
485
498
|
link: string[];
|
|
499
|
+
danger: string[];
|
|
486
500
|
};
|
|
487
501
|
size: {
|
|
488
502
|
sm: string;
|
|
@@ -498,12 +512,14 @@ declare const buttonStyles: tailwind_variants.TVReturnType<{
|
|
|
498
512
|
};
|
|
499
513
|
}, undefined, string[], {
|
|
500
514
|
variant: {
|
|
501
|
-
|
|
515
|
+
cta: string[];
|
|
502
516
|
accent: string[];
|
|
517
|
+
primary: string[];
|
|
503
518
|
secondary: string[];
|
|
504
519
|
ghost: string[];
|
|
505
520
|
subtle: string[];
|
|
506
521
|
link: string[];
|
|
522
|
+
danger: string[];
|
|
507
523
|
};
|
|
508
524
|
size: {
|
|
509
525
|
sm: string;
|
|
@@ -519,12 +535,14 @@ declare const buttonStyles: tailwind_variants.TVReturnType<{
|
|
|
519
535
|
};
|
|
520
536
|
}, undefined, tailwind_variants.TVReturnType<{
|
|
521
537
|
variant: {
|
|
522
|
-
|
|
538
|
+
cta: string[];
|
|
523
539
|
accent: string[];
|
|
540
|
+
primary: string[];
|
|
524
541
|
secondary: string[];
|
|
525
542
|
ghost: string[];
|
|
526
543
|
subtle: string[];
|
|
527
544
|
link: string[];
|
|
545
|
+
danger: string[];
|
|
528
546
|
};
|
|
529
547
|
size: {
|
|
530
548
|
sm: string;
|
|
@@ -2100,12 +2118,19 @@ type ModalContentProps = ModalOverlayProps & {
|
|
|
2100
2118
|
children: DialogProps['children'];
|
|
2101
2119
|
/** Visual override for the panel wrapper (affects width, padding, etc.). */
|
|
2102
2120
|
modalClassName?: string;
|
|
2121
|
+
/** Visual override for the dialog element inside the panel — the column the
|
|
2122
|
+
* slots sit in. It hugs its content by default; a panel given a height of
|
|
2123
|
+
* its own needs `grow` here for the slots to fill it. */
|
|
2124
|
+
dialogClassName?: string;
|
|
2125
|
+
/** Accessible name for a dialog WITHOUT a `<ModalTitle>`. A titled dialog is
|
|
2126
|
+
* named by its title and doesn't need this. */
|
|
2127
|
+
'aria-label'?: string;
|
|
2103
2128
|
};
|
|
2104
2129
|
/**
|
|
2105
2130
|
* Portaled overlay + floating panel + dialog role. Backdrop darkens the page
|
|
2106
2131
|
* with a warm ink tint; panel uses vellum bg + rule border + the float shadow.
|
|
2107
2132
|
*/
|
|
2108
|
-
declare function ModalContent({ children, className, modalClassName, isDismissable, ...props }: ModalContentProps): react_jsx_runtime.JSX.Element;
|
|
2133
|
+
declare function ModalContent({ children, className, modalClassName, dialogClassName, isDismissable, 'aria-label': ariaLabel, ...props }: ModalContentProps): react_jsx_runtime.JSX.Element;
|
|
2109
2134
|
/** Padded top block. Contains `<ModalTitle>` and optionally `<ModalDescription>`. */
|
|
2110
2135
|
declare function ModalHeader({ className, ...props }: HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
|
|
2111
2136
|
/** The modal's accessible name. Uses RAC `<Heading slot="title">` so the
|
|
@@ -2705,10 +2730,12 @@ declare const segmentedControlStyles: tailwind_variants.TVReturnType<{
|
|
|
2705
2730
|
segment: string;
|
|
2706
2731
|
};
|
|
2707
2732
|
};
|
|
2708
|
-
|
|
2709
|
-
|
|
2733
|
+
wrap: {
|
|
2734
|
+
true: {
|
|
2735
|
+
group: string;
|
|
2710
2736
|
segment: string;
|
|
2711
2737
|
};
|
|
2738
|
+
false: {};
|
|
2712
2739
|
};
|
|
2713
2740
|
}, {
|
|
2714
2741
|
group: string;
|
|
@@ -2722,10 +2749,12 @@ declare const segmentedControlStyles: tailwind_variants.TVReturnType<{
|
|
|
2722
2749
|
segment: string;
|
|
2723
2750
|
};
|
|
2724
2751
|
};
|
|
2725
|
-
|
|
2726
|
-
|
|
2752
|
+
wrap: {
|
|
2753
|
+
true: {
|
|
2754
|
+
group: string;
|
|
2727
2755
|
segment: string;
|
|
2728
2756
|
};
|
|
2757
|
+
false: {};
|
|
2729
2758
|
};
|
|
2730
2759
|
}, {
|
|
2731
2760
|
group: string;
|
|
@@ -2739,10 +2768,12 @@ declare const segmentedControlStyles: tailwind_variants.TVReturnType<{
|
|
|
2739
2768
|
segment: string;
|
|
2740
2769
|
};
|
|
2741
2770
|
};
|
|
2742
|
-
|
|
2743
|
-
|
|
2771
|
+
wrap: {
|
|
2772
|
+
true: {
|
|
2773
|
+
group: string;
|
|
2744
2774
|
segment: string;
|
|
2745
2775
|
};
|
|
2776
|
+
false: {};
|
|
2746
2777
|
};
|
|
2747
2778
|
}, {
|
|
2748
2779
|
group: string;
|
|
@@ -2753,12 +2784,17 @@ type SegmentedControlOption<T extends Key$1 = Key$1> = {
|
|
|
2753
2784
|
id: T;
|
|
2754
2785
|
label: ReactNode;
|
|
2755
2786
|
isDisabled?: boolean;
|
|
2787
|
+
/** Accessible name for icon-only segments. */
|
|
2788
|
+
'aria-label'?: string;
|
|
2756
2789
|
};
|
|
2757
2790
|
type SegmentedControlProps<T extends Key$1 = Key$1> = Omit<RadioGroupProps$1, 'children' | 'value' | 'onChange'> & {
|
|
2758
2791
|
options: ReadonlyArray<SegmentedControlOption<T>>;
|
|
2759
|
-
|
|
2792
|
+
/** `null` renders no selected segment. */
|
|
2793
|
+
value: T | null;
|
|
2760
2794
|
onChange: (value: T) => void;
|
|
2761
2795
|
size?: SegmentedControlVariants['size'];
|
|
2796
|
+
/** Flow-wrap long option lists; segments share the line equally. */
|
|
2797
|
+
wrap?: boolean;
|
|
2762
2798
|
/** Focus the selected segment on mount. RAC's RadioGroup doesn't surface
|
|
2763
2799
|
* `autoFocus` itself — it's a per-Radio prop — so we apply it to the
|
|
2764
2800
|
* Radio whose value matches `value`. */
|
|
@@ -2766,7 +2802,7 @@ type SegmentedControlProps<T extends Key$1 = Key$1> = Omit<RadioGroupProps$1, 'c
|
|
|
2766
2802
|
/** Visual override for the group wrapper. */
|
|
2767
2803
|
className?: string;
|
|
2768
2804
|
};
|
|
2769
|
-
declare function SegmentedControl<T extends Key$1>({ options, value, onChange, size, autoFocus, className, orientation, ...props }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
|
|
2805
|
+
declare function SegmentedControl<T extends Key$1>({ options, value, onChange, size, wrap, autoFocus, className, orientation, ...props }: SegmentedControlProps<T>): react_jsx_runtime.JSX.Element;
|
|
2770
2806
|
|
|
2771
2807
|
type SelectOption<T extends Key = Key> = {
|
|
2772
2808
|
id: T;
|