@krizaka/ui 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/audio-player.d.ts +113 -0
- package/dist/audio-player.js +207 -0
- package/dist/audio-player.js.map +1 -0
- package/dist/chunk-2USC2YT6.js +17 -0
- package/dist/chunk-2USC2YT6.js.map +1 -0
- package/dist/chunk-EUPTXKH7.js +95 -0
- package/dist/chunk-EUPTXKH7.js.map +1 -0
- package/dist/chunk-RUPRYJ45.js +82 -0
- package/dist/chunk-RUPRYJ45.js.map +1 -0
- package/dist/chunk-XUMJA5ZI.js +283 -0
- package/dist/chunk-XUMJA5ZI.js.map +1 -0
- package/dist/chunk-YH4LMWRU.js +92 -0
- package/dist/chunk-YH4LMWRU.js.map +1 -0
- package/dist/chunk-YX6CNVJA.js +94 -0
- package/dist/chunk-YX6CNVJA.js.map +1 -0
- package/dist/chunk-ZIXB33X7.js +95 -0
- package/dist/chunk-ZIXB33X7.js.map +1 -0
- package/dist/combobox.d.ts +188 -0
- package/dist/combobox.js +16 -0
- package/dist/combobox.js.map +1 -0
- package/dist/data-table.d.ts +246 -0
- package/dist/data-table.js +290 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +288 -0
- package/dist/date-picker.js +364 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/file-upload.d.ts +238 -0
- package/dist/file-upload.js +437 -0
- package/dist/file-upload.js.map +1 -0
- package/dist/filter-bar.d.ts +139 -0
- package/dist/filter-bar.js +155 -0
- package/dist/filter-bar.js.map +1 -0
- package/dist/image-cropper.d.ts +115 -0
- package/dist/image-cropper.js +166 -0
- package/dist/image-cropper.js.map +1 -0
- package/dist/index.js.map +1 -1
- package/dist/media-capture.d.ts +155 -0
- package/dist/media-capture.js +242 -0
- package/dist/media-capture.js.map +1 -0
- package/dist/native/media-capture.d.ts +49 -0
- package/dist/native/media-capture.js +113 -0
- package/dist/native/media-capture.js.map +1 -0
- package/dist/native/video-player.d.ts +50 -0
- package/dist/native/video-player.js +69 -0
- package/dist/native/video-player.js.map +1 -0
- package/dist/native.d.ts +94 -3
- package/dist/native.js +195 -73
- package/dist/native.js.map +1 -1
- package/dist/pagination.d.ts +141 -0
- package/dist/pagination.js +165 -0
- package/dist/pagination.js.map +1 -0
- package/dist/search-field.d.ts +100 -0
- package/dist/search-field.js +167 -0
- package/dist/search-field.js.map +1 -0
- package/dist/tag-input.d.ts +44 -0
- package/dist/tag-input.js +67 -0
- package/dist/tag-input.js.map +1 -0
- package/dist/video-player.d.ts +204 -0
- package/dist/video-player.js +371 -0
- package/dist/video-player.js.map +1 -0
- package/dist/video-trimmer.d.ts +142 -0
- package/dist/video-trimmer.js +193 -0
- package/dist/video-trimmer.js.map +1 -0
- package/package.json +233 -5
- package/registry/alert.json +1 -1
- package/registry/audio-player.json +282 -0
- package/registry/avatar.json +1 -1
- package/registry/badge.json +1 -1
- package/registry/button.json +1 -1
- package/registry/card.json +1 -1
- package/registry/checkbox.json +1 -1
- package/registry/chip-link.json +1 -1
- package/registry/chip.json +1 -1
- package/registry/combobox.json +475 -0
- package/registry/command.json +1 -1
- package/registry/confirm-button.json +1 -1
- package/registry/countdown.json +1 -1
- package/registry/data-table.json +500 -0
- package/registry/date-picker.json +978 -0
- package/registry/dialog.json +1 -1
- package/registry/dropdown-menu.json +1 -1
- package/registry/empty-state.json +1 -1
- package/registry/examples/audio-player/podcast.d.ts +4 -0
- package/registry/examples/audio-player/podcast.js +22 -0
- package/registry/examples/audio-player/podcast.tsx +19 -0
- package/registry/examples/audio-player/voice-note.d.ts +4 -0
- package/registry/examples/audio-player/voice-note.js +12 -0
- package/registry/examples/audio-player/voice-note.tsx +12 -0
- package/registry/examples/combobox/async.d.ts +4 -0
- package/registry/examples/combobox/async.js +23 -0
- package/registry/examples/combobox/async.tsx +22 -0
- package/registry/examples/combobox/creatable.d.ts +4 -0
- package/registry/examples/combobox/creatable.js +32 -0
- package/registry/examples/combobox/creatable.tsx +28 -0
- package/registry/examples/combobox/invalid.d.ts +4 -0
- package/registry/examples/combobox/invalid.js +23 -0
- package/registry/examples/combobox/invalid.tsx +17 -0
- package/registry/examples/combobox/multiple.d.ts +4 -0
- package/registry/examples/combobox/multiple.js +29 -0
- package/registry/examples/combobox/multiple.tsx +26 -0
- package/registry/examples/data-table/cards.d.ts +4 -0
- package/registry/examples/data-table/cards.js +21 -0
- package/registry/examples/data-table/cards.tsx +20 -0
- package/registry/examples/data-table/empty.d.ts +4 -0
- package/registry/examples/data-table/empty.js +26 -0
- package/registry/examples/data-table/empty.tsx +21 -0
- package/registry/examples/data-table/error.d.ts +4 -0
- package/registry/examples/data-table/error.js +28 -0
- package/registry/examples/data-table/error.tsx +29 -0
- package/registry/examples/data-table/jobs.d.ts +4 -0
- package/registry/examples/data-table/jobs.js +37 -0
- package/registry/examples/data-table/jobs.tsx +36 -0
- package/registry/examples/data-table/loading.d.ts +4 -0
- package/registry/examples/data-table/loading.js +16 -0
- package/registry/examples/data-table/loading.tsx +12 -0
- package/registry/examples/data-table/virtualized.d.ts +4 -0
- package/registry/examples/data-table/virtualized.js +21 -0
- package/registry/examples/data-table/virtualized.tsx +20 -0
- package/registry/examples/date-picker/calendar.d.ts +4 -0
- package/registry/examples/date-picker/calendar.js +14 -0
- package/registry/examples/date-picker/calendar.tsx +16 -0
- package/registry/examples/date-picker/french.d.ts +4 -0
- package/registry/examples/date-picker/french.js +20 -0
- package/registry/examples/date-picker/french.tsx +14 -0
- package/registry/examples/date-picker/open.d.ts +4 -0
- package/registry/examples/date-picker/open.js +11 -0
- package/registry/examples/date-picker/open.tsx +8 -0
- package/registry/examples/date-picker/range.d.ts +4 -0
- package/registry/examples/date-picker/range.js +29 -0
- package/registry/examples/date-picker/range.tsx +25 -0
- package/registry/examples/date-picker/schedule.d.ts +4 -0
- package/registry/examples/date-picker/schedule.js +26 -0
- package/registry/examples/date-picker/schedule.tsx +22 -0
- package/registry/examples/file-upload/images.d.ts +4 -0
- package/registry/examples/file-upload/images.js +32 -0
- package/registry/examples/file-upload/images.tsx +25 -0
- package/registry/examples/file-upload/states.d.ts +4 -0
- package/registry/examples/file-upload/states.js +28 -0
- package/registry/examples/file-upload/states.tsx +23 -0
- package/registry/examples/file-upload/tus.d.ts +4 -0
- package/registry/examples/file-upload/tus.js +23 -0
- package/registry/examples/file-upload/tus.tsx +26 -0
- package/registry/examples/file-upload/video.d.ts +4 -0
- package/registry/examples/file-upload/video.js +39 -0
- package/registry/examples/file-upload/video.tsx +36 -0
- package/registry/examples/filter-bar/address.d.ts +4 -0
- package/registry/examples/filter-bar/address.js +29 -0
- package/registry/examples/filter-bar/address.tsx +27 -0
- package/registry/examples/filter-bar/jobs.d.ts +4 -0
- package/registry/examples/filter-bar/jobs.js +37 -0
- package/registry/examples/filter-bar/jobs.tsx +37 -0
- package/registry/examples/filter-bar/menu.d.ts +4 -0
- package/registry/examples/filter-bar/menu.js +27 -0
- package/registry/examples/filter-bar/menu.tsx +23 -0
- package/registry/examples/image-cropper/avatar.d.ts +4 -0
- package/registry/examples/image-cropper/avatar.js +13 -0
- package/registry/examples/image-cropper/avatar.tsx +14 -0
- package/registry/examples/image-cropper/banner.d.ts +4 -0
- package/registry/examples/image-cropper/banner.js +11 -0
- package/registry/examples/image-cropper/banner.tsx +10 -0
- package/registry/examples/image-cropper/vertical-video.d.ts +4 -0
- package/registry/examples/image-cropper/vertical-video.js +12 -0
- package/registry/examples/image-cropper/vertical-video.tsx +16 -0
- package/registry/examples/media-capture/clip.d.ts +4 -0
- package/registry/examples/media-capture/clip.js +20 -0
- package/registry/examples/media-capture/clip.tsx +18 -0
- package/registry/examples/media-capture/native/photo.d.ts +4 -0
- package/registry/examples/media-capture/native/photo.dark.png +0 -0
- package/registry/examples/media-capture/native/photo.js +27 -0
- package/registry/examples/media-capture/native/photo.light.png +0 -0
- package/registry/examples/media-capture/native/photo.tsx +20 -0
- package/registry/examples/media-capture/profile-photo.d.ts +4 -0
- package/registry/examples/media-capture/profile-photo.js +24 -0
- package/registry/examples/media-capture/profile-photo.tsx +20 -0
- package/registry/examples/pagination/cursor.d.ts +4 -0
- package/registry/examples/pagination/cursor.js +24 -0
- package/registry/examples/pagination/cursor.tsx +20 -0
- package/registry/examples/pagination/links.d.ts +4 -0
- package/registry/examples/pagination/links.js +11 -0
- package/registry/examples/pagination/links.tsx +6 -0
- package/registry/examples/pagination/native/cursor.d.ts +4 -0
- package/registry/examples/pagination/native/cursor.dark.png +0 -0
- package/registry/examples/pagination/native/cursor.js +19 -0
- package/registry/examples/pagination/native/cursor.light.png +0 -0
- package/registry/examples/pagination/native/cursor.tsx +13 -0
- package/registry/examples/pagination/native/pages.d.ts +4 -0
- package/registry/examples/pagination/native/pages.dark.png +0 -0
- package/registry/examples/pagination/native/pages.js +21 -0
- package/registry/examples/pagination/native/pages.light.png +0 -0
- package/registry/examples/pagination/native/pages.tsx +14 -0
- package/registry/examples/pagination/results.d.ts +4 -0
- package/registry/examples/pagination/results.js +23 -0
- package/registry/examples/pagination/results.tsx +19 -0
- package/registry/examples/pagination/table-footer.d.ts +4 -0
- package/registry/examples/pagination/table-footer.js +31 -0
- package/registry/examples/pagination/table-footer.tsx +27 -0
- package/registry/examples/search-field/global.d.ts +4 -0
- package/registry/examples/search-field/global.js +19 -0
- package/registry/examples/search-field/global.tsx +15 -0
- package/registry/examples/search-field/native/default.d.ts +4 -0
- package/registry/examples/search-field/native/default.dark.png +0 -0
- package/registry/examples/search-field/native/default.js +13 -0
- package/registry/examples/search-field/native/default.light.png +0 -0
- package/registry/examples/search-field/native/default.tsx +7 -0
- package/registry/examples/search-field/suggestions.d.ts +4 -0
- package/registry/examples/search-field/suggestions.js +30 -0
- package/registry/examples/search-field/suggestions.tsx +27 -0
- package/registry/examples/search-field/toolbar.d.ts +4 -0
- package/registry/examples/search-field/toolbar.js +17 -0
- package/registry/examples/search-field/toolbar.tsx +21 -0
- package/registry/examples/tag-input/recipients.d.ts +4 -0
- package/registry/examples/tag-input/recipients.js +23 -0
- package/registry/examples/tag-input/recipients.tsx +20 -0
- package/registry/examples/tag-input/video-tags.d.ts +4 -0
- package/registry/examples/tag-input/video-tags.js +26 -0
- package/registry/examples/tag-input/video-tags.tsx +22 -0
- package/registry/examples/video-player/default.d.ts +4 -0
- package/registry/examples/video-player/default.js +12 -0
- package/registry/examples/video-player/default.tsx +8 -0
- package/registry/examples/video-player/gated.d.ts +4 -0
- package/registry/examples/video-player/gated.js +26 -0
- package/registry/examples/video-player/gated.tsx +23 -0
- package/registry/examples/video-player/native/default.d.ts +4 -0
- package/registry/examples/video-player/native/default.dark.png +0 -0
- package/registry/examples/video-player/native/default.js +18 -0
- package/registry/examples/video-player/native/default.light.png +0 -0
- package/registry/examples/video-player/native/default.tsx +12 -0
- package/registry/examples/video-player/signed-source.d.ts +4 -0
- package/registry/examples/video-player/signed-source.js +16 -0
- package/registry/examples/video-player/signed-source.tsx +15 -0
- package/registry/examples/video-player/vertical.d.ts +4 -0
- package/registry/examples/video-player/vertical.js +12 -0
- package/registry/examples/video-player/vertical.tsx +12 -0
- package/registry/examples/video-trimmer/custom.d.ts +4 -0
- package/registry/examples/video-trimmer/custom.js +24 -0
- package/registry/examples/video-trimmer/custom.tsx +26 -0
- package/registry/examples/video-trimmer/filmstrip.d.ts +4 -0
- package/registry/examples/video-trimmer/filmstrip.js +15 -0
- package/registry/examples/video-trimmer/filmstrip.tsx +13 -0
- package/registry/examples/video-trimmer/playhead.d.ts +4 -0
- package/registry/examples/video-trimmer/playhead.js +15 -0
- package/registry/examples/video-trimmer/playhead.tsx +13 -0
- package/registry/field.json +1 -1
- package/registry/file-upload.json +471 -0
- package/registry/filter-bar.json +347 -0
- package/registry/glow-card.json +1 -1
- package/registry/image-cropper.json +313 -0
- package/registry/index.json +255 -1
- package/registry/iso.json +1 -1
- package/registry/kbd.json +1 -1
- package/registry/loader.json +1 -1
- package/registry/marquee.json +1 -1
- package/registry/mascots.json +1 -1
- package/registry/media-capture.json +347 -0
- package/registry/meter.json +3 -3
- package/registry/nav-bar.json +1 -1
- package/registry/number-ticker.json +1 -1
- package/registry/page-header.json +1 -1
- package/registry/pagination.json +475 -0
- package/registry/popover.json +1 -1
- package/registry/progress.json +5 -5
- package/registry/radio-group.json +1 -1
- package/registry/search-field.json +436 -0
- package/registry/section-backdrop.json +1 -1
- package/registry/separator.json +1 -1
- package/registry/skeleton.json +1 -1
- package/registry/slider.json +1 -1
- package/registry/slot.json +1 -1
- package/registry/spinner.json +1 -1
- package/registry/stat.json +1 -1
- package/registry/stepper.json +1 -1
- package/registry/switch.json +1 -1
- package/registry/tabs.json +1 -1
- package/registry/tag-input.json +363 -0
- package/registry/theme.json +1 -1
- package/registry/toast.json +1 -1
- package/registry/tooltip.json +1 -1
- package/registry/video-player.json +598 -0
- package/registry/video-trimmer.json +385 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import {
|
|
3
|
+
clamp,
|
|
4
|
+
formatClock
|
|
5
|
+
} from "./chunk-EUPTXKH7.js";
|
|
6
|
+
|
|
7
|
+
// src/video-trimmer/video-trimmer.tsx
|
|
8
|
+
import * as React from "react";
|
|
9
|
+
import { tv } from "tailwind-variants";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var videoTrimmer = tv({
|
|
12
|
+
slots: {
|
|
13
|
+
root: "w-full select-none",
|
|
14
|
+
header: "mb-2 flex items-center justify-between font-mono text-[11px] tabular-nums text-fg-secondary",
|
|
15
|
+
kept: "rounded-full bg-accent-soft px-2.5 py-0.5 font-sans text-xs font-semibold text-fg",
|
|
16
|
+
track: "relative h-16 touch-none rounded-xl bg-surface-2 data-[disabled]:opacity-50",
|
|
17
|
+
strip: "pointer-events-none absolute inset-0 flex overflow-hidden rounded-xl",
|
|
18
|
+
frame: "h-full min-w-0 flex-1 object-cover",
|
|
19
|
+
shade: "pointer-events-none absolute inset-y-0 bg-scrim-strong",
|
|
20
|
+
range: "pointer-events-none absolute inset-y-0 border-y-[3px] border-accent",
|
|
21
|
+
handle: "absolute inset-y-0 z-10 flex w-6 cursor-ew-resize items-center justify-center bg-accent text-on-accent shadow-md focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 data-[edge=start]:rounded-l-xl data-[edge=end]:-translate-x-full data-[edge=end]:rounded-r-xl",
|
|
22
|
+
grip: "flex gap-[3px] [&>span]:h-5 [&>span]:w-[2px] [&>span]:rounded-sm [&>span]:bg-on-accent/70",
|
|
23
|
+
playhead: "absolute -inset-y-1.5 z-20 w-[3px] -translate-x-1/2 cursor-ew-resize rounded-full bg-fg shadow-md focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring"
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
var videoTrimmerLabels = {
|
|
27
|
+
start: "Start",
|
|
28
|
+
end: "End",
|
|
29
|
+
playhead: "Playhead",
|
|
30
|
+
kept: (length) => `${length} kept`
|
|
31
|
+
};
|
|
32
|
+
var tenths = (seconds) => `${formatClock(seconds)}.${Math.floor(Math.max(0, seconds) % 1 * 10)}`;
|
|
33
|
+
function VideoTrimmer({
|
|
34
|
+
duration,
|
|
35
|
+
value: valueProp,
|
|
36
|
+
defaultValue,
|
|
37
|
+
onValueChange,
|
|
38
|
+
onValueCommit,
|
|
39
|
+
time,
|
|
40
|
+
onSeek,
|
|
41
|
+
minLength = 0.5,
|
|
42
|
+
step = 0.1,
|
|
43
|
+
largeStep = 1,
|
|
44
|
+
frames,
|
|
45
|
+
children,
|
|
46
|
+
formatTime = tenths,
|
|
47
|
+
showHeader = true,
|
|
48
|
+
disabled,
|
|
49
|
+
classNames = {},
|
|
50
|
+
renderHandle,
|
|
51
|
+
labels: given
|
|
52
|
+
}) {
|
|
53
|
+
const labels = { ...videoTrimmerLabels, ...given };
|
|
54
|
+
const s = videoTrimmer();
|
|
55
|
+
const track = React.useRef(null);
|
|
56
|
+
const grip = React.useRef(null);
|
|
57
|
+
const [inner, setInner] = React.useState(() => [defaultValue?.[0] ?? 0, defaultValue?.[1] ?? duration]);
|
|
58
|
+
const [start, end] = valueProp ?? inner;
|
|
59
|
+
const total = duration > 0 ? duration : 1;
|
|
60
|
+
const pct = (seconds) => clamp(seconds, 0, total) / total * 100;
|
|
61
|
+
const set = (next, commit = false) => {
|
|
62
|
+
if (!valueProp) setInner(next);
|
|
63
|
+
onValueChange?.(next);
|
|
64
|
+
if (commit) onValueCommit?.(next);
|
|
65
|
+
};
|
|
66
|
+
const move = (edge, to, commit = false) => {
|
|
67
|
+
const next = edge === "start" ? [clamp(to, 0, end - minLength), end] : [start, clamp(to, start + minLength, duration)];
|
|
68
|
+
set([Math.round(next[0] * 1e3) / 1e3, Math.round(next[1] * 1e3) / 1e3], commit);
|
|
69
|
+
};
|
|
70
|
+
const seek = (to) => onSeek?.(clamp(to, start, Math.max(start, end - 0.05)));
|
|
71
|
+
const at = (clientX) => {
|
|
72
|
+
const box = track.current?.getBoundingClientRect();
|
|
73
|
+
if (!box || box.width === 0) return 0;
|
|
74
|
+
return clamp((clientX - box.left) / box.width * duration, 0, duration);
|
|
75
|
+
};
|
|
76
|
+
const keys = (which) => (event) => {
|
|
77
|
+
const current = which === "start" ? start : which === "end" ? end : time ?? start;
|
|
78
|
+
const big = largeStep;
|
|
79
|
+
const small = event.shiftKey ? largeStep : step;
|
|
80
|
+
const target = {
|
|
81
|
+
ArrowLeft: current - small,
|
|
82
|
+
ArrowDown: current - small,
|
|
83
|
+
ArrowRight: current + small,
|
|
84
|
+
ArrowUp: current + small,
|
|
85
|
+
PageDown: current - big,
|
|
86
|
+
PageUp: current + big,
|
|
87
|
+
Home: 0,
|
|
88
|
+
End: duration
|
|
89
|
+
};
|
|
90
|
+
const to = target[event.key];
|
|
91
|
+
if (to === void 0 || disabled) return;
|
|
92
|
+
event.preventDefault();
|
|
93
|
+
if (which === "playhead") seek(to);
|
|
94
|
+
else move(which, to, true);
|
|
95
|
+
};
|
|
96
|
+
const handle = (edge) => {
|
|
97
|
+
const own = edge === "start" ? start : end;
|
|
98
|
+
return /* @__PURE__ */ jsx(
|
|
99
|
+
"div",
|
|
100
|
+
{
|
|
101
|
+
role: "slider",
|
|
102
|
+
tabIndex: disabled ? -1 : 0,
|
|
103
|
+
"aria-label": edge === "start" ? labels.start : labels.end,
|
|
104
|
+
"aria-valuemin": edge === "start" ? 0 : Math.round((start + minLength) * 10) / 10,
|
|
105
|
+
"aria-valuemax": edge === "start" ? Math.round((end - minLength) * 10) / 10 : Math.round(duration * 10) / 10,
|
|
106
|
+
"aria-valuenow": Math.round(own * 10) / 10,
|
|
107
|
+
"aria-valuetext": formatTime(own),
|
|
108
|
+
"aria-disabled": disabled || void 0,
|
|
109
|
+
"data-edge": edge,
|
|
110
|
+
className: s.handle({ className: classNames.handle }),
|
|
111
|
+
style: { left: `${pct(own)}%` },
|
|
112
|
+
onPointerDown: (event) => {
|
|
113
|
+
if (disabled) return;
|
|
114
|
+
event.stopPropagation();
|
|
115
|
+
track.current?.setPointerCapture?.(event.pointerId);
|
|
116
|
+
grip.current = edge;
|
|
117
|
+
},
|
|
118
|
+
onKeyDown: keys(edge),
|
|
119
|
+
children: renderHandle ? renderHandle(edge) : /* @__PURE__ */ jsxs("span", { className: s.grip({ className: classNames.grip }), children: [
|
|
120
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
121
|
+
/* @__PURE__ */ jsx("span", {})
|
|
122
|
+
] })
|
|
123
|
+
},
|
|
124
|
+
edge
|
|
125
|
+
);
|
|
126
|
+
};
|
|
127
|
+
return /* @__PURE__ */ jsxs("div", { className: s.root({ className: classNames.root }), children: [
|
|
128
|
+
showHeader && /* @__PURE__ */ jsxs("div", { className: s.header({ className: classNames.header }), children: [
|
|
129
|
+
/* @__PURE__ */ jsx("span", { children: formatTime(start) }),
|
|
130
|
+
/* @__PURE__ */ jsx("span", { className: s.kept({ className: classNames.kept }), children: labels.kept(formatTime(end - start)) }),
|
|
131
|
+
/* @__PURE__ */ jsx("span", { children: formatTime(end) })
|
|
132
|
+
] }),
|
|
133
|
+
/* @__PURE__ */ jsxs(
|
|
134
|
+
"div",
|
|
135
|
+
{
|
|
136
|
+
ref: track,
|
|
137
|
+
className: s.track({ className: classNames.track }),
|
|
138
|
+
"data-disabled": disabled ? "" : void 0,
|
|
139
|
+
onPointerDown: (event) => {
|
|
140
|
+
if (disabled) return;
|
|
141
|
+
track.current?.setPointerCapture?.(event.pointerId);
|
|
142
|
+
const t = at(event.clientX);
|
|
143
|
+
grip.current = onSeek ? "playhead" : Math.abs(t - start) < Math.abs(t - end) ? "start" : "end";
|
|
144
|
+
if (grip.current === "playhead") seek(t);
|
|
145
|
+
else move(grip.current, t);
|
|
146
|
+
},
|
|
147
|
+
onPointerMove: (event) => {
|
|
148
|
+
if (!grip.current) return;
|
|
149
|
+
const t = at(event.clientX);
|
|
150
|
+
if (grip.current === "playhead") seek(t);
|
|
151
|
+
else move(grip.current, t);
|
|
152
|
+
},
|
|
153
|
+
onPointerUp: () => {
|
|
154
|
+
if (grip.current && grip.current !== "playhead") onValueCommit?.([start, end]);
|
|
155
|
+
grip.current = null;
|
|
156
|
+
},
|
|
157
|
+
onPointerCancel: () => {
|
|
158
|
+
grip.current = null;
|
|
159
|
+
},
|
|
160
|
+
children: [
|
|
161
|
+
/* @__PURE__ */ jsx("div", { className: s.strip({ className: classNames.strip }), children: children ?? frames?.map((src, i) => /* @__PURE__ */ jsx("img", { src, alt: "", draggable: false, className: s.frame({ className: classNames.frame }) }, `${i}-${src}`)) }),
|
|
162
|
+
/* @__PURE__ */ jsx("div", { className: s.shade({ className: classNames.shade }), style: { left: 0, width: `${pct(start)}%`, borderRadius: "0.75rem 0 0 0.75rem" } }),
|
|
163
|
+
/* @__PURE__ */ jsx("div", { className: s.shade({ className: classNames.shade }), style: { right: 0, width: `${100 - pct(end)}%`, borderRadius: "0 0.75rem 0.75rem 0" } }),
|
|
164
|
+
/* @__PURE__ */ jsx("div", { className: s.range({ className: classNames.range }), style: { left: `${pct(start)}%`, right: `${100 - pct(end)}%` } }),
|
|
165
|
+
time !== void 0 && /* @__PURE__ */ jsx(
|
|
166
|
+
"div",
|
|
167
|
+
{
|
|
168
|
+
role: "slider",
|
|
169
|
+
tabIndex: disabled || !onSeek ? -1 : 0,
|
|
170
|
+
"aria-label": labels.playhead,
|
|
171
|
+
"aria-valuemin": Math.round(start * 10) / 10,
|
|
172
|
+
"aria-valuemax": Math.round(end * 10) / 10,
|
|
173
|
+
"aria-valuenow": Math.round(time * 10) / 10,
|
|
174
|
+
"aria-valuetext": formatTime(time),
|
|
175
|
+
"aria-readonly": !onSeek || void 0,
|
|
176
|
+
className: s.playhead({ className: classNames.playhead }),
|
|
177
|
+
style: { left: `${pct(time)}%` },
|
|
178
|
+
onKeyDown: onSeek ? keys("playhead") : void 0
|
|
179
|
+
}
|
|
180
|
+
),
|
|
181
|
+
handle("start"),
|
|
182
|
+
handle("end")
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
] });
|
|
187
|
+
}
|
|
188
|
+
export {
|
|
189
|
+
VideoTrimmer,
|
|
190
|
+
videoTrimmer,
|
|
191
|
+
videoTrimmerLabels
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=video-trimmer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/video-trimmer/video-trimmer.tsx"],"sourcesContent":["// Client. The trim timeline of a video editor: the clip as a filmstrip (or any track content), the part kept framed\n// between two edge handles — each a `slider` named by a prop, its value read as a time, never past the other one —\n// the outside dimmed, and a playhead to scrub. The handles sit on their value by their outer edge (the start handle\n// to the right of its value, the end handle to its left), so the frame encloses exactly what is kept. Every part\n// takes its own classes (`classNames`) and the handles their own content (`renderHandle`).\nimport * as React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nimport { clamp, formatClock } from \"../media\";\n\nexport const videoTrimmer = tv({\n slots: {\n root: \"w-full select-none\",\n header: \"mb-2 flex items-center justify-between font-mono text-[11px] tabular-nums text-fg-secondary\",\n kept: \"rounded-full bg-accent-soft px-2.5 py-0.5 font-sans text-xs font-semibold text-fg\",\n track: \"relative h-16 touch-none rounded-xl bg-surface-2 data-[disabled]:opacity-50\",\n strip: \"pointer-events-none absolute inset-0 flex overflow-hidden rounded-xl\",\n frame: \"h-full min-w-0 flex-1 object-cover\",\n shade: \"pointer-events-none absolute inset-y-0 bg-scrim-strong\",\n range: \"pointer-events-none absolute inset-y-0 border-y-[3px] border-accent\",\n handle:\n \"absolute inset-y-0 z-10 flex w-6 cursor-ew-resize items-center justify-center bg-accent text-on-accent shadow-md \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-surface-0 \" +\n \"data-[edge=start]:rounded-l-xl data-[edge=end]:-translate-x-full data-[edge=end]:rounded-r-xl\",\n grip: \"flex gap-[3px] [&>span]:h-5 [&>span]:w-[2px] [&>span]:rounded-sm [&>span]:bg-on-accent/70\",\n playhead:\n \"absolute -inset-y-1.5 z-20 w-[3px] -translate-x-1/2 cursor-ew-resize rounded-full bg-fg shadow-md \" +\n \"focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring\",\n },\n});\n\ntype Part = keyof ReturnType<typeof videoTrimmer>;\n\nexport type VideoTrimmerLabels = {\n /** The start handle (\"Start\"). */\n start: string;\n /** The end handle (\"End\"). */\n end: string;\n /** The playhead (\"Playhead\"). */\n playhead: string;\n /** The length kept, above the track: `(length) => length + \" kept\"` (the length already formatted). */\n kept: (length: string) => string;\n};\n\nexport const videoTrimmerLabels: VideoTrimmerLabels = {\n start: \"Start\",\n end: \"End\",\n playhead: \"Playhead\",\n kept: (length) => `${length} kept`,\n};\n\nexport type VideoTrimmerProps = {\n /** The length of the clip, in seconds. */\n duration: number;\n /** The part kept, `[start, end]` in seconds (controlled). */\n value?: readonly [number, number];\n /** The part kept at first, uncontrolled. Default: the whole clip. */\n defaultValue?: readonly [number, number];\n /** Called on every move of a handle. */\n onValueChange?: (value: [number, number]) => void;\n /** Called once a drag or a key press ends: render a preview, save. */\n onValueCommit?: (value: [number, number]) => void;\n /** The time played, in seconds: shows the playhead. */\n time?: number;\n /** Called when the playhead is moved (a drag on the track, the arrows on the playhead). */\n onSeek?: (time: number) => void;\n /** The shortest part that can be kept, in seconds. Default 0.5. */\n minLength?: number;\n /** One arrow press, in seconds. Default 0.1. */\n step?: number;\n /** Shift + arrow, Page Up / Page Down, in seconds. Default 1. */\n largeStep?: number;\n /** Pictures of the clip, in order: the filmstrip. */\n frames?: readonly string[];\n /** Track content instead of the filmstrip (a waveform, a coloured band). */\n children?: React.ReactNode;\n /** A time as read and shown. Default `m:ss` with tenths. */\n formatTime?: (seconds: number) => string;\n /** Shows the times and the length kept above the track. Default `true`. */\n showHeader?: boolean;\n /** Not available (a render is running). */\n disabled?: boolean;\n /** Classes per part: `root`, `header`, `kept`, `track`, `strip`, `frame`, `shade`, `range`, `handle`, `grip`, `playhead`. */\n classNames?: Partial<Record<Part, string>>;\n /** The content of a handle (default: two grip lines). */\n renderHandle?: (edge: \"start\" | \"end\") => React.ReactNode;\n /** The words, passed translated; English by default. */\n labels?: Partial<VideoTrimmerLabels>;\n};\n\nconst tenths = (seconds: number) => `${formatClock(seconds)}.${Math.floor((Math.max(0, seconds) % 1) * 10)}`;\n\ntype Grip = \"start\" | \"end\" | \"playhead\";\n\n/** Keeps a part of a clip between two handles over its filmstrip, with a playhead to scrub — the keyboard included. */\nexport function VideoTrimmer({\n duration,\n value: valueProp,\n defaultValue,\n onValueChange,\n onValueCommit,\n time,\n onSeek,\n minLength = 0.5,\n step = 0.1,\n largeStep = 1,\n frames,\n children,\n formatTime = tenths,\n showHeader = true,\n disabled,\n classNames = {},\n renderHandle,\n labels: given,\n}: VideoTrimmerProps) {\n const labels = { ...videoTrimmerLabels, ...given };\n const s = videoTrimmer();\n const track = React.useRef<HTMLDivElement>(null);\n const grip = React.useRef<Grip | null>(null);\n const [inner, setInner] = React.useState<[number, number]>(() => [defaultValue?.[0] ?? 0, defaultValue?.[1] ?? duration]);\n const [start, end] = valueProp ?? inner;\n const total = duration > 0 ? duration : 1;\n const pct = (seconds: number) => (clamp(seconds, 0, total) / total) * 100;\n\n const set = (next: [number, number], commit = false) => {\n if (!valueProp) setInner(next);\n onValueChange?.(next);\n if (commit) onValueCommit?.(next);\n };\n const move = (edge: \"start\" | \"end\", to: number, commit = false) => {\n const next: [number, number] =\n edge === \"start\" ? [clamp(to, 0, end - minLength), end] : [start, clamp(to, start + minLength, duration)];\n set([Math.round(next[0] * 1000) / 1000, Math.round(next[1] * 1000) / 1000], commit);\n };\n const seek = (to: number) => onSeek?.(clamp(to, start, Math.max(start, end - 0.05)));\n\n const at = (clientX: number) => {\n const box = track.current?.getBoundingClientRect();\n if (!box || box.width === 0) return 0;\n return clamp(((clientX - box.left) / box.width) * duration, 0, duration);\n };\n\n const keys = (which: Grip) => (event: React.KeyboardEvent) => {\n const current = which === \"start\" ? start : which === \"end\" ? end : (time ?? start);\n const big = largeStep;\n const small = event.shiftKey ? largeStep : step;\n const target: Record<string, number> = {\n ArrowLeft: current - small,\n ArrowDown: current - small,\n ArrowRight: current + small,\n ArrowUp: current + small,\n PageDown: current - big,\n PageUp: current + big,\n Home: 0,\n End: duration,\n };\n const to = target[event.key];\n if (to === undefined || disabled) return;\n event.preventDefault();\n if (which === \"playhead\") seek(to);\n else move(which, to, true);\n };\n\n const handle = (edge: \"start\" | \"end\") => {\n const own = edge === \"start\" ? start : end;\n return (\n <div\n key={edge}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-label={edge === \"start\" ? labels.start : labels.end}\n aria-valuemin={edge === \"start\" ? 0 : Math.round((start + minLength) * 10) / 10}\n aria-valuemax={edge === \"start\" ? Math.round((end - minLength) * 10) / 10 : Math.round(duration * 10) / 10}\n aria-valuenow={Math.round(own * 10) / 10}\n aria-valuetext={formatTime(own)}\n aria-disabled={disabled || undefined}\n data-edge={edge}\n className={s.handle({ className: classNames.handle })}\n style={{ left: `${pct(own)}%` }}\n onPointerDown={(event) => {\n if (disabled) return;\n event.stopPropagation();\n track.current?.setPointerCapture?.(event.pointerId);\n grip.current = edge;\n }}\n onKeyDown={keys(edge)}\n >\n {renderHandle ? (\n renderHandle(edge)\n ) : (\n <span className={s.grip({ className: classNames.grip })}>\n <span />\n <span />\n </span>\n )}\n </div>\n );\n };\n\n return (\n <div className={s.root({ className: classNames.root })}>\n {showHeader && (\n <div className={s.header({ className: classNames.header })}>\n <span>{formatTime(start)}</span>\n <span className={s.kept({ className: classNames.kept })}>{labels.kept(formatTime(end - start))}</span>\n <span>{formatTime(end)}</span>\n </div>\n )}\n <div\n ref={track}\n className={s.track({ className: classNames.track })}\n data-disabled={disabled ? \"\" : undefined}\n onPointerDown={(event) => {\n if (disabled) return;\n track.current?.setPointerCapture?.(event.pointerId);\n const t = at(event.clientX);\n grip.current = onSeek ? \"playhead\" : Math.abs(t - start) < Math.abs(t - end) ? \"start\" : \"end\";\n if (grip.current === \"playhead\") seek(t);\n else move(grip.current, t);\n }}\n onPointerMove={(event) => {\n if (!grip.current) return;\n const t = at(event.clientX);\n if (grip.current === \"playhead\") seek(t);\n else move(grip.current, t);\n }}\n onPointerUp={() => {\n if (grip.current && grip.current !== \"playhead\") onValueCommit?.([start, end]);\n grip.current = null;\n }}\n onPointerCancel={() => {\n grip.current = null;\n }}\n >\n <div className={s.strip({ className: classNames.strip })}>\n {children ?? frames?.map((src, i) => <img key={`${i}-${src}`} src={src} alt=\"\" draggable={false} className={s.frame({ className: classNames.frame })} />)}\n </div>\n <div className={s.shade({ className: classNames.shade })} style={{ left: 0, width: `${pct(start)}%`, borderRadius: \"0.75rem 0 0 0.75rem\" }} />\n <div className={s.shade({ className: classNames.shade })} style={{ right: 0, width: `${100 - pct(end)}%`, borderRadius: \"0 0.75rem 0.75rem 0\" }} />\n <div className={s.range({ className: classNames.range })} style={{ left: `${pct(start)}%`, right: `${100 - pct(end)}%` }} />\n {time !== undefined && (\n <div\n role=\"slider\"\n tabIndex={disabled || !onSeek ? -1 : 0}\n aria-label={labels.playhead}\n aria-valuemin={Math.round(start * 10) / 10}\n aria-valuemax={Math.round(end * 10) / 10}\n aria-valuenow={Math.round(time * 10) / 10}\n aria-valuetext={formatTime(time)}\n aria-readonly={!onSeek || undefined}\n className={s.playhead({ className: classNames.playhead })}\n style={{ left: `${pct(time)}%` }}\n onKeyDown={onSeek ? keys(\"playhead\") : undefined}\n />\n )}\n {handle(\"start\")}\n {handle(\"end\")}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krizaka/ui",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "The Krizaka front-end platform's components: the primitives (button, card, dialog, toast, menu, field, tabs, chip, switch, slider, command palette, theme, countdown…) on the semantic --kz-* tokens, the animated marks (Krizaka, Orazaka, Orochia) and the motion signature — web and /native.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"krizaka",
|
|
@@ -210,12 +210,72 @@
|
|
|
210
210
|
"types": "./dist/meter.d.ts",
|
|
211
211
|
"import": "./dist/meter.js"
|
|
212
212
|
},
|
|
213
|
+
"./pagination": {
|
|
214
|
+
"types": "./dist/pagination.d.ts",
|
|
215
|
+
"import": "./dist/pagination.js"
|
|
216
|
+
},
|
|
217
|
+
"./data-table": {
|
|
218
|
+
"types": "./dist/data-table.d.ts",
|
|
219
|
+
"import": "./dist/data-table.js"
|
|
220
|
+
},
|
|
221
|
+
"./filter-bar": {
|
|
222
|
+
"types": "./dist/filter-bar.d.ts",
|
|
223
|
+
"import": "./dist/filter-bar.js"
|
|
224
|
+
},
|
|
225
|
+
"./combobox": {
|
|
226
|
+
"types": "./dist/combobox.d.ts",
|
|
227
|
+
"import": "./dist/combobox.js"
|
|
228
|
+
},
|
|
229
|
+
"./tag-input": {
|
|
230
|
+
"types": "./dist/tag-input.d.ts",
|
|
231
|
+
"import": "./dist/tag-input.js"
|
|
232
|
+
},
|
|
233
|
+
"./date-picker": {
|
|
234
|
+
"types": "./dist/date-picker.d.ts",
|
|
235
|
+
"import": "./dist/date-picker.js"
|
|
236
|
+
},
|
|
237
|
+
"./search-field": {
|
|
238
|
+
"types": "./dist/search-field.d.ts",
|
|
239
|
+
"import": "./dist/search-field.js"
|
|
240
|
+
},
|
|
241
|
+
"./video-player": {
|
|
242
|
+
"types": "./dist/video-player.d.ts",
|
|
243
|
+
"import": "./dist/video-player.js"
|
|
244
|
+
},
|
|
245
|
+
"./file-upload": {
|
|
246
|
+
"types": "./dist/file-upload.d.ts",
|
|
247
|
+
"import": "./dist/file-upload.js"
|
|
248
|
+
},
|
|
249
|
+
"./media-capture": {
|
|
250
|
+
"types": "./dist/media-capture.d.ts",
|
|
251
|
+
"import": "./dist/media-capture.js"
|
|
252
|
+
},
|
|
253
|
+
"./video-trimmer": {
|
|
254
|
+
"types": "./dist/video-trimmer.d.ts",
|
|
255
|
+
"import": "./dist/video-trimmer.js"
|
|
256
|
+
},
|
|
257
|
+
"./audio-player": {
|
|
258
|
+
"types": "./dist/audio-player.d.ts",
|
|
259
|
+
"import": "./dist/audio-player.js"
|
|
260
|
+
},
|
|
261
|
+
"./image-cropper": {
|
|
262
|
+
"types": "./dist/image-cropper.d.ts",
|
|
263
|
+
"import": "./dist/image-cropper.js"
|
|
264
|
+
},
|
|
213
265
|
"./motion.css": "./dist/motion.css",
|
|
214
266
|
"./tailwind.css": "./tailwind.css",
|
|
215
267
|
"./native": {
|
|
216
268
|
"types": "./dist/native.d.ts",
|
|
217
269
|
"import": "./dist/native.js"
|
|
218
270
|
},
|
|
271
|
+
"./native/video-player": {
|
|
272
|
+
"types": "./dist/native/video-player.d.ts",
|
|
273
|
+
"import": "./dist/native/video-player.js"
|
|
274
|
+
},
|
|
275
|
+
"./native/media-capture": {
|
|
276
|
+
"types": "./dist/native/media-capture.d.ts",
|
|
277
|
+
"import": "./dist/native/media-capture.js"
|
|
278
|
+
},
|
|
219
279
|
"./registry/examples/*": {
|
|
220
280
|
"types": "./registry/examples/*.d.ts",
|
|
221
281
|
"import": "./registry/examples/*.js"
|
|
@@ -238,7 +298,10 @@
|
|
|
238
298
|
"*.css"
|
|
239
299
|
],
|
|
240
300
|
"peerDependencies": {
|
|
241
|
-
"@krizaka/tailwind": ">=2.
|
|
301
|
+
"@krizaka/tailwind": ">=2.5.0",
|
|
302
|
+
"expo-camera": ">=16",
|
|
303
|
+
"expo-video": ">=2",
|
|
304
|
+
"hls.js": ">=1.5",
|
|
242
305
|
"react": ">=18",
|
|
243
306
|
"react-dom": ">=18",
|
|
244
307
|
"react-native": ">=0.76",
|
|
@@ -264,6 +327,9 @@
|
|
|
264
327
|
"babel-jest": "30.4.1",
|
|
265
328
|
"eslint": "^9.39.0",
|
|
266
329
|
"expect": "30.4.1",
|
|
330
|
+
"expo-camera": "57.0.6",
|
|
331
|
+
"expo-modules-core": "^57.0.21",
|
|
332
|
+
"expo-video": "57.0.5",
|
|
267
333
|
"happy-dom": "^20.0.0",
|
|
268
334
|
"jest": "30.4.2",
|
|
269
335
|
"jest-environment-node": "30.4.1",
|
|
@@ -281,8 +347,8 @@
|
|
|
281
347
|
"tsup": "^8.5.1",
|
|
282
348
|
"typescript": "^5.9.0",
|
|
283
349
|
"vitest": "^4.1.11",
|
|
284
|
-
"@krizaka/
|
|
285
|
-
"@krizaka/
|
|
350
|
+
"@krizaka/config": "0.1.0",
|
|
351
|
+
"@krizaka/tokens": "2.5.0"
|
|
286
352
|
},
|
|
287
353
|
"engines": {
|
|
288
354
|
"node": ">=20"
|
|
@@ -294,6 +360,15 @@
|
|
|
294
360
|
"@krizaka/tailwind": {
|
|
295
361
|
"optional": true
|
|
296
362
|
},
|
|
363
|
+
"expo-camera": {
|
|
364
|
+
"optional": true
|
|
365
|
+
},
|
|
366
|
+
"expo-video": {
|
|
367
|
+
"optional": true
|
|
368
|
+
},
|
|
369
|
+
"hls.js": {
|
|
370
|
+
"optional": true
|
|
371
|
+
},
|
|
297
372
|
"react-dom": {
|
|
298
373
|
"optional": true
|
|
299
374
|
},
|
|
@@ -317,7 +392,7 @@
|
|
|
317
392
|
{
|
|
318
393
|
"name": "./native (bundled into the app by Metro, never downloaded: a regression guard, not a budget)",
|
|
319
394
|
"path": "dist/native.js",
|
|
320
|
-
"limit": "
|
|
395
|
+
"limit": "16 kB",
|
|
321
396
|
"gzip": true
|
|
322
397
|
},
|
|
323
398
|
{
|
|
@@ -741,9 +816,162 @@
|
|
|
741
816
|
"tailwind-variants",
|
|
742
817
|
"clsx"
|
|
743
818
|
]
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
"name": "./pagination",
|
|
822
|
+
"path": "dist/pagination.js",
|
|
823
|
+
"limit": "2 kB",
|
|
824
|
+
"gzip": true,
|
|
825
|
+
"ignore": [
|
|
826
|
+
"tailwind-variants",
|
|
827
|
+
"clsx"
|
|
828
|
+
]
|
|
829
|
+
},
|
|
830
|
+
{
|
|
831
|
+
"name": "./data-table",
|
|
832
|
+
"path": "dist/data-table.js",
|
|
833
|
+
"limit": "9.5 kB",
|
|
834
|
+
"gzip": true,
|
|
835
|
+
"ignore": [
|
|
836
|
+
"tailwind-variants",
|
|
837
|
+
"clsx"
|
|
838
|
+
]
|
|
839
|
+
},
|
|
840
|
+
{
|
|
841
|
+
"name": "./filter-bar",
|
|
842
|
+
"path": "dist/filter-bar.js",
|
|
843
|
+
"limit": "34 kB",
|
|
844
|
+
"gzip": true,
|
|
845
|
+
"ignore": [
|
|
846
|
+
"tailwind-variants",
|
|
847
|
+
"clsx"
|
|
848
|
+
]
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
"name": "./combobox",
|
|
852
|
+
"path": "dist/combobox.js",
|
|
853
|
+
"limit": "13 kB",
|
|
854
|
+
"gzip": true,
|
|
855
|
+
"ignore": [
|
|
856
|
+
"tailwind-variants",
|
|
857
|
+
"clsx"
|
|
858
|
+
]
|
|
859
|
+
},
|
|
860
|
+
{
|
|
861
|
+
"name": "./tag-input",
|
|
862
|
+
"path": "dist/tag-input.js",
|
|
863
|
+
"limit": "13.5 kB",
|
|
864
|
+
"gzip": true,
|
|
865
|
+
"ignore": [
|
|
866
|
+
"tailwind-variants",
|
|
867
|
+
"clsx"
|
|
868
|
+
]
|
|
869
|
+
},
|
|
870
|
+
{
|
|
871
|
+
"name": "./date-picker",
|
|
872
|
+
"path": "dist/date-picker.js",
|
|
873
|
+
"limit": "29 kB",
|
|
874
|
+
"gzip": true,
|
|
875
|
+
"ignore": [
|
|
876
|
+
"tailwind-variants",
|
|
877
|
+
"clsx"
|
|
878
|
+
]
|
|
879
|
+
},
|
|
880
|
+
{
|
|
881
|
+
"name": "./search-field",
|
|
882
|
+
"path": "dist/search-field.js",
|
|
883
|
+
"limit": "3 kB",
|
|
884
|
+
"gzip": true,
|
|
885
|
+
"ignore": [
|
|
886
|
+
"tailwind-variants",
|
|
887
|
+
"clsx"
|
|
888
|
+
]
|
|
889
|
+
},
|
|
890
|
+
{
|
|
891
|
+
"name": "./video-player",
|
|
892
|
+
"path": "dist/video-player.js",
|
|
893
|
+
"limit": "15 kB",
|
|
894
|
+
"gzip": true,
|
|
895
|
+
"ignore": [
|
|
896
|
+
"tailwind-variants",
|
|
897
|
+
"clsx"
|
|
898
|
+
]
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
"name": "./file-upload",
|
|
902
|
+
"path": "dist/file-upload.js",
|
|
903
|
+
"limit": "5 kB",
|
|
904
|
+
"gzip": true,
|
|
905
|
+
"ignore": [
|
|
906
|
+
"tailwind-variants",
|
|
907
|
+
"clsx"
|
|
908
|
+
]
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
"name": "./media-capture",
|
|
912
|
+
"path": "dist/media-capture.js",
|
|
913
|
+
"limit": "3.8 kB",
|
|
914
|
+
"gzip": true,
|
|
915
|
+
"ignore": [
|
|
916
|
+
"tailwind-variants",
|
|
917
|
+
"clsx"
|
|
918
|
+
]
|
|
919
|
+
},
|
|
920
|
+
{
|
|
921
|
+
"name": "./video-trimmer",
|
|
922
|
+
"path": "dist/video-trimmer.js",
|
|
923
|
+
"limit": "2.4 kB",
|
|
924
|
+
"gzip": true,
|
|
925
|
+
"ignore": [
|
|
926
|
+
"tailwind-variants",
|
|
927
|
+
"clsx"
|
|
928
|
+
]
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
"name": "./audio-player",
|
|
932
|
+
"path": "dist/audio-player.js",
|
|
933
|
+
"limit": "2.8 kB",
|
|
934
|
+
"gzip": true,
|
|
935
|
+
"ignore": [
|
|
936
|
+
"tailwind-variants",
|
|
937
|
+
"clsx"
|
|
938
|
+
]
|
|
939
|
+
},
|
|
940
|
+
{
|
|
941
|
+
"name": "./image-cropper",
|
|
942
|
+
"path": "dist/image-cropper.js",
|
|
943
|
+
"limit": "12.5 kB",
|
|
944
|
+
"gzip": true,
|
|
945
|
+
"ignore": [
|
|
946
|
+
"tailwind-variants",
|
|
947
|
+
"clsx"
|
|
948
|
+
]
|
|
949
|
+
},
|
|
950
|
+
{
|
|
951
|
+
"name": "./native/video-player (expo-video is the app's)",
|
|
952
|
+
"path": "dist/native/video-player.js",
|
|
953
|
+
"limit": "2 kB",
|
|
954
|
+
"gzip": true,
|
|
955
|
+
"ignore": [
|
|
956
|
+
"expo-video",
|
|
957
|
+
"expo-camera",
|
|
958
|
+
"@krizaka/ui"
|
|
959
|
+
]
|
|
960
|
+
},
|
|
961
|
+
{
|
|
962
|
+
"name": "./native/media-capture (expo-camera is the app's)",
|
|
963
|
+
"path": "dist/native/media-capture.js",
|
|
964
|
+
"limit": "2.5 kB",
|
|
965
|
+
"gzip": true,
|
|
966
|
+
"ignore": [
|
|
967
|
+
"expo-video",
|
|
968
|
+
"expo-camera",
|
|
969
|
+
"@krizaka/ui"
|
|
970
|
+
]
|
|
744
971
|
}
|
|
745
972
|
],
|
|
746
973
|
"dependencies": {
|
|
974
|
+
"@krizaka/intl": "^0.1.0",
|
|
747
975
|
"clsx": "^2.1.1",
|
|
748
976
|
"cmdk": "^1.1.1",
|
|
749
977
|
"radix-ui": "^1.7.0",
|
package/registry/alert.json
CHANGED
|
@@ -147,7 +147,7 @@
|
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
"path": "meta.ts",
|
|
150
|
-
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"glow-card\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/** The group of the catalogue. */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
150
|
+
"content": "// The documentation of a component, carried by its code: each primitive has a `meta.ts` beside its source\n// (`src/<name>/meta.ts`; a component that exists only in React Native: `src/native/meta/<name>.ts`). Never built into\n// the package: `scripts/build-registry.mjs` reads them into `registry/<name>.json`, which krizaka.com renders as\n// /docs/ui/<name>, and `scripts/registry.test.mjs` fails when one is missing or incomplete.\n//\n// Why a typed module and not JSDoc tags: the fields are lists and links (`related`, `whenNotToUse[].use`, examples),\n// which a type checks and a comment does not; the file is plain data (erasable TypeScript), so Node reads it without a\n// compiler, and an editor completes it.\n\n/** Every documented component: the web primitives (one entry of the package each) and the native-only ones. */\nexport type ComponentName =\n | \"alert\"\n | \"audio-player\"\n | \"avatar\"\n | \"badge\"\n | \"button\"\n | \"card\"\n | \"checkbox\"\n | \"chip\"\n | \"chip-link\"\n | \"cn\"\n | \"combobox\"\n | \"command\"\n | \"confirm-button\"\n | \"countdown\"\n | \"data-table\"\n | \"date-picker\"\n | \"dialog\"\n | \"dropdown-menu\"\n | \"empty-state\"\n | \"field\"\n | \"file-upload\"\n | \"filter-bar\"\n | \"glow-card\"\n | \"image-cropper\"\n | \"iso\"\n | \"kbd\"\n | \"loader\"\n | \"marquee\"\n | \"mascots\"\n | \"media-capture\"\n | \"meter\"\n | \"nav-bar\"\n | \"number-ticker\"\n | \"page-header\"\n | \"pagination\"\n | \"popover\"\n | \"progress\"\n | \"radio-group\"\n | \"search-field\"\n | \"section-backdrop\"\n | \"segmented\"\n | \"separator\"\n | \"skeleton\"\n | \"slider\"\n | \"slot\"\n | \"spinner\"\n | \"stat\"\n | \"stepper\"\n | \"switch\"\n | \"tabs\"\n | \"tag-input\"\n | \"theme\"\n | \"toast\"\n | \"tooltip\"\n | \"txt\"\n | \"video-player\"\n | \"video-trimmer\";\n\n/** Where a component exists: `@krizaka/ui/<name>` (web), `@krizaka/ui/native` (React Native), or both. */\nexport type Platform = \"web\" | \"native\" | \"both\";\n\n/** `stable`: its API only changes in a major. `beta`: it may still change in a minor. */\nexport type Status = \"stable\" | \"beta\";\n\n/** The group of the catalogue. `media`: video, sound, camera, files, cropping. */\nexport type Category = \"actions\" | \"forms\" | \"navigation\" | \"overlays\" | \"feedback\" | \"data-display\" | \"media\" | \"layout\" | \"foundations\";\n\n/**\n * A named example: the file `registry/examples/<component>/<name>.tsx` (web) or\n * `registry/examples/<component>/native/<name>.tsx` (React Native) — at most 40 lines, imported by the stories and\n * shown (live, with its code) by the documentation.\n */\nexport interface Example {\n /** The file name, kebab-case (`primary`, `icon-button`). */\n readonly name: string;\n /** A short title (`Primary`, `Icon button`). */\n readonly title: string;\n /** One or two sentences: when this variant is the right one. */\n readonly description: string;\n}\n\n/** One platform's side of a component. */\nexport interface PlatformDocs {\n /** The names to import (`[\"Button\", \"IconButton\"]`): from `@krizaka/ui/<name>` on the web, `@krizaka/ui/native` in React Native. */\n readonly imports: readonly string[];\n /** The examples, in reading order; the first one is the component's preview. */\n readonly examples: readonly Example[];\n}\n\n/** The React Native side: the same concept, and what differs from the web API. */\nexport interface NativeDocs extends PlatformDocs {\n /**\n * The entry to import from when it is not `@krizaka/ui/native`: a component that needs an Expo module (an optional\n * peer) has its own, `@krizaka/ui/native/<name>`, so an app that does not use it never installs the module.\n */\n readonly entry?: string;\n /** What differs from the web API (`label` instead of children…); empty for a native-only component. */\n readonly differences: readonly string[];\n}\n\nexport interface KeyboardInteraction {\n /** The keys, as written on a keyboard: `Space`, `Enter`, `Arrow keys`, `Esc`, `Tab`. */\n readonly keys: string;\n /** What they do. */\n readonly action: string;\n}\n\nexport interface ComponentMeta {\n /** The display name: `Button`, `Dropdown menu`. */\n readonly title: string;\n /** One sentence: what it is. */\n readonly summary: string;\n readonly status: Status;\n readonly category: Category;\n /** Must match the sides below: `both` ⇔ `web` and `native`. */\n readonly platforms: Platform;\n /** When to reach for it: concrete situations, one per item. */\n readonly whenToUse: readonly string[];\n /** When not to — and what to use instead (`use`), when another component is the answer. */\n readonly whenNotToUse: readonly { readonly when: string; readonly use?: ComponentName }[];\n /** How to use it well: wording, placement, composition. */\n readonly bestPractices: readonly string[];\n readonly accessibility: {\n /** The keyboard, when it does more than Tab and Enter. */\n readonly keyboard: readonly KeyboardInteraction[];\n /** Roles, names and announcements: what the component does, what the app must provide. */\n readonly notes: readonly string[];\n };\n /** The components a reader of this page should know about. */\n readonly related: readonly ComponentName[];\n readonly web?: PlatformDocs;\n readonly native?: NativeDocs;\n}\n"
|
|
151
151
|
}
|
|
152
152
|
],
|
|
153
153
|
"dependencies": [
|