aplance-ui 1.4.0 → 1.5.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/package.json +1 -1
- package/registry/components/primitives/icon/icon.tsx +4 -6
- package/registry/components/primitives/modal/modal.module.css +5 -0
- package/registry/components/primitives/modal/modal.tsx +32 -34
- package/registry/components/primitives/popover/popover.module.css +4 -2
- package/registry/components/primitives/popover/popover.tsx +16 -17
- package/registry/components/primitives/scroll-rail/scroll-rail.module.css +148 -0
- package/registry/components/primitives/scroll-rail/scroll-rail.tsx +214 -0
- package/registry/components/ui/accordion/accordion.module.css +52 -0
- package/registry/components/ui/accordion/accordion.tsx +97 -25
- package/registry/components/ui/avatar/avatar.tsx +2 -2
- package/registry/components/ui/breadcrumbs/breadcrumbs.module.css +9 -9
- package/registry/components/ui/button/button.module.css +43 -5
- package/registry/components/ui/button/button.tsx +2 -1
- package/registry/components/ui/copy-button/copy-button.module.css +2 -0
- package/registry/components/ui/data-table/data-table.module.css +68 -25
- package/registry/components/ui/data-table/data-table.tsx +1238 -1229
- package/registry/components/ui/data-table/filters.tsx +21 -0
- package/registry/components/ui/data-table/pagination-bar.tsx +31 -17
- package/registry/components/ui/data-table/types.ts +11 -1
- package/registry/components/ui/data-table/useDataTable.tsx +1 -2
- package/registry/components/ui/data-table/utils.ts +4 -3
- package/registry/components/ui/input-fields/common/input-field-common.module.css +8 -2
- package/registry/components/ui/input-fields/common/picker-popover-common.module.css +4 -0
- package/registry/components/ui/input-fields/custom-select/custom-select.module.css +115 -84
- package/registry/components/ui/input-fields/custom-select/custom-select.tsx +63 -11
- package/registry/components/ui/input-fields/date-picker/date-picker.tsx +51 -55
- package/registry/components/ui/input-fields/input/input.tsx +348 -348
- package/registry/components/ui/input-fields/media-input/media-input.tsx +3 -1
- package/registry/components/ui/input-fields/media-input/types.ts +8 -2
- package/registry/components/ui/input-fields/media-input/useMediaUpload.tsx +5 -5
- package/registry/components/ui/input-fields/media-input/utils.ts +18 -5
- package/registry/components/ui/tabs/tabs.module.css +8 -12
- package/registry/components/ui/tabs/tabs.tsx +75 -44
- package/registry/components/ui/tooltip/tooltip.module.css +8 -3
- package/registry/components/ui/tooltip/tooltip.tsx +16 -3
- package/registry/lib/string.ts +3 -3
- package/registry/registry.json +32 -3
|
@@ -111,7 +111,9 @@ export const MediaInput = (props: MediaInputProps) => {
|
|
|
111
111
|
(multiple ? "Drop files here or browse" : "Drop a file here or browse");
|
|
112
112
|
const hintParts = [
|
|
113
113
|
accept ? `Accepts ${accept}` : null,
|
|
114
|
-
maxSize
|
|
114
|
+
typeof maxSize === "number" && maxSize > 0
|
|
115
|
+
? `Up to ${formatBytes(maxSize)} per file`
|
|
116
|
+
: null,
|
|
115
117
|
multiple && maxFiles ? `Max ${maxFiles} files` : null,
|
|
116
118
|
].filter(Boolean);
|
|
117
119
|
const resolvedHint = dropzoneHint ?? hintParts.join(" - ");
|
|
@@ -58,6 +58,9 @@ export type MediaPreviewLayout = (typeof mediaPreviewLayouts)[number];
|
|
|
58
58
|
export const mediaPreviewSizes = ["sm", "md", "lg"] as const;
|
|
59
59
|
export type MediaPreviewSize = (typeof mediaPreviewSizes)[number];
|
|
60
60
|
|
|
61
|
+
/** A size cap for every file, or each file's own; undefined takes any size. */
|
|
62
|
+
export type MaxSize = number | ((file: File) => number | undefined);
|
|
63
|
+
|
|
61
64
|
export type MediaInputProps = Omit<
|
|
62
65
|
BaseInputFieldProps,
|
|
63
66
|
"iconStart" | "iconEnd"
|
|
@@ -68,8 +71,11 @@ export type MediaInputProps = Omit<
|
|
|
68
71
|
multiple?: boolean;
|
|
69
72
|
/** Hard cap on accepted files (only enforced when `multiple`). */
|
|
70
73
|
maxFiles?: number;
|
|
71
|
-
/**
|
|
72
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Per-file size cap in bytes, or a function giving a file's own cap, for a
|
|
76
|
+
* field that takes kinds of file with caps of their own.
|
|
77
|
+
*/
|
|
78
|
+
maxSize?: MaxSize;
|
|
73
79
|
|
|
74
80
|
/**
|
|
75
81
|
* Variant for the inner Browse button. Independent from `buttonStyle`
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
useRef,
|
|
11
11
|
useState,
|
|
12
12
|
} from "react";
|
|
13
|
-
import type { MediaFile, MediaRejection } from "./types";
|
|
13
|
+
import type { MaxSize, MediaFile, MediaRejection } from "./types";
|
|
14
14
|
import {
|
|
15
15
|
revokePreviewUrl,
|
|
16
16
|
validateIncomingFiles,
|
|
@@ -30,7 +30,7 @@ export type UseMediaUploadOptions = {
|
|
|
30
30
|
accept?: string;
|
|
31
31
|
multiple?: boolean;
|
|
32
32
|
maxFiles?: number;
|
|
33
|
-
maxSize?:
|
|
33
|
+
maxSize?: MaxSize;
|
|
34
34
|
|
|
35
35
|
disabled?: boolean;
|
|
36
36
|
readOnly?: boolean;
|
|
@@ -96,10 +96,10 @@ export function useMediaUpload({
|
|
|
96
96
|
filesRef.current = isControlled ? value! : internal;
|
|
97
97
|
}, [isControlled, value, internal]);
|
|
98
98
|
|
|
99
|
+
// Disabled or read-only ends a drag in progress, in the render that sees it.
|
|
100
|
+
if ((disabled || readOnly) && isDragging) setIsDragging(false);
|
|
99
101
|
useEffect(() => {
|
|
100
|
-
if (
|
|
101
|
-
dragCounter.current = 0;
|
|
102
|
-
setIsDragging(false);
|
|
102
|
+
if (disabled || readOnly) dragCounter.current = 0;
|
|
103
103
|
}, [disabled, readOnly]);
|
|
104
104
|
|
|
105
105
|
// Revoke any preview URLs the hook created on unmount so blob memory is
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
MaxSize,
|
|
3
|
+
MediaFile,
|
|
4
|
+
MediaKind,
|
|
5
|
+
MediaRejection,
|
|
6
|
+
MediaRejectionCode,
|
|
7
|
+
} from "./types";
|
|
2
8
|
|
|
3
9
|
const SIZE_UNITS = ["B", "KB", "MB", "GB", "TB"] as const;
|
|
4
10
|
|
|
@@ -114,7 +120,7 @@ export const rejectionMessage = (
|
|
|
114
120
|
|
|
115
121
|
export type ValidateOptions = {
|
|
116
122
|
accept?: string;
|
|
117
|
-
maxSize?:
|
|
123
|
+
maxSize?: MaxSize;
|
|
118
124
|
maxFiles?: number;
|
|
119
125
|
multiple: boolean;
|
|
120
126
|
existing: MediaFile[];
|
|
@@ -142,10 +148,16 @@ export const validateIncomingFiles = (
|
|
|
142
148
|
typeof options.maxFiles === "number" && Number.isFinite(options.maxFiles)
|
|
143
149
|
? Math.max(0, Math.floor(options.maxFiles))
|
|
144
150
|
: undefined;
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
151
|
+
// A file's own cap: the one for every file, or the one the function gives it.
|
|
152
|
+
const capOf = (file: File) => {
|
|
153
|
+
const cap =
|
|
154
|
+
typeof options.maxSize === "function"
|
|
155
|
+
? options.maxSize(file)
|
|
156
|
+
: options.maxSize;
|
|
157
|
+
return typeof cap === "number" && Number.isFinite(cap)
|
|
158
|
+
? Math.max(0, cap)
|
|
148
159
|
: undefined;
|
|
160
|
+
};
|
|
149
161
|
const remainingCapacity = options.multiple
|
|
150
162
|
? maxFiles !== undefined
|
|
151
163
|
? Math.max(0, maxFiles - options.existing.length)
|
|
@@ -161,6 +173,7 @@ export const validateIncomingFiles = (
|
|
|
161
173
|
});
|
|
162
174
|
continue;
|
|
163
175
|
}
|
|
176
|
+
const maxSize = capOf(file);
|
|
164
177
|
if (maxSize !== undefined && file.size > maxSize) {
|
|
165
178
|
rejected.push({
|
|
166
179
|
file,
|
|
@@ -10,23 +10,19 @@
|
|
|
10
10
|
|
|
11
11
|
/* ─────────────────────────────────────────────
|
|
12
12
|
Tab list
|
|
13
|
+
It sits in a ScrollRail, which scrolls it when the tabs don't fit (many
|
|
14
|
+
status tabs on a phone) with fades and chevrons at the ends that have
|
|
15
|
+
more. The rail's row is at least its width, so the list still spans it.
|
|
13
16
|
───────────────────────────────────────────── */
|
|
17
|
+
.rail_content {
|
|
18
|
+
min-width: 100%;
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
.list {
|
|
15
22
|
position: relative;
|
|
16
23
|
display: inline-flex;
|
|
24
|
+
flex: 1 0 auto;
|
|
17
25
|
align-items: center;
|
|
18
|
-
/* Scroll horizontally when the tabs don't fit (e.g. many status tabs on a
|
|
19
|
-
phone) instead of clipping/overflowing the page. The active indicator is
|
|
20
|
-
absolutely positioned inside, so it scrolls with the tabs and stays aligned.
|
|
21
|
-
Scrollbar hidden for a clean strip - the partially-shown edge tab signals
|
|
22
|
-
scrollability. */
|
|
23
|
-
max-width: 100%;
|
|
24
|
-
overflow-x: auto;
|
|
25
|
-
scrollbar-width: none;
|
|
26
|
-
|
|
27
|
-
&::-webkit-scrollbar {
|
|
28
|
-
display: none;
|
|
29
|
-
}
|
|
30
26
|
|
|
31
27
|
/* style1 - pill container */
|
|
32
28
|
&.list_style1 {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from "react";
|
|
11
11
|
import clsx from "clsx";
|
|
12
12
|
import { useResizeObserver } from "../../../hooks/useResizeObserver";
|
|
13
|
+
import { ScrollRail } from "../../primitives/scroll-rail/scroll-rail";
|
|
13
14
|
import s from "./tabs.module.css";
|
|
14
15
|
|
|
15
16
|
// Variants & Types
|
|
@@ -57,6 +58,8 @@ export const Tabs = ({
|
|
|
57
58
|
|
|
58
59
|
// `animate` separates deliberate tab switches from layout-driven re-fits.
|
|
59
60
|
const listRef = useRef<HTMLDivElement>(null);
|
|
61
|
+
// The rail's scroller, when the tabs are wider than their row.
|
|
62
|
+
const railRef = useRef<HTMLDivElement>(null);
|
|
60
63
|
const [indicator, setIndicator] = useState({ left: 0, width: 0, animate: true });
|
|
61
64
|
|
|
62
65
|
const updateIndicator = useCallback((id: string, animate: boolean) => {
|
|
@@ -66,21 +69,46 @@ export const Tabs = ({
|
|
|
66
69
|
if (!btn) return;
|
|
67
70
|
const listRect = list.getBoundingClientRect();
|
|
68
71
|
const btnRect = btn.getBoundingClientRect();
|
|
69
|
-
//
|
|
70
|
-
// stays
|
|
71
|
-
const left = btnRect.left - listRect.left
|
|
72
|
+
// Measured against the list, which scrolls with its tabs inside the rail,
|
|
73
|
+
// so the indicator stays on its tab wherever the strip is scrolled.
|
|
74
|
+
const left = btnRect.left - listRect.left;
|
|
72
75
|
const width = btnRect.width;
|
|
73
76
|
setIndicator((prev) =>
|
|
74
77
|
prev.left === left && prev.width === width ? prev : { left, width, animate },
|
|
75
78
|
);
|
|
76
79
|
}, []);
|
|
77
80
|
|
|
81
|
+
// The active tab in view: a strip wider than its row opens on its tab, and
|
|
82
|
+
// scrolls to each one chosen that sits past an edge. A tab already in view
|
|
83
|
+
// stays where it is.
|
|
84
|
+
const revealActive = useCallback((id: string, animate: boolean) => {
|
|
85
|
+
const rail = railRef.current;
|
|
86
|
+
const btn = listRef.current?.querySelector<HTMLButtonElement>(
|
|
87
|
+
`[data-tab-id="${id}"]`,
|
|
88
|
+
);
|
|
89
|
+
if (!rail || !btn) return;
|
|
90
|
+
const railRect = rail.getBoundingClientRect();
|
|
91
|
+
const btnRect = btn.getBoundingClientRect();
|
|
92
|
+
if (btnRect.left >= railRect.left && btnRect.right <= railRect.right) return;
|
|
93
|
+
const still = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
94
|
+
rail.scrollTo({
|
|
95
|
+
left:
|
|
96
|
+
rail.scrollLeft +
|
|
97
|
+
btnRect.left -
|
|
98
|
+
railRect.left -
|
|
99
|
+
(railRect.width - btnRect.width) / 2,
|
|
100
|
+
behavior: animate && !still ? "smooth" : "auto",
|
|
101
|
+
});
|
|
102
|
+
}, []);
|
|
103
|
+
|
|
78
104
|
const prevActiveRef = useRef<string | null>(null);
|
|
79
105
|
useIsomorphicLayoutEffect(() => {
|
|
80
106
|
const isSwitch = prevActiveRef.current !== activeId;
|
|
107
|
+
const isFirst = prevActiveRef.current === null;
|
|
81
108
|
prevActiveRef.current = activeId;
|
|
82
109
|
updateIndicator(activeId, isSwitch);
|
|
83
|
-
|
|
110
|
+
revealActive(activeId, !isFirst);
|
|
111
|
+
}, [tabs, activeId, updateIndicator, revealActive]);
|
|
84
112
|
|
|
85
113
|
// Container and font reflows re-fit the indicator without animating.
|
|
86
114
|
useResizeObserver(listRef, () => updateIndicator(activeId, false));
|
|
@@ -92,47 +120,50 @@ export const Tabs = ({
|
|
|
92
120
|
|
|
93
121
|
return (
|
|
94
122
|
<div className={clsx(s.root, className)} {...rest}>
|
|
95
|
-
{/* Tab List
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
{/* Tab List - in a rail that scrolls it, with fades and chevrons,
|
|
124
|
+
when the tabs are wider than their row */}
|
|
125
|
+
<ScrollRail ref={railRef} contentClassName={s.rail_content}>
|
|
126
|
+
<div
|
|
127
|
+
ref={listRef}
|
|
128
|
+
role="tablist"
|
|
129
|
+
className={clsx(s.list, s[`list_${variant}`])}
|
|
130
|
+
aria-orientation="horizontal"
|
|
131
|
+
>
|
|
132
|
+
{/* Animated indicator */}
|
|
133
|
+
<span
|
|
134
|
+
className={clsx(s.indicator, s[`indicator_${variant}`])}
|
|
135
|
+
style={{
|
|
136
|
+
left: indicator.left,
|
|
137
|
+
width: indicator.width,
|
|
138
|
+
transition: indicator.animate ? undefined : "none",
|
|
139
|
+
}}
|
|
140
|
+
aria-hidden="true"
|
|
141
|
+
/>
|
|
112
142
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
143
|
+
{tabs.map((tab) => {
|
|
144
|
+
const isActive = tab.id === activeId;
|
|
145
|
+
return (
|
|
146
|
+
<button
|
|
147
|
+
key={tab.id}
|
|
148
|
+
role="tab"
|
|
149
|
+
id={`${uid}-tab-${tab.id}`}
|
|
150
|
+
aria-controls={`${uid}-panel-${tab.id}`}
|
|
151
|
+
aria-selected={isActive}
|
|
152
|
+
disabled={tab.disabled}
|
|
153
|
+
data-tab-id={tab.id}
|
|
154
|
+
className={clsx(
|
|
155
|
+
s.tab,
|
|
156
|
+
s[`tab_${variant}`],
|
|
157
|
+
isActive && s.tab_active,
|
|
158
|
+
)}
|
|
159
|
+
onClick={() => !tab.disabled && handleSelect(tab.id)}
|
|
160
|
+
>
|
|
161
|
+
{tab.label}
|
|
162
|
+
</button>
|
|
163
|
+
);
|
|
164
|
+
})}
|
|
165
|
+
</div>
|
|
166
|
+
</ScrollRail>
|
|
136
167
|
|
|
137
168
|
{/* Tab Panel */}
|
|
138
169
|
{activeContent !== undefined && (
|
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
not including the popover selectors because it's not at all required
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
/* The cap, applied together with the space the popover found (tooltip.tsx).
|
|
6
|
+
Zero specificity, so a class passed through `popoverMenu.className` can set
|
|
7
|
+
its own. */
|
|
8
|
+
:where(.container) {
|
|
9
|
+
--tooltip-max-width: 250px;
|
|
10
|
+
}
|
|
11
|
+
|
|
5
12
|
.container {
|
|
6
|
-
width:
|
|
7
|
-
min-width: fit-content;
|
|
8
|
-
max-width: 250px;
|
|
13
|
+
width: max-content;
|
|
9
14
|
background-color: var(--color-secondary);
|
|
10
15
|
color: var(--color-secondary-foreground);
|
|
11
16
|
border-radius: var(--radius-sm);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ReactNode, type FC } from "react";
|
|
1
|
+
import { type CSSProperties, type ReactNode, type FC } from "react";
|
|
2
2
|
import {
|
|
3
3
|
Popover,
|
|
4
4
|
PopoverTrigger,
|
|
@@ -26,6 +26,16 @@ export type TooltipProps = {
|
|
|
26
26
|
popoverMenu?: ComponentProps<typeof PopoverMenu>;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
// The menu's auto positioning sizes it as a dropdown: `overflow: auto` (which
|
|
30
|
+
// turns the arrow, outside the box, into a scrollbar) and a `max-width` of the
|
|
31
|
+
// space it found (which would replace the tooltip's own cap). A tooltip never
|
|
32
|
+
// scrolls and hugs its text up to the smaller of its cap and that space.
|
|
33
|
+
const menuStyle: CSSProperties = {
|
|
34
|
+
overflow: "visible",
|
|
35
|
+
maxWidth:
|
|
36
|
+
"min(var(--tooltip-max-width), var(--popover-available-width, var(--tooltip-max-width)))",
|
|
37
|
+
};
|
|
38
|
+
|
|
29
39
|
export const Tooltip: FC<TooltipProps> = ({
|
|
30
40
|
content,
|
|
31
41
|
children,
|
|
@@ -53,10 +63,13 @@ export const Tooltip: FC<TooltipProps> = ({
|
|
|
53
63
|
<PopoverTrigger asChild {...popoverTrigger}>
|
|
54
64
|
{children}
|
|
55
65
|
</PopoverTrigger>
|
|
56
|
-
{/* Using menu as a direct content wrapper
|
|
66
|
+
{/* Using menu as a direct content wrapper. Sized by its text, not by
|
|
67
|
+
what it points at. */}
|
|
57
68
|
<PopoverMenu
|
|
58
|
-
|
|
69
|
+
matchTriggerWidth={false}
|
|
59
70
|
{...popoverMenu}
|
|
71
|
+
className={clsx(s.container, popoverMenu?.className)}
|
|
72
|
+
style={{ ...menuStyle, ...popoverMenu?.style }}
|
|
60
73
|
>
|
|
61
74
|
{showArrow && (
|
|
62
75
|
<div
|
package/registry/lib/string.ts
CHANGED
|
@@ -17,7 +17,7 @@ export function hashName(name: string): number {
|
|
|
17
17
|
* Extract 1-2 letter initials from a name (e.g. "John Doe" -> "JD")
|
|
18
18
|
*/
|
|
19
19
|
export function getInitials(name: string): string {
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
return
|
|
20
|
+
const [first = "", second = ""] = name.trim().split(/\s+/);
|
|
21
|
+
if (second) return first.charAt(0) + second.charAt(0);
|
|
22
|
+
return first.substring(0, 2) || "?";
|
|
23
23
|
}
|
package/registry/registry.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://ui.aplance.com/registry.schema.json",
|
|
3
3
|
"version": 4,
|
|
4
|
-
"generated": "2026-
|
|
4
|
+
"generated": "2026-11-11T12:39:14.314Z",
|
|
5
5
|
"units": [
|
|
6
6
|
{
|
|
7
7
|
"name": "accordion",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"components/ui/accordion/accordion.tsx"
|
|
16
16
|
],
|
|
17
17
|
"deps": [
|
|
18
|
+
"button",
|
|
18
19
|
"useResizeObserver"
|
|
19
20
|
],
|
|
20
21
|
"externalDeps": [
|
|
@@ -214,6 +215,7 @@
|
|
|
214
215
|
"components/ui/data-table/data-table.tsx",
|
|
215
216
|
"components/ui/data-table/filter-bar.tsx",
|
|
216
217
|
"components/ui/data-table/filter-modal.tsx",
|
|
218
|
+
"components/ui/data-table/filters.tsx",
|
|
217
219
|
"components/ui/data-table/pagination-bar.tsx",
|
|
218
220
|
"components/ui/data-table/types.ts",
|
|
219
221
|
"components/ui/data-table/useDataTable.tsx",
|
|
@@ -223,6 +225,7 @@
|
|
|
223
225
|
"components/ui/data-table/checkbox-column.tsx",
|
|
224
226
|
"components/ui/data-table/data-table.tsx",
|
|
225
227
|
"components/ui/data-table/filter-modal.tsx",
|
|
228
|
+
"components/ui/data-table/filters.tsx",
|
|
226
229
|
"components/ui/data-table/pagination-bar.tsx",
|
|
227
230
|
"components/ui/data-table/types.ts",
|
|
228
231
|
"components/ui/data-table/useDataTable.tsx",
|
|
@@ -236,6 +239,7 @@
|
|
|
236
239
|
"lib-dom",
|
|
237
240
|
"loader",
|
|
238
241
|
"modal",
|
|
242
|
+
"scroll-rail",
|
|
239
243
|
"tooltip",
|
|
240
244
|
"useMediaQuery"
|
|
241
245
|
],
|
|
@@ -566,6 +570,26 @@
|
|
|
566
570
|
"react-dom"
|
|
567
571
|
]
|
|
568
572
|
},
|
|
573
|
+
{
|
|
574
|
+
"name": "scroll-rail",
|
|
575
|
+
"kind": "component",
|
|
576
|
+
"group": "primitives",
|
|
577
|
+
"files": [
|
|
578
|
+
"components/primitives/scroll-rail/scroll-rail.module.css",
|
|
579
|
+
"components/primitives/scroll-rail/scroll-rail.tsx"
|
|
580
|
+
],
|
|
581
|
+
"clientFiles": [
|
|
582
|
+
"components/primitives/scroll-rail/scroll-rail.tsx"
|
|
583
|
+
],
|
|
584
|
+
"deps": [
|
|
585
|
+
"useResizeObserver"
|
|
586
|
+
],
|
|
587
|
+
"externalDeps": [
|
|
588
|
+
"@tabler/icons-react",
|
|
589
|
+
"clsx",
|
|
590
|
+
"react"
|
|
591
|
+
]
|
|
592
|
+
},
|
|
569
593
|
{
|
|
570
594
|
"name": "select",
|
|
571
595
|
"kind": "component",
|
|
@@ -576,7 +600,9 @@
|
|
|
576
600
|
"components/ui/input-fields/common/types.ts",
|
|
577
601
|
"components/ui/input-fields/select/select.tsx"
|
|
578
602
|
],
|
|
579
|
-
"clientFiles": [
|
|
603
|
+
"clientFiles": [
|
|
604
|
+
"components/ui/input-fields/select/select.tsx"
|
|
605
|
+
],
|
|
580
606
|
"deps": [
|
|
581
607
|
"button",
|
|
582
608
|
"field-message",
|
|
@@ -664,7 +690,9 @@
|
|
|
664
690
|
"components/ui/input-fields/switch/switch.module.css",
|
|
665
691
|
"components/ui/input-fields/switch/switch.tsx"
|
|
666
692
|
],
|
|
667
|
-
"clientFiles": [
|
|
693
|
+
"clientFiles": [
|
|
694
|
+
"components/ui/input-fields/switch/switch.tsx"
|
|
695
|
+
],
|
|
668
696
|
"deps": [
|
|
669
697
|
"button",
|
|
670
698
|
"field-message"
|
|
@@ -686,6 +714,7 @@
|
|
|
686
714
|
"components/ui/tabs/tabs.tsx"
|
|
687
715
|
],
|
|
688
716
|
"deps": [
|
|
717
|
+
"scroll-rail",
|
|
689
718
|
"useResizeObserver"
|
|
690
719
|
],
|
|
691
720
|
"externalDeps": [
|