aplance-ui 1.1.1 → 1.2.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/api.d.ts +2 -0
- package/dist/api.js +4 -0
- package/dist/api.js.map +1 -1
- package/dist/index.js +18 -1
- package/dist/index.js.map +1 -1
- package/package.json +63 -63
- package/registry/components/primitives/infinite-scroll/infinite-scroll-context.ts +32 -0
- package/registry/components/primitives/infinite-scroll/infinite-scroll.module.css +118 -0
- package/registry/components/primitives/infinite-scroll/infinite-scroll.tsx +386 -0
- package/registry/components/primitives/slider/slider-context.ts +50 -0
- package/registry/components/primitives/slider/slider.module.css +300 -0
- package/registry/components/primitives/slider/slider.tsx +1174 -0
- package/registry/components/primitives/slider/types.ts +140 -0
- package/registry/components/primitives/slider/utils.ts +88 -0
- package/registry/components/ui/breadcrumbs/breadcrumbs.module.css +144 -0
- package/registry/components/ui/breadcrumbs/breadcrumbs.tsx +236 -0
- package/registry/components/ui/chart/chart.module.css +86 -70
- package/registry/components/ui/chart/chart.tsx +117 -31
- package/registry/components/ui/input-fields/media-input/media-input.module.css +12 -0
- package/registry/components/ui/input-fields/media-input/media-input.tsx +10 -9
- package/registry/components/ui/input-fields/media-input/useMediaUpload.tsx +19 -5
- package/registry/components/ui/input-fields/media-input/utils.ts +13 -5
- package/registry/registry.json +64 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createContext, useContext } from "react";
|
|
2
|
+
|
|
3
|
+
export type SliderApi = {
|
|
4
|
+
/** Current logical slide index. */
|
|
5
|
+
index: number;
|
|
6
|
+
/** Alias for index, useful when mirroring carousel terminology. */
|
|
7
|
+
activeIndex: number;
|
|
8
|
+
/** Total number of real slides. */
|
|
9
|
+
count: number;
|
|
10
|
+
/** Total number of snap points/pages. */
|
|
11
|
+
snapCount: number;
|
|
12
|
+
/** How many slides are visible in the current responsive layout. */
|
|
13
|
+
slidesPerView: number | "auto";
|
|
14
|
+
/** How many slides move on next/previous. */
|
|
15
|
+
slidesPerGroup: number;
|
|
16
|
+
/** 0..1 progress through the available snap points. */
|
|
17
|
+
progress: number;
|
|
18
|
+
/** Whether loop mode is active. */
|
|
19
|
+
isLoop: boolean;
|
|
20
|
+
/** Whether the pointer is currently dragging the track. */
|
|
21
|
+
isDragging: boolean;
|
|
22
|
+
/** Whether autoplay is currently paused by hover/focus/drag. */
|
|
23
|
+
isAutoplayPaused: boolean;
|
|
24
|
+
/** True when previous movement is not available in non-loop mode. */
|
|
25
|
+
isFirst: boolean;
|
|
26
|
+
/** True when next movement is not available in non-loop mode. */
|
|
27
|
+
isLast: boolean;
|
|
28
|
+
/** Alias for !isFirst. */
|
|
29
|
+
canSlidePrev: boolean;
|
|
30
|
+
/** Alias for !isLast. */
|
|
31
|
+
canSlideNext: boolean;
|
|
32
|
+
/** Advance by one group, or by a custom step count. */
|
|
33
|
+
next: (steps?: number) => void;
|
|
34
|
+
/** Move back by one group, or by a custom step count. */
|
|
35
|
+
prev: (steps?: number) => void;
|
|
36
|
+
/** Jump to a logical slide/snap index. */
|
|
37
|
+
goTo: (index: number) => void;
|
|
38
|
+
/** Alias for goTo. */
|
|
39
|
+
slideTo: (index: number) => void;
|
|
40
|
+
/** Stop autoplay for the rest of the current mount. */
|
|
41
|
+
stopAutoplay: () => void;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const SliderContext = createContext<SliderApi | undefined>(undefined);
|
|
45
|
+
|
|
46
|
+
export const useSlider = () => {
|
|
47
|
+
const ctx = useContext(SliderContext);
|
|
48
|
+
if (!ctx) throw new Error("useSlider must be used within a <Slider>");
|
|
49
|
+
return ctx;
|
|
50
|
+
};
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/* ─── Container ──────────────────────────────────────────────────────────────
|
|
2
|
+
Positioning context for nav arrows + pagination. Token contract is declared
|
|
3
|
+
on the root so consumer apps can theme dot/nav colors without overrides.
|
|
4
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
5
|
+
|
|
6
|
+
.container {
|
|
7
|
+
--slider-nav-size: var(--spacing-12);
|
|
8
|
+
--slider-nav-bg: color-mix(in srgb, var(--color-foreground) 56%, transparent);
|
|
9
|
+
--slider-nav-bg-hover: color-mix(in srgb, var(--color-foreground) 78%, transparent);
|
|
10
|
+
--slider-nav-fg: var(--color-background);
|
|
11
|
+
--slider-dot-size: var(--spacing-6);
|
|
12
|
+
--slider-dot-bg: color-mix(in srgb, var(--color-foreground) 28%, transparent);
|
|
13
|
+
--slider-dot-bg-active: var(--color-primary);
|
|
14
|
+
|
|
15
|
+
position: relative;
|
|
16
|
+
display: flex;
|
|
17
|
+
width: 100%;
|
|
18
|
+
min-width: 0;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
gap: var(--spacing-6);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.container_effect {
|
|
24
|
+
overflow: hidden;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* ─── Viewport + track ───────────────────────────────────────────────────────
|
|
28
|
+
Viewport clips overflow and captures pointer events. Track is the moving
|
|
29
|
+
strip; `fade` / `scale` effects stack slides via CSS grid in the same cell.
|
|
30
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
31
|
+
|
|
32
|
+
.viewport {
|
|
33
|
+
position: relative;
|
|
34
|
+
width: 100%;
|
|
35
|
+
min-width: 0;
|
|
36
|
+
overflow: hidden;
|
|
37
|
+
user-select: none;
|
|
38
|
+
-webkit-user-select: none;
|
|
39
|
+
transition: height var(--transition-base);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.track {
|
|
43
|
+
display: flex;
|
|
44
|
+
min-width: 0;
|
|
45
|
+
flex-wrap: nowrap;
|
|
46
|
+
align-items: stretch;
|
|
47
|
+
will-change: transform;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.track_fade,
|
|
51
|
+
.track_scale {
|
|
52
|
+
display: grid;
|
|
53
|
+
transform: none;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.slide {
|
|
57
|
+
min-width: 0;
|
|
58
|
+
flex-grow: 0;
|
|
59
|
+
flex-shrink: 0;
|
|
60
|
+
display: block;
|
|
61
|
+
|
|
62
|
+
> img,
|
|
63
|
+
> video,
|
|
64
|
+
> picture {
|
|
65
|
+
display: block;
|
|
66
|
+
width: 100%;
|
|
67
|
+
height: 100%;
|
|
68
|
+
user-select: none;
|
|
69
|
+
-webkit-user-drag: none;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
> img,
|
|
73
|
+
> video {
|
|
74
|
+
object-fit: cover;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.slide_overlay {
|
|
79
|
+
grid-area: 1 / 1;
|
|
80
|
+
width: 100%;
|
|
81
|
+
opacity: 0;
|
|
82
|
+
pointer-events: none;
|
|
83
|
+
transition:
|
|
84
|
+
opacity var(--transition-base),
|
|
85
|
+
transform var(--transition-base);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.track_fade .slide_overlay {
|
|
89
|
+
transform: none;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.track_scale .slide_overlay {
|
|
93
|
+
transform: scale(0.96);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.slide_active {
|
|
97
|
+
opacity: 1;
|
|
98
|
+
pointer-events: auto;
|
|
99
|
+
transform: scale(1);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/* ─── Built-in nav arrows ───────────────────────────────────────────────────
|
|
103
|
+
`data-slider-no-drag` is set in TSX so `dragIgnoreSelector` does not start
|
|
104
|
+
a track drag when the user clicks the chevron.
|
|
105
|
+
─────────────────────────────────────────────────────────────────────────── */
|
|
106
|
+
|
|
107
|
+
.nav {
|
|
108
|
+
position: absolute;
|
|
109
|
+
top: 50%;
|
|
110
|
+
z-index: 2;
|
|
111
|
+
display: inline-flex;
|
|
112
|
+
width: var(--slider-nav-size);
|
|
113
|
+
height: var(--slider-nav-size);
|
|
114
|
+
padding: 0;
|
|
115
|
+
align-items: center;
|
|
116
|
+
justify-content: center;
|
|
117
|
+
border: 0;
|
|
118
|
+
border-radius: var(--radius-full);
|
|
119
|
+
appearance: none;
|
|
120
|
+
background-color: var(--slider-nav-bg);
|
|
121
|
+
color: var(--slider-nav-fg);
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
font: inherit;
|
|
124
|
+
line-height: 0;
|
|
125
|
+
transform: translateY(-50%);
|
|
126
|
+
transition: var(--transition-fast);
|
|
127
|
+
transition-property: background-color, opacity, transform;
|
|
128
|
+
|
|
129
|
+
&:hover:not(:disabled) {
|
|
130
|
+
background-color: var(--slider-nav-bg-hover);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
&:focus-visible {
|
|
134
|
+
outline: var(--outline-2) solid var(--color-ring);
|
|
135
|
+
outline-offset: 2px;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&:disabled {
|
|
139
|
+
opacity: 0.38;
|
|
140
|
+
cursor: not-allowed;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
> svg {
|
|
144
|
+
display: block;
|
|
145
|
+
flex: 0 0 auto;
|
|
146
|
+
width: 60%;
|
|
147
|
+
height: 60%;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.nav_prev {
|
|
152
|
+
left: var(--spacing-6);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.nav_next {
|
|
156
|
+
right: var(--spacing-6);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/* ─── Pagination (dots / fraction / progress) ───────────────────────────── */
|
|
160
|
+
|
|
161
|
+
.dots {
|
|
162
|
+
display: flex;
|
|
163
|
+
min-height: var(--spacing-10);
|
|
164
|
+
align-items: center;
|
|
165
|
+
justify-content: center;
|
|
166
|
+
gap: var(--spacing-4);
|
|
167
|
+
padding: var(--spacing-2);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.dot {
|
|
171
|
+
width: var(--slider-dot-size);
|
|
172
|
+
height: var(--slider-dot-size);
|
|
173
|
+
padding: 0;
|
|
174
|
+
border: 0;
|
|
175
|
+
border-radius: var(--radius-full);
|
|
176
|
+
appearance: none;
|
|
177
|
+
background-color: var(--slider-dot-bg);
|
|
178
|
+
cursor: pointer;
|
|
179
|
+
font: inherit;
|
|
180
|
+
line-height: 0;
|
|
181
|
+
transition: var(--transition-fast);
|
|
182
|
+
transition-property: background-color, transform, opacity;
|
|
183
|
+
|
|
184
|
+
&:hover:not(:disabled) {
|
|
185
|
+
background-color: color-mix(in srgb, var(--color-foreground) 48%, transparent);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
&:focus-visible {
|
|
189
|
+
outline: var(--outline-2) solid var(--color-ring);
|
|
190
|
+
outline-offset: 2px;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
&:disabled {
|
|
194
|
+
cursor: default;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.dot_active {
|
|
199
|
+
background-color: var(--slider-dot-bg-active);
|
|
200
|
+
transform: scale(1.18);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
.fraction {
|
|
204
|
+
display: inline-flex;
|
|
205
|
+
min-height: var(--spacing-10);
|
|
206
|
+
align-items: center;
|
|
207
|
+
justify-content: center;
|
|
208
|
+
gap: var(--spacing-3);
|
|
209
|
+
padding: var(--spacing-2);
|
|
210
|
+
color: var(--color-muted-foreground);
|
|
211
|
+
font-size: var(--font-size-sm);
|
|
212
|
+
font-variant-numeric: tabular-nums;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.fraction_sep {
|
|
216
|
+
color: var(--color-border);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.progress {
|
|
220
|
+
width: 100%;
|
|
221
|
+
height: var(--spacing-2);
|
|
222
|
+
overflow: hidden;
|
|
223
|
+
border-radius: var(--radius-full);
|
|
224
|
+
background-color: var(--color-muted);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.progress_bar {
|
|
228
|
+
height: 100%;
|
|
229
|
+
border-radius: inherit;
|
|
230
|
+
background-color: var(--color-primary);
|
|
231
|
+
transition: width var(--transition-base);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/* ─── Custom sub-component buttons ──────────────────────────────────────── */
|
|
235
|
+
|
|
236
|
+
.custom_btn {
|
|
237
|
+
display: inline-flex;
|
|
238
|
+
width: var(--spacing-11);
|
|
239
|
+
height: var(--spacing-11);
|
|
240
|
+
padding: 0;
|
|
241
|
+
align-items: center;
|
|
242
|
+
justify-content: center;
|
|
243
|
+
border: 0;
|
|
244
|
+
border-radius: var(--radius-full);
|
|
245
|
+
appearance: none;
|
|
246
|
+
background-color: var(--color-secondary);
|
|
247
|
+
color: var(--color-secondary-foreground);
|
|
248
|
+
cursor: pointer;
|
|
249
|
+
font: inherit;
|
|
250
|
+
line-height: 0;
|
|
251
|
+
transition: var(--transition-fast);
|
|
252
|
+
transition-property: background-color, opacity;
|
|
253
|
+
|
|
254
|
+
&:hover:not(:disabled) {
|
|
255
|
+
background-color: var(--color-secondary-muted);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
&:focus-visible {
|
|
259
|
+
outline: var(--outline-2) solid var(--color-ring);
|
|
260
|
+
outline-offset: 2px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
&:disabled {
|
|
264
|
+
opacity: 0.38;
|
|
265
|
+
cursor: not-allowed;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
> svg {
|
|
269
|
+
display: block;
|
|
270
|
+
flex: 0 0 auto;
|
|
271
|
+
width: 60%;
|
|
272
|
+
height: 60%;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.dots_static {
|
|
277
|
+
padding: 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
@media (--md) {
|
|
281
|
+
.container {
|
|
282
|
+
--slider-nav-size: var(--spacing-11);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.nav_prev {
|
|
286
|
+
left: var(--spacing-4);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.nav_next {
|
|
290
|
+
right: var(--spacing-4);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@media (--motion-reduce) {
|
|
295
|
+
.track,
|
|
296
|
+
.slide_overlay,
|
|
297
|
+
.progress_bar {
|
|
298
|
+
transition: none;
|
|
299
|
+
}
|
|
300
|
+
}
|