@exsto/ds 0.0.1-rc.4 → 0.0.1-rc.6
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/README.md +8 -27
- package/dist/ds/src/index.d.ts +2 -3
- package/dist/index.js +5107 -2
- package/dist/index.js.map +1 -0
- package/dist/styles.css +525 -296
- package/dist/theme.css +58 -1
- package/dist/ui/src/components/edyn/animated-number/animated-number.d.ts +30 -0
- package/dist/ui/src/components/edyn/animated-number/animated-number.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/animated-number/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.d.ts +26 -0
- package/dist/ui/src/components/edyn/date-range-picker/date-range-picker.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/date-range-picker/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/initials-avatar/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.d.ts +53 -0
- package/dist/ui/src/components/edyn/initials-avatar/initials-avatar.test.d.ts +10 -0
- package/dist/ui/src/components/edyn/multi-select/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/multi-select/multi-select.d.ts +96 -0
- package/dist/ui/src/components/edyn/multi-select/multi-select.test.d.ts +9 -0
- package/dist/ui/src/components/edyn/progress-line/index.d.ts +1 -0
- package/dist/ui/src/components/edyn/progress-line/progress-line.d.ts +23 -0
- package/dist/ui/src/components/edyn/progress-line/progress-line.test.d.ts +9 -0
- package/dist/ui/src/components/ui/attachment/attachment.d.ts +1 -1
- package/dist/ui/src/components/ui/button/button.behavior.test.d.ts +8 -0
- package/dist/ui/src/components/ui/dropdown-menu/dropdown-menu.d.ts +9 -10
- package/dist/ui/src/components/ui/input-group/input-group.d.ts +1 -1
- package/dist/ui/src/components/ui/item/item.d.ts +1 -1
- package/dist/ui/src/components/ui/progress/progress.behavior.test.d.ts +8 -0
- package/dist/ui/src/components/ui/progress/progress.d.ts +43 -1
- package/dist/ui/src/components/ui/scroll-area/scroll-area.behavior.test.d.ts +7 -6
- package/dist/ui/src/components/ui/scroll-area/scroll-area.d.ts +27 -8
- package/dist/ui/src/components/ui/table/table.behavior.test.d.ts +4 -5
- package/dist/ui/src/index.d.ts +5 -0
- package/dist/ui/src/lib/focus-ring.test.d.ts +8 -0
- package/dist/ui/src/lib/popup-list.d.ts +47 -0
- package/dist/ui/src/lib/popup-list.test.d.ts +10 -0
- package/package.json +4 -9
- package/dist/chunks/toggle-group-CTTjTe-K.js +0 -4371
- package/dist/chunks/toggle-group-CTTjTe-K.js.map +0 -1
- package/dist/dom/src/context.d.ts +0 -34
- package/dist/dom/src/define-element.d.ts +0 -11
- package/dist/dom/src/define-element.test.d.ts +0 -1
- package/dist/dom/src/field-control.d.ts +0 -5
- package/dist/dom/src/index.d.ts +0 -6
- package/dist/dom/src/mode.d.ts +0 -8
- package/dist/dom/src/native-slot.test.d.ts +0 -1
- package/dist/dom/src/styles.d.ts +0 -6
- package/dist/dom/src/theme-state.d.ts +0 -1
- package/dist/dom/src/types.d.ts +0 -65
- package/dist/ds/src/elements.d.ts +0 -12
- package/dist/elements/src/edx-accordion.d.ts +0 -14
- package/dist/elements/src/edx-accordion.test.d.ts +0 -1
- package/dist/elements/src/edx-alert.d.ts +0 -14
- package/dist/elements/src/edx-audio-player.d.ts +0 -11
- package/dist/elements/src/edx-avatar.d.ts +0 -10
- package/dist/elements/src/edx-badge.d.ts +0 -12
- package/dist/elements/src/edx-breadcrumb.d.ts +0 -11
- package/dist/elements/src/edx-button-group.d.ts +0 -7
- package/dist/elements/src/edx-button.d.ts +0 -20
- package/dist/elements/src/edx-calendar.d.ts +0 -21
- package/dist/elements/src/edx-card.d.ts +0 -8
- package/dist/elements/src/edx-checkbox.d.ts +0 -18
- package/dist/elements/src/edx-combobox.d.ts +0 -28
- package/dist/elements/src/edx-content-components.d.ts +0 -2
- package/dist/elements/src/edx-dialog.d.ts +0 -20
- package/dist/elements/src/edx-drawer.d.ts +0 -21
- package/dist/elements/src/edx-dropdown-menu.d.ts +0 -29
- package/dist/elements/src/edx-field.d.ts +0 -9
- package/dist/elements/src/edx-field.test.d.ts +0 -1
- package/dist/elements/src/edx-indicator.d.ts +0 -14
- package/dist/elements/src/edx-input-group.d.ts +0 -32
- package/dist/elements/src/edx-input-otp.d.ts +0 -19
- package/dist/elements/src/edx-input.d.ts +0 -31
- package/dist/elements/src/edx-interactive-components.d.ts +0 -2
- package/dist/elements/src/edx-label.d.ts +0 -6
- package/dist/elements/src/edx-pagination.d.ts +0 -8
- package/dist/elements/src/edx-popover.d.ts +0 -24
- package/dist/elements/src/edx-progress.d.ts +0 -10
- package/dist/elements/src/edx-radio-group.d.ts +0 -22
- package/dist/elements/src/edx-radio-group.test.d.ts +0 -1
- package/dist/elements/src/edx-scroll-area.d.ts +0 -20
- package/dist/elements/src/edx-scroll-area.test.d.ts +0 -1
- package/dist/elements/src/edx-select.d.ts +0 -34
- package/dist/elements/src/edx-separator.d.ts +0 -10
- package/dist/elements/src/edx-skeleton.d.ts +0 -8
- package/dist/elements/src/edx-slider.d.ts +0 -17
- package/dist/elements/src/edx-slider.test.d.ts +0 -1
- package/dist/elements/src/edx-switch.d.ts +0 -18
- package/dist/elements/src/edx-table.d.ts +0 -13
- package/dist/elements/src/edx-table.test.d.ts +0 -1
- package/dist/elements/src/edx-tabs.d.ts +0 -15
- package/dist/elements/src/edx-tabs.test.d.ts +0 -1
- package/dist/elements/src/edx-textarea.d.ts +0 -25
- package/dist/elements/src/edx-toggle-group.d.ts +0 -27
- package/dist/elements/src/edx-toggle-group.test.d.ts +0 -1
- package/dist/elements/src/edx-toggle.d.ts +0 -18
- package/dist/elements/src/edx-tooltip.d.ts +0 -28
- package/dist/elements/src/edx-video-player.d.ts +0 -16
- package/dist/elements/src/field-control-bridge.d.ts +0 -7
- package/dist/elements/src/index.d.ts +0 -14
- package/dist/elements/src/projected-content.test.d.ts +0 -1
- package/dist/elements/src/registry.d.ts +0 -39
- package/dist/elements/src/registry.test.d.ts +0 -1
- package/dist/elements.js +0 -4026
- package/dist/elements.js.map +0 -1
package/dist/theme.css
CHANGED
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
|
|
111
111
|
--border: oklch(0.922 0 0);
|
|
112
112
|
--input: oklch(0.922 0 0);
|
|
113
|
-
--ring: oklch(0.
|
|
113
|
+
--ring: oklch(0.6 0 0);
|
|
114
114
|
|
|
115
115
|
--chart-1: oklch(0.646 0.222 41.116);
|
|
116
116
|
--chart-2: oklch(0.6 0.118 184.704);
|
|
@@ -126,6 +126,38 @@
|
|
|
126
126
|
--sidebar-accent-foreground: oklch(0.205 0 0);
|
|
127
127
|
--sidebar-border: oklch(0.922 0 0);
|
|
128
128
|
--sidebar-ring: oklch(0.708 0 0);
|
|
129
|
+
|
|
130
|
+
/*
|
|
131
|
+
* Avatar palette: twelve hues, each a pair at an even perceived lightness, a
|
|
132
|
+
* soft tint with strong text of the same hue in the light theme and a deep tint
|
|
133
|
+
* with light text in the dark one. No yellows, olives or browns: they turn muddy.
|
|
134
|
+
* InitialsAvatar picks one by hashing the initials; every pair clears 4.5:1
|
|
135
|
+
* (packages/ui/src/components/edyn/initials-avatar/initials-avatar.test.tsx checks it).
|
|
136
|
+
*/
|
|
137
|
+
--avatar-1-bg: oklch(0.93 0.045 259); /* blue */
|
|
138
|
+
--avatar-1-fg: oklch(0.45 0.15 259);
|
|
139
|
+
--avatar-2-bg: oklch(0.93 0.045 277); /* indigo */
|
|
140
|
+
--avatar-2-fg: oklch(0.45 0.15 277);
|
|
141
|
+
--avatar-3-bg: oklch(0.93 0.045 293); /* violet */
|
|
142
|
+
--avatar-3-fg: oklch(0.45 0.15 293);
|
|
143
|
+
--avatar-4-bg: oklch(0.93 0.045 322); /* fuchsia */
|
|
144
|
+
--avatar-4-fg: oklch(0.45 0.15 322);
|
|
145
|
+
--avatar-5-bg: oklch(0.93 0.045 354); /* pink */
|
|
146
|
+
--avatar-5-fg: oklch(0.45 0.15 354);
|
|
147
|
+
--avatar-6-bg: oklch(0.93 0.045 16); /* rose */
|
|
148
|
+
--avatar-6-fg: oklch(0.45 0.15 16);
|
|
149
|
+
--avatar-7-bg: oklch(0.93 0.045 27); /* red */
|
|
150
|
+
--avatar-7-fg: oklch(0.45 0.15 27);
|
|
151
|
+
--avatar-8-bg: oklch(0.93 0.045 47); /* orange */
|
|
152
|
+
--avatar-8-fg: oklch(0.45 0.15 47);
|
|
153
|
+
--avatar-9-bg: oklch(0.93 0.045 163); /* emerald */
|
|
154
|
+
--avatar-9-fg: oklch(0.45 0.15 163);
|
|
155
|
+
--avatar-10-bg: oklch(0.93 0.045 183); /* teal */
|
|
156
|
+
--avatar-10-fg: oklch(0.45 0.15 183);
|
|
157
|
+
--avatar-11-bg: oklch(0.93 0.045 215); /* cyan */
|
|
158
|
+
--avatar-11-fg: oklch(0.45 0.15 215);
|
|
159
|
+
--avatar-12-bg: oklch(0.93 0.045 237); /* sky */
|
|
160
|
+
--avatar-12-fg: oklch(0.45 0.15 237);
|
|
129
161
|
}
|
|
130
162
|
|
|
131
163
|
.dark {
|
|
@@ -184,6 +216,31 @@
|
|
|
184
216
|
--sidebar-accent-foreground: oklch(0.985 0 0);
|
|
185
217
|
--sidebar-border: oklch(1 0 0 / 10%);
|
|
186
218
|
--sidebar-ring: oklch(0.556 0 0);
|
|
219
|
+
|
|
220
|
+
--avatar-1-bg: oklch(0.32 0.07 259); /* blue */
|
|
221
|
+
--avatar-1-fg: oklch(0.86 0.09 259);
|
|
222
|
+
--avatar-2-bg: oklch(0.32 0.07 277); /* indigo */
|
|
223
|
+
--avatar-2-fg: oklch(0.86 0.09 277);
|
|
224
|
+
--avatar-3-bg: oklch(0.32 0.07 293); /* violet */
|
|
225
|
+
--avatar-3-fg: oklch(0.86 0.09 293);
|
|
226
|
+
--avatar-4-bg: oklch(0.32 0.07 322); /* fuchsia */
|
|
227
|
+
--avatar-4-fg: oklch(0.86 0.09 322);
|
|
228
|
+
--avatar-5-bg: oklch(0.32 0.07 354); /* pink */
|
|
229
|
+
--avatar-5-fg: oklch(0.86 0.09 354);
|
|
230
|
+
--avatar-6-bg: oklch(0.32 0.07 16); /* rose */
|
|
231
|
+
--avatar-6-fg: oklch(0.86 0.09 16);
|
|
232
|
+
--avatar-7-bg: oklch(0.32 0.07 27); /* red */
|
|
233
|
+
--avatar-7-fg: oklch(0.86 0.09 27);
|
|
234
|
+
--avatar-8-bg: oklch(0.32 0.07 47); /* orange */
|
|
235
|
+
--avatar-8-fg: oklch(0.86 0.09 47);
|
|
236
|
+
--avatar-9-bg: oklch(0.32 0.07 163); /* emerald */
|
|
237
|
+
--avatar-9-fg: oklch(0.86 0.09 163);
|
|
238
|
+
--avatar-10-bg: oklch(0.32 0.07 183); /* teal */
|
|
239
|
+
--avatar-10-fg: oklch(0.86 0.09 183);
|
|
240
|
+
--avatar-11-bg: oklch(0.32 0.07 215); /* cyan */
|
|
241
|
+
--avatar-11-fg: oklch(0.86 0.09 215);
|
|
242
|
+
--avatar-12-bg: oklch(0.32 0.07 237); /* sky */
|
|
243
|
+
--avatar-12-fg: oklch(0.86 0.09 237);
|
|
187
244
|
}
|
|
188
245
|
|
|
189
246
|
@theme inline {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
/** Thousands separated, rounded to a whole number: the default way a count reads. */
|
|
3
|
+
export declare const formatCount: (value: number) => string;
|
|
4
|
+
/**
|
|
5
|
+
* The values to show for `targets` this frame, all on one clock and one curve, so a
|
|
6
|
+
* count and its bar move together. They start from 0 and move once `element` has
|
|
7
|
+
* been on screen.
|
|
8
|
+
*/
|
|
9
|
+
export declare const useAnimatedValues: (targets: number[], element: RefObject<Element | null>) => number[];
|
|
10
|
+
export interface IAnimatedNumberProps {
|
|
11
|
+
value: number;
|
|
12
|
+
/** What it shows while it moves and once there (formatCount by default; a percentage formatter for shares). */
|
|
13
|
+
format?: (value: number) => string;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A number that moves to its new value. Its width holds the widest of where it starts
|
|
18
|
+
* and where it lands, in tabular figures, so nothing beside it moves while the digits
|
|
19
|
+
* change. Assistive technology reads only the final value.
|
|
20
|
+
*/
|
|
21
|
+
export declare const AnimatedNumber: ({ value, format, className }: IAnimatedNumberProps) => import('react').JSX.Element;
|
|
22
|
+
export interface INumberTextProps {
|
|
23
|
+
element?: RefObject<HTMLSpanElement | null>;
|
|
24
|
+
shown: number;
|
|
25
|
+
value: number;
|
|
26
|
+
format?: (value: number) => string;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/** The text of a moving number: what it shows now, held at its widest, with the final value for assistive technology. */
|
|
30
|
+
export declare const NumberText: ({ element, shown, value, format, className }: INumberTextProps) => import('react').JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AnimatedNumber: a number that moves to its new value, announced once.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: the formatting, the markup and the reduced-motion and no-change
|
|
5
|
+
* paths are plain logic and run in happy-dom. The motion itself (a number really
|
|
6
|
+
* passing through values, a width that holds) needs a real clock and layout, so
|
|
7
|
+
* e2e/animated-number.spec.ts measures it in the browser.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './animated-number';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** A range of calendar days as yyyy-mm-dd, either end optional. */
|
|
2
|
+
export type TDateRange = {
|
|
3
|
+
from?: string;
|
|
4
|
+
to?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const dayToDate: (value: string | undefined) => Date | undefined;
|
|
7
|
+
export declare const dateToDay: (date: Date | undefined) => string | undefined;
|
|
8
|
+
export interface IDateRangePickerProps {
|
|
9
|
+
id?: string;
|
|
10
|
+
value: TDateRange;
|
|
11
|
+
onValueChange: (value: TDateRange) => void;
|
|
12
|
+
placeholder?: string;
|
|
13
|
+
/**
|
|
14
|
+
* What the trigger says once a range is set. `range` (default) writes the ends; `label` keeps the label, so a
|
|
15
|
+
* range the page shows elsewhere (as a removable chip, say) is not repeated here. In both, the trigger carries
|
|
16
|
+
* `data-set` while either end is set, for a look of its own.
|
|
17
|
+
*/
|
|
18
|
+
summary?: 'range' | 'label';
|
|
19
|
+
/** How the ends are written on the trigger (BCP 47); en-GB reads 05 Mar 2026. */
|
|
20
|
+
locale?: string;
|
|
21
|
+
/** An accessible name for the trigger, when there is no visible label to point at. */
|
|
22
|
+
'aria-label'?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
/** A range of calendar days, either end optional; two months side by side, one on a phone. */
|
|
26
|
+
export declare const DateRangePicker: ({ id, value, onValueChange, placeholder, locale, summary, "aria-label": ariaLabel, className, }: IDateRangePickerProps) => import('react').JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DateRangePicker: the day arithmetic and the trigger's text.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: converting a calendar day to a Date and back, and how the ends are
|
|
5
|
+
* written, are plain logic and run in happy-dom. Opening the calendar, picking two
|
|
6
|
+
* days and the one-month layout on a phone need a real browser and layout, so
|
|
7
|
+
* e2e/date-range-picker.spec.ts covers those.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './date-range-picker';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './initials-avatar';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** How many colour pairs the theme defines (--avatar-1-bg, --avatar-1-fg ... in @edyn/theme tokens.css). */
|
|
2
|
+
export declare const AVATAR_TONES = 12;
|
|
3
|
+
/**
|
|
4
|
+
* The palette entry the text gets, from 1: the same text always gets the same one.
|
|
5
|
+
* FNV-1a, because a plain multiply-and-add hash puts two letters on a few entries
|
|
6
|
+
* only (it reduces to 7 x first + second, modulo 12).
|
|
7
|
+
*/
|
|
8
|
+
export declare const avatarTone: (text: string) => number;
|
|
9
|
+
/** Up to two initials, upper-cased: the first letter of the first two words. */
|
|
10
|
+
export declare const initialsOf: (name: string) => string;
|
|
11
|
+
/**
|
|
12
|
+
* The circle and its letters together, so the initials always fit. The font size
|
|
13
|
+
* is inline rather than a class on purpose: 9px and 15px are not on Tailwind's
|
|
14
|
+
* type scale, a custom `text-*` token would be read by tailwind-merge as a colour
|
|
15
|
+
* and could drop the wrong class, and an inline size cannot be fought by the
|
|
16
|
+
* fallback's own `text-sm`.
|
|
17
|
+
*/
|
|
18
|
+
declare const SIZES: {
|
|
19
|
+
readonly xs: {
|
|
20
|
+
readonly box: "size-5";
|
|
21
|
+
readonly fontSize: 9;
|
|
22
|
+
};
|
|
23
|
+
readonly sm: {
|
|
24
|
+
readonly box: "size-6";
|
|
25
|
+
readonly fontSize: 10;
|
|
26
|
+
};
|
|
27
|
+
readonly md: {
|
|
28
|
+
readonly box: "size-8";
|
|
29
|
+
readonly fontSize: 12;
|
|
30
|
+
};
|
|
31
|
+
readonly lg: {
|
|
32
|
+
readonly box: "size-10";
|
|
33
|
+
readonly fontSize: 15;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
export type TInitialsAvatarSize = keyof typeof SIZES;
|
|
37
|
+
export interface IInitialsAvatarProps {
|
|
38
|
+
name: string;
|
|
39
|
+
photoUrl?: string | null;
|
|
40
|
+
/** xs 20px, sm 24px in table rows, md 32px in a sidebar, lg 40px in a menu's header. */
|
|
41
|
+
size?: TInitialsAvatarSize;
|
|
42
|
+
className?: string;
|
|
43
|
+
/** Colour the initials from the palette (on by default); off, they take the muted look. */
|
|
44
|
+
autoColor?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* An accessible name. Left out, the avatar is decoration, which is right beside
|
|
47
|
+
* the person's name; give one when it stands alone.
|
|
48
|
+
*/
|
|
49
|
+
label?: string;
|
|
50
|
+
}
|
|
51
|
+
/** A person's photo, or their initials on a circle in the palette colour they pick; both themes switch by themselves. */
|
|
52
|
+
export declare const InitialsAvatar: ({ name, photoUrl, size, className, autoColor, label }: IInitialsAvatarProps) => import('react').JSX.Element;
|
|
53
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InitialsAvatar: a stable colour per person, initials that fit, and a palette
|
|
3
|
+
* that stays readable.
|
|
4
|
+
*
|
|
5
|
+
* PATH TAKEN: the hash, the initials and the markup are plain logic, so happy-dom
|
|
6
|
+
* covers them. The palette claim ("every pair is readable") is checked against
|
|
7
|
+
* the real tokens.css, converting OKLCH to sRGB and measuring WCAG contrast, so
|
|
8
|
+
* the numbers cannot drift from the file.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './multi-select';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/** An option: `leading` goes before its label (an avatar, a status dot), `count` after it (how many it would show). */
|
|
3
|
+
export type TMultiSelectOption = {
|
|
4
|
+
value: string;
|
|
5
|
+
label: string;
|
|
6
|
+
count?: number;
|
|
7
|
+
leading?: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
/** Every word the component prints, so a product can translate it. */
|
|
10
|
+
export interface IMultiSelectLabels {
|
|
11
|
+
noMatches: string;
|
|
12
|
+
loading: string;
|
|
13
|
+
/** Shown when `error` is `true`; a string `error` replaces it. */
|
|
14
|
+
error: string;
|
|
15
|
+
retry: string;
|
|
16
|
+
loadMore: string;
|
|
17
|
+
loadingMore: string;
|
|
18
|
+
clear: string;
|
|
19
|
+
selectedCount: (count: number) => string;
|
|
20
|
+
}
|
|
21
|
+
export declare const DEFAULT_MULTI_SELECT_LABELS: IMultiSelectLabels;
|
|
22
|
+
/** Above this many options a list draws only the rows on screen. */
|
|
23
|
+
export declare const VIRTUALIZE_FROM = 100;
|
|
24
|
+
export interface IMultiSelectProps {
|
|
25
|
+
/** The trigger's text with nothing picked, which means no filter ("All dealer groups"). */
|
|
26
|
+
placeholder: string;
|
|
27
|
+
/** The search field's prompt ("Search dealer groups…"). */
|
|
28
|
+
searchPlaceholder: string;
|
|
29
|
+
/** The options to show now: all of a short fixed list, or in async mode the ones for the typed text. */
|
|
30
|
+
options: readonly TMultiSelectOption[];
|
|
31
|
+
value: readonly string[];
|
|
32
|
+
onValueChange: (value: string[]) => void;
|
|
33
|
+
/**
|
|
34
|
+
* What the trigger says once something is chosen. `selection` (default) names the one chosen or counts several;
|
|
35
|
+
* `label` keeps the label and only counts, so a value the page shows elsewhere (as a removable chip, say) is
|
|
36
|
+
* not repeated here: nothing chosen reads `placeholder`, anything chosen reads `labels.selectedCount(n)`.
|
|
37
|
+
*/
|
|
38
|
+
summary?: 'selection' | 'label';
|
|
39
|
+
/** For a Label's htmlFor. */
|
|
40
|
+
id?: string;
|
|
41
|
+
'aria-label'?: string;
|
|
42
|
+
/** Shown but not changeable (a read-only form). */
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
/** Layout only (a width); the look is the kit's. */
|
|
45
|
+
className?: string;
|
|
46
|
+
/**
|
|
47
|
+
* Passing this turns on ASYNC MODE, for lists that grow (people, dealer groups) and must
|
|
48
|
+
* be searched by the API rather than loaded whole and filtered in the browser. The
|
|
49
|
+
* component then never filters: it reports the typed text (after `searchDelay`) and shows
|
|
50
|
+
* whatever `options` the caller supplies for it. It is also called with '' each time the
|
|
51
|
+
* list opens, so the first page is fetched on demand, not at page load.
|
|
52
|
+
*/
|
|
53
|
+
onSearchChange?: (text: string) => void;
|
|
54
|
+
/** How long typing must pause before `onSearchChange` is called. Async mode only. */
|
|
55
|
+
searchDelay?: number;
|
|
56
|
+
/**
|
|
57
|
+
* The options behind the chosen values, for the ones not in the current `options`. A
|
|
58
|
+
* search that no longer returns a chosen value must not make it vanish from the trigger
|
|
59
|
+
* or the count, so the caller says what it is called. Without a label a value shows as
|
|
60
|
+
* itself.
|
|
61
|
+
*/
|
|
62
|
+
selectedOptions?: readonly TMultiSelectOption[];
|
|
63
|
+
/** The options for the typed text are on their way. The old ones stay until they arrive. */
|
|
64
|
+
loading?: boolean;
|
|
65
|
+
/** The request failed: `true` for the default message, or the message itself. */
|
|
66
|
+
error?: boolean | string;
|
|
67
|
+
onRetry?: () => void;
|
|
68
|
+
/** There is another page after `options`. */
|
|
69
|
+
hasMore?: boolean;
|
|
70
|
+
onLoadMore?: () => void;
|
|
71
|
+
/** The next page is on its way. */
|
|
72
|
+
loadingMore?: boolean;
|
|
73
|
+
labels?: Partial<IMultiSelectLabels>;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The options behind the chosen values, in the order they were chosen. A value with no
|
|
77
|
+
* known option is kept and shown as itself rather than dropped: a selection must never
|
|
78
|
+
* change just because a list did.
|
|
79
|
+
*/
|
|
80
|
+
export declare const resolveChosen: (value: readonly string[], options: readonly TMultiSelectOption[], selectedOptions?: readonly TMultiSelectOption[]) => TMultiSelectOption[];
|
|
81
|
+
/** What the trigger says: the placeholder, the one picked, or a count. */
|
|
82
|
+
export declare const summarize: (chosen: readonly TMultiSelectOption[], placeholder: string, labels: IMultiSelectLabels, summary?: "selection" | "label") => string;
|
|
83
|
+
/** Every chosen name, for a tooltip on a trigger whose text is cut. With `label` the names are not shown, so it is the text itself. */
|
|
84
|
+
export declare const fullSelection: (chosen: readonly TMultiSelectOption[], placeholder: string, labels: IMultiSelectLabels, summary?: "selection" | "label") => string;
|
|
85
|
+
/**
|
|
86
|
+
* A choice of several from a list: a trigger shaped like a Select that says what is picked
|
|
87
|
+
* (the placeholder, the one picked, or a count), and a popup with a search field and checkbox
|
|
88
|
+
* options, with the shared popup list style, the ScrollArea's bar and fades, and virtualization
|
|
89
|
+
* past VIRTUALIZE_FROM options. Nothing chosen means no filter.
|
|
90
|
+
*
|
|
91
|
+
* For a short fixed list pass `options` and nothing else: the component filters them as the
|
|
92
|
+
* user types. For a list that grows, pass `onSearchChange` and it becomes a window onto a
|
|
93
|
+
* server: the caller fetches the options for the typed text, and says when they are loading,
|
|
94
|
+
* failed, or have another page.
|
|
95
|
+
*/
|
|
96
|
+
export declare const MultiSelect: ({ placeholder, searchPlaceholder, options, value, onValueChange, id, disabled, className, onSearchChange, searchDelay, selectedOptions, loading, error, onRetry, hasMore, onLoadMore, loadingMore, labels: labelOverrides, summary, ...rest }: IMultiSelectProps) => import('react').JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MultiSelect: what stays chosen, what the trigger says, and what words it prints.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: the rules that keep a selection stable while the list under it changes
|
|
5
|
+
* are plain functions, and the closed trigger renders in happy-dom. Opening the popup,
|
|
6
|
+
* typing, the server round trips and virtualization need a real browser, so
|
|
7
|
+
* e2e/multi-select.spec.ts drives those against a fake server.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './progress-line';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The line's colour: an app sets --progress-line (on :root, or on any element above the
|
|
4
|
+
* line) to match its accent. The fallback is read where the line is, so it follows the
|
|
5
|
+
* theme, which a default declared once on :root would not.
|
|
6
|
+
*/
|
|
7
|
+
export declare const PROGRESS_LINE_COLOR = "var(--progress-line, var(--primary))";
|
|
8
|
+
export interface IProgressLineProps {
|
|
9
|
+
/** Work is under way. */
|
|
10
|
+
active: boolean;
|
|
11
|
+
label?: string;
|
|
12
|
+
className?: string;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A thin line in the accent (--progress-line, by default --primary) that runs along the top of what is loading (a table's rows
|
|
17
|
+
* under its header, a page under the top bar). It waits a moment before it shows, so
|
|
18
|
+
* quick work never flashes it; it eases towards the end without reaching it while the
|
|
19
|
+
* work runs; when the work is done it runs to the end and only then fades. More work
|
|
20
|
+
* before it has gone carries on from where it is. With reduced motion it is a
|
|
21
|
+
* full-width line that fades.
|
|
22
|
+
*/
|
|
23
|
+
export declare const ProgressLine: ({ active, label, className, style }: IProgressLineProps) => import('react').JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ProgressLine: waits before it shows, eases while the work runs, finishes before it fades.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: the phase machine is timers and state, so happy-dom with the real
|
|
5
|
+
* clock covers it (the delays are 150, 150 and 200ms, waited out with margin
|
|
6
|
+
* rather than faked). Carrying on from where the line is after more work arrives
|
|
7
|
+
* mid-fade needs a real computed transform, so e2e/progress-line.spec.ts covers it.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
@@ -10,7 +10,7 @@ export declare const Attachment: ({ className, state, size, orientation, ...prop
|
|
|
10
10
|
state?: "idle" | "uploading" | "processing" | "error" | "done";
|
|
11
11
|
}) => React.JSX.Element;
|
|
12
12
|
declare const attachmentMediaVariants: (props?: ({
|
|
13
|
-
variant?: "
|
|
13
|
+
variant?: "icon" | "image" | null | undefined;
|
|
14
14
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
15
15
|
export declare const AttachmentMedia: ({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof attachmentMediaVariants>) => React.JSX.Element;
|
|
16
16
|
export declare const AttachmentContent: ({ className, ...props }: React.ComponentProps<"div">) => React.JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Button that renders a link has to stay a link.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: the roles and attributes Base UI emits do not depend on layout, so
|
|
5
|
+
* happy-dom is enough to assert what assistive technology would be told. The
|
|
6
|
+
* axe scan over the demo pages covers it again in a real browser.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
@@ -4,18 +4,17 @@ export declare const DropdownMenu: ({ ...props }: MenuPrimitive.Root.Props) => R
|
|
|
4
4
|
export declare const DropdownMenuPortal: ({ ...props }: MenuPrimitive.Portal.Props) => React.JSX.Element;
|
|
5
5
|
export declare const DropdownMenuTrigger: ({ ...props }: MenuPrimitive.Trigger.Props) => React.JSX.Element;
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Scrolls inside a DS ScrollArea like the other popup lists, with the bar shown
|
|
8
|
+
* for as long as the menu overflows and a fade on whichever end is cut off.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* part (Select.List) and leave the popup as presentation.
|
|
10
|
+
* Base UI puts `role="menu"` on this popup itself and offers no inner list part
|
|
11
|
+
* to move it onto, so the ScrollArea sits INSIDE the role. That is only legal
|
|
12
|
+
* because ScrollArea drops the `role="presentation"` Base UI gives its root,
|
|
13
|
+
* viewport and content: a menu may not own presentation wrappers (axe reports
|
|
14
|
+
* a critical aria-required-children violation), but it may own plain divs.
|
|
15
|
+
* e2e/a11y.spec.ts scans the open menu in both themes to keep it that way.
|
|
17
16
|
*/
|
|
18
|
-
export declare const DropdownMenuContent: ({ align, alignOffset, side, sideOffset, className, ...props }: MenuPrimitive.Popup.Props & Pick<MenuPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) => React.JSX.Element;
|
|
17
|
+
export declare const DropdownMenuContent: ({ align, alignOffset, side, sideOffset, className, children, ...props }: MenuPrimitive.Popup.Props & Pick<MenuPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset">) => React.JSX.Element;
|
|
19
18
|
export declare const DropdownMenuGroup: ({ ...props }: MenuPrimitive.Group.Props) => React.JSX.Element;
|
|
20
19
|
export declare const DropdownMenuLabel: ({ className, inset, ...props }: MenuPrimitive.GroupLabel.Props & {
|
|
21
20
|
inset?: boolean;
|
|
@@ -6,7 +6,7 @@ export interface IInputGroupProps extends React.ComponentProps<'div'> {
|
|
|
6
6
|
export declare const InputGroup: ({ className, ...props }: IInputGroupProps) => React.JSX.Element;
|
|
7
7
|
export type TInputGroupAddonAlign = 'inline-start' | 'inline-end' | 'block-start' | 'block-end';
|
|
8
8
|
declare const inputGroupAddonVariants: (props?: ({
|
|
9
|
-
align?: "inline-
|
|
9
|
+
align?: "inline-end" | "inline-start" | "block-start" | "block-end" | null | undefined;
|
|
10
10
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
11
11
|
export interface IInputGroupAddonProps extends React.ComponentProps<'div'>, VariantProps<typeof inputGroupAddonVariants> {
|
|
12
12
|
}
|
|
@@ -10,7 +10,7 @@ declare const itemVariants: (props?: ({
|
|
|
10
10
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
11
11
|
export declare const Item: ({ className, variant, size, render, ...props }: useRender.ComponentProps<"div"> & VariantProps<typeof itemVariants>) => React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
12
12
|
declare const itemMediaVariants: (props?: ({
|
|
13
|
-
variant?: "default" | "
|
|
13
|
+
variant?: "default" | "icon" | "image" | null | undefined;
|
|
14
14
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
15
15
|
export declare const ItemMedia: ({ className, variant, ...props }: React.ComponentProps<"div"> & VariantProps<typeof itemMediaVariants>) => React.JSX.Element;
|
|
16
16
|
export declare const ItemContent: ({ className, ...props }: React.ComponentProps<"div">) => React.JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Progress tones: a closed set of theme tokens, never a free class string.
|
|
3
|
+
*
|
|
4
|
+
* PATH TAKEN: classes and attributes do not depend on layout, so happy-dom is enough. The
|
|
5
|
+
* tokens' contrast is measured from the real tokens.css below, and the rendered colours in
|
|
6
|
+
* the browser by e2e/progress-tone.spec.ts.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
import { Progress as ProgressPrimitive } from '@base-ui/react/progress';
|
|
2
|
+
import { VariantProps } from 'class-variance-authority';
|
|
3
|
+
/**
|
|
4
|
+
* The tones: a closed set of semantic colours rather than a class string, so a bar cannot carry a
|
|
5
|
+
* colour the theme does not define and dark mode and a re-theme keep working. Each is the theme token
|
|
6
|
+
* the fill uses; the track is a 20% tint of the same token.
|
|
7
|
+
*/
|
|
8
|
+
declare const TONE_TOKEN: {
|
|
9
|
+
readonly default: "var(--primary)";
|
|
10
|
+
readonly info: "var(--info)";
|
|
11
|
+
readonly success: "var(--success)";
|
|
12
|
+
readonly warning: "var(--warning)";
|
|
13
|
+
readonly destructive: "var(--destructive)";
|
|
14
|
+
};
|
|
15
|
+
export type TProgressTone = keyof typeof TONE_TOKEN;
|
|
16
|
+
/**
|
|
17
|
+
* Colours an app can set without a class string. --progress-color replaces the fill (any colour, such as an
|
|
18
|
+
* app's own status tokens); --progress-track replaces the track, which does not follow the fill: an app
|
|
19
|
+
* that wants a neutral track sets it to var(--muted). Both are read where the bar is, so they follow the
|
|
20
|
+
* theme and can be set on :root or on any ancestor.
|
|
21
|
+
*/
|
|
22
|
+
export declare const progressFill: (tone: TProgressTone) => string;
|
|
23
|
+
export declare const progressTrack: (tone: TProgressTone) => string;
|
|
24
|
+
/**
|
|
25
|
+
* How the fill eases its width. The defaults are the 300ms ease-in-out it always had; an app retunes them
|
|
26
|
+
* with --progress-duration and --progress-ease, or turns the easing off with `animated={false}` when the
|
|
27
|
+
* number it shows is itself animated and the bar is driven from the same clock.
|
|
28
|
+
*/
|
|
29
|
+
export declare const PROGRESS_DURATION = "var(--progress-duration, 300ms)";
|
|
30
|
+
export declare const PROGRESS_EASE = "var(--progress-ease, cubic-bezier(0.4, 0, 0.2, 1))";
|
|
31
|
+
declare const progressTrackVariants: (props?: ({
|
|
32
|
+
size?: "default" | "sm" | null | undefined;
|
|
33
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
2
34
|
export interface IProgressProps extends Omit<ProgressPrimitive.Root.Props, 'value'> {
|
|
3
35
|
value?: number | null;
|
|
36
|
+
/** The bar's colour: a share of a total reads as `warning` when nearly used up, `success` when done. */
|
|
37
|
+
tone?: TProgressTone;
|
|
38
|
+
/** 4px (`sm`) or 8px (default) tall. */
|
|
39
|
+
size?: VariantProps<typeof progressTrackVariants>['size'];
|
|
40
|
+
/**
|
|
41
|
+
* Whether the fill eases when `value` changes. Turn it off when the value already moves smoothly
|
|
42
|
+
* (driven from an animated number's clock), or the bar eases a second time behind it.
|
|
43
|
+
*/
|
|
44
|
+
animated?: boolean;
|
|
4
45
|
}
|
|
5
|
-
export declare const Progress: ({ value, className, ...props }: IProgressProps) => import('react').JSX.Element;
|
|
46
|
+
export declare const Progress: ({ value, tone, size, animated, className, ...props }: IProgressProps) => import('react').JSX.Element;
|
|
47
|
+
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Edge-fade wiring and the sizing contract for ScrollArea.
|
|
3
3
|
*
|
|
4
|
-
* PATH TAKEN: the fades are
|
|
5
|
-
* keeps on the root (data-overflow-y-start and friends).
|
|
6
|
-
* layout nor a stylesheet, so what is checked here is
|
|
7
|
-
* the
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* PATH TAKEN: the fades are cut by a mask in scroll-fade.css, keyed off the
|
|
5
|
+
* overflow flags Base UI keeps on the root (data-overflow-y-start and friends).
|
|
6
|
+
* happy-dom has neither layout nor a stylesheet, so what is checked here is the
|
|
7
|
+
* contract the stylesheet reads: which axis the component declares, and that
|
|
8
|
+
* nothing of the painted version is left behind. The mask itself, and the flags
|
|
9
|
+
* flipping at the right moment, are measured in a real browser by
|
|
10
|
+
* e2e/scroll-area-fade.spec.ts.
|
|
10
11
|
*/
|
|
11
12
|
export {};
|
|
@@ -7,7 +7,12 @@ import { ComponentProps, RefObject } from 'react';
|
|
|
7
7
|
* when there is something to scroll", never a bar on a list that fits.
|
|
8
8
|
*/
|
|
9
9
|
export type TScrollbarVisibility = 'hover' | 'scroll' | 'always';
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Surface the edge fades blended into, back when they were painted.
|
|
12
|
+
*
|
|
13
|
+
* @deprecated The fades are cut into the content by a mask, so they match any
|
|
14
|
+
* surface without being told which one. Still accepted, and ignored.
|
|
15
|
+
*/
|
|
11
16
|
export type TScrollAreaFadeFrom = 'card' | 'background' | 'sidebar' | 'popover';
|
|
12
17
|
export interface IScrollBarProps extends ComponentProps<typeof BaseScrollArea.Scrollbar> {
|
|
13
18
|
visibility?: TScrollbarVisibility;
|
|
@@ -20,7 +25,10 @@ export interface IScrollAreaProps extends ComponentProps<typeof BaseScrollArea.R
|
|
|
20
25
|
type?: TScrollbarVisibility;
|
|
21
26
|
/** Edge fades hinting at clipped content; each one shows only while its own edge hides something. */
|
|
22
27
|
fade?: boolean;
|
|
23
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated No longer read. The fades mask the content, so they sit correctly
|
|
30
|
+
* on any surface; passing this does nothing and is safe to delete.
|
|
31
|
+
*/
|
|
24
32
|
fadeFrom?: TScrollAreaFadeFrom;
|
|
25
33
|
/** Places both bars, for a host that gives them a gutter of their own (a sidebar menu). */
|
|
26
34
|
scrollbarClassName?: string;
|
|
@@ -30,6 +38,13 @@ export interface IScrollAreaProps extends ComponentProps<typeof BaseScrollArea.R
|
|
|
30
38
|
viewportClassName?: string;
|
|
31
39
|
/** Published on the viewport as data-scroll-restoration-id, for a router that restores scroll position. */
|
|
32
40
|
scrollRestorationId?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the viewport is a tab stop of its own (default). Turn it off inside a
|
|
43
|
+
* widget that already owns focus, a menu above all: its items are the tab
|
|
44
|
+
* stops, and a focusable wrapper between the role and its items is both
|
|
45
|
+
* redundant and an aria-required-children violation.
|
|
46
|
+
*/
|
|
47
|
+
focusable?: boolean;
|
|
33
48
|
/** @deprecated Use `viewportId`. */
|
|
34
49
|
viewPortId?: string;
|
|
35
50
|
/** @deprecated Use `viewportRef`. */
|
|
@@ -54,13 +69,17 @@ export interface IScrollAreaProps extends ComponentProps<typeof BaseScrollArea.R
|
|
|
54
69
|
* underneath with no scrollbar, and that reads as a working height right up until the
|
|
55
70
|
* content outgrows it.
|
|
56
71
|
*
|
|
57
|
-
* `fade`
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
72
|
+
* `fade` fades out each edge that is currently hiding content, rather than always
|
|
73
|
+
* fading one: a permanent fade is a lie half the time, dimming the last row that fits
|
|
74
|
+
* and promising more below when the reader is already at the end. It is cut into the
|
|
75
|
+
* content by a mask (@edyn/theme/scroll-fade.css), so it needs no surface colour and
|
|
76
|
+
* reads correctly over a tint, a gradient or a glow. A host that keeps something
|
|
77
|
+
* unscrolled at the top, such as a sticky table header, exempts that band by setting
|
|
78
|
+
* --scroll-fade-offset on the ScrollArea. The static faded-* utilities in
|
|
79
|
+
* @edyn/theme/utilities.css are the other tool, for DECORATIVE edges that do not
|
|
80
|
+
* track scroll position.
|
|
62
81
|
*
|
|
63
82
|
* The viewport publishes its size as --scroll-area-width/--scroll-area-height CSS vars
|
|
64
83
|
* so children can size against the visible area.
|
|
65
84
|
*/
|
|
66
|
-
export declare const ScrollArea: ({ className, children, orientation, type, fade, fadeFrom, scrollbarClassName, viewportId, viewportRef, viewportClassName, scrollRestorationId, viewPortId, viewPortRef, viewPortClassName, scrollVerticalClassName, scrollHorizontalClassName, ...props }: IScrollAreaProps) => import('react').JSX.Element;
|
|
85
|
+
export declare const ScrollArea: ({ className, children, orientation, type, fade, fadeFrom, scrollbarClassName, viewportId, viewportRef, viewportClassName, scrollRestorationId, focusable, viewPortId, viewPortRef, viewPortClassName, scrollVerticalClassName, scrollHorizontalClassName, ...props }: IScrollAreaProps) => import('react').JSX.Element;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Structure test for the Table primitives.
|
|
3
3
|
*
|
|
4
|
-
* Uses happy-dom (registered by test-setup.ts) and the
|
|
5
|
-
* pattern
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* (and the Angular demos that consume it) get a real, accessible table.
|
|
4
|
+
* Uses happy-dom (registered by test-setup.ts) and the React-in-bun-test
|
|
5
|
+
* pattern: render with createRoot + flushSync, then query the real DOM. Guards
|
|
6
|
+
* that the primitives produce a semantic <table> (thead/tbody/th/td/caption) and
|
|
7
|
+
* the shadcn overflow wrapper, so consumers get a real, accessible table.
|
|
9
8
|
*/
|
|
10
9
|
export {};
|
package/dist/ui/src/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
export * from './components/edyn/animated-number';
|
|
1
2
|
export * from './components/edyn/audio-player';
|
|
3
|
+
export * from './components/edyn/date-range-picker';
|
|
4
|
+
export * from './components/edyn/initials-avatar';
|
|
5
|
+
export * from './components/edyn/multi-select';
|
|
6
|
+
export * from './components/edyn/progress-line';
|
|
2
7
|
export * from './components/edyn/video-player';
|
|
3
8
|
export * from './components/ui/accordion';
|
|
4
9
|
export * from './components/ui/alert';
|