@caratlogic/design-system 0.1.9 → 0.1.11
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/components/atoms/ToggleSwitch/ToggleSwitch.d.ts.map +1 -1
- package/dist/components/atoms/ToggleSwitch/ToggleSwitch.utils.d.ts +9 -0
- package/dist/components/atoms/ToggleSwitch/ToggleSwitch.utils.d.ts.map +1 -1
- package/dist/components/layouts/CreateFormPageShell/CreateFormPageShell.d.ts.map +1 -1
- package/dist/components/organisms/MediaGallery/MediaGallery.d.ts +1 -1
- package/dist/components/organisms/MediaGallery/MediaGallery.d.ts.map +1 -1
- package/dist/components/organisms/MediaGallery/MediaGallery.utils.d.ts +6 -0
- package/dist/components/organisms/MediaGallery/MediaGallery.utils.d.ts.map +1 -1
- package/dist/components/ui/switch.d.ts.map +1 -1
- package/dist/constants/filePatterns.d.ts +3 -0
- package/dist/constants/filePatterns.d.ts.map +1 -1
- package/dist/index.cjs.js +78 -32
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +78 -32
- package/dist/index.esm.js.map +1 -1
- package/dist/ui.cjs.js +26 -20
- package/dist/ui.cjs.js.map +1 -1
- package/dist/ui.esm.js +26 -20
- package/dist/ui.esm.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleSwitch.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/ToggleSwitch/ToggleSwitch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,wBAAgB,YAAY,CAAC,EAC3B,OAAe,EACf,eAAe,EACf,QAAgB,EAChB,EAAE,EACF,IAAI,EACJ,SAAS,EACT,KAAK,EACL,aAAuB,EACvB,IAAW,EACX,GAAG,KAAK,EACT,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ToggleSwitch.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/ToggleSwitch/ToggleSwitch.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,wBAAgB,YAAY,CAAC,EAC3B,OAAe,EACf,eAAe,EACf,QAAgB,EAChB,EAAE,EACF,IAAI,EACJ,SAAS,EACT,KAAK,EACL,aAAuB,EACvB,IAAW,EACX,GAAG,KAAK,EACT,EAAE,iBAAiB,2CAwEnB"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import type { SwitchSizeClasses, ToggleSwitchSize } from './ToggleSwitch.types';
|
|
2
|
+
/**
|
|
3
|
+
* Track, thumb and travel, sized so the thumb keeps an even 2px inset on all
|
|
4
|
+
* four sides. Travel is stated in px rather than `calc(100% - Npx)`: that form
|
|
5
|
+
* resolves against the thumb's own width, so the gap silently changed whenever a
|
|
6
|
+
* thumb size did — `md` ended up with a 0.2px vertical inset and no gap at
|
|
7
|
+
* either end, which read as a thumb bulging out of its track.
|
|
8
|
+
*
|
|
9
|
+
* inner = track - 2px border | thumb = innerHeight - 4 | on = innerWidth - thumb - 2
|
|
10
|
+
*/
|
|
2
11
|
export declare const switchSizes: Record<ToggleSwitchSize, SwitchSizeClasses>;
|
|
3
12
|
//# sourceMappingURL=ToggleSwitch.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleSwitch.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/ToggleSwitch/ToggleSwitch.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEhF,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"ToggleSwitch.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/ToggleSwitch/ToggleSwitch.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEhF;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAsBnE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateFormPageShell.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/CreateFormPageShell/CreateFormPageShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE5E,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAkB,EAClB,kBAAkB,GACnB,EAAE,wBAAwB,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"CreateFormPageShell.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/CreateFormPageShell/CreateFormPageShell.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE5E,wBAAgB,mBAAmB,CAAC,EAClC,KAAK,EACL,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAkB,EAClB,kBAAkB,GACnB,EAAE,wBAAwB,GAAG,YAAY,CA2BzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaGallery.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/MediaGallery/MediaGallery.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,
|
|
1
|
+
{"version":3,"file":"MediaGallery.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/MediaGallery/MediaGallery.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAY1C,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,sBAAsB,CAAC;AAwI9B,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CA+H9C,CAAC"}
|
|
@@ -2,6 +2,12 @@ import type { MediaItem, MediaKind } from './MediaGallery.types';
|
|
|
2
2
|
/** Seek to ~1st frame for static video thumbnails (HTML5 media fragment). */
|
|
3
3
|
export declare const videoThumbnailSrc: (src: string) => string;
|
|
4
4
|
export declare const createVideoMediaItem: (src: string, index: number, idPrefix?: string) => MediaItem;
|
|
5
|
+
/**
|
|
6
|
+
* True when a "video" is really an interactive viewer page. Supplier 360°
|
|
7
|
+
* spinners (Vision360, Varni) serve `text/html`, so `<video>` renders nothing
|
|
8
|
+
* and there is no frame to seek for a thumbnail — they need an iframe.
|
|
9
|
+
*/
|
|
10
|
+
export declare const isEmbedMediaItem: (item: MediaItem) => boolean;
|
|
5
11
|
export declare const isPdfMediaItem: (item: MediaItem) => boolean;
|
|
6
12
|
export declare const MEDIA_KIND_ORDER: MediaKind[];
|
|
7
13
|
export declare const MEDIA_KIND_LABEL: Record<MediaKind, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MediaGallery.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/MediaGallery/MediaGallery.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjE,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,MAI/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,KAAK,MAAM,EACX,OAAO,MAAM,EACb,iBAAgB,KACf,SAKD,CAAC;AAEH,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OAGa,CAAC;AAE/D,eAAO,MAAM,gBAAgB,EAAE,SAAS,EAAsC,CAAC;AAE/E,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAItD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,SAAS,EAAE,KACjB,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,CAU/B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,SAAS,EAAE,KAAG,SAAS,EACU,CAAC;AAExE,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,EAAE,WAAW,MAAM,KAAG,IASlE,CAAC"}
|
|
1
|
+
{"version":3,"file":"MediaGallery.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/MediaGallery/MediaGallery.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjE,6EAA6E;AAC7E,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,KAAG,MAI/C,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,KAAK,MAAM,EACX,OAAO,MAAM,EACb,iBAAgB,KACf,SAKD,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,MAAM,SAAS,KAAG,OACE,CAAC;AAEtD,eAAO,MAAM,cAAc,GAAI,MAAM,SAAS,KAAG,OAGa,CAAC;AAE/D,eAAO,MAAM,gBAAgB,EAAE,SAAS,EAAsC,CAAC;AAE/E,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAItD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,SAAS,EAAE,KACjB,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,CAU/B,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,OAAO,SAAS,EAAE,KAAG,SAAS,EACU,CAAC;AAExE,eAAO,MAAM,iBAAiB,GAAI,KAAK,MAAM,EAAE,WAAW,MAAM,KAAG,IASlE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/ui/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../../src/components/ui/switch.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAqCD,QAAA,MAAM,MAAM,uFA4DX,CAAC;AAIF,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -4,6 +4,8 @@ export declare const FILE_TYPE_PATTERNS: {
|
|
|
4
4
|
readonly DOCUMENT: RegExp;
|
|
5
5
|
readonly VIDEO: RegExp;
|
|
6
6
|
readonly AUDIO: RegExp;
|
|
7
|
+
/** Interactive viewer pages (supplier 360° spinners), not media files. */
|
|
8
|
+
readonly EMBED: RegExp;
|
|
7
9
|
};
|
|
8
10
|
export declare const isFileType: {
|
|
9
11
|
readonly pdf: (url: string) => boolean;
|
|
@@ -11,5 +13,6 @@ export declare const isFileType: {
|
|
|
11
13
|
readonly document: (url: string) => boolean;
|
|
12
14
|
readonly video: (url: string) => boolean;
|
|
13
15
|
readonly audio: (url: string) => boolean;
|
|
16
|
+
readonly embed: (url: string) => boolean;
|
|
14
17
|
};
|
|
15
18
|
//# sourceMappingURL=filePatterns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filePatterns.d.ts","sourceRoot":"","sources":["../../src/constants/filePatterns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;
|
|
1
|
+
{"version":3,"file":"filePatterns.d.ts","sourceRoot":"","sources":["../../src/constants/filePatterns.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB;;;;;;IAM7B,0EAA0E;;CAElE,CAAC;AAEX,eAAO,MAAM,UAAU;wBACV,MAAM;0BACJ,MAAM;6BACH,MAAM;0BACT,MAAM;0BACN,MAAM;0BACN,MAAM;CACX,CAAC"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -5772,21 +5772,33 @@ const TextHyperlink = ({ to, href, children, showIcon = true, className, 'aria-l
|
|
|
5772
5772
|
return (jsxRuntime.jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", "aria-label": ariaLabel, className: cn(LINK_CLASS, className), children: content }));
|
|
5773
5773
|
};
|
|
5774
5774
|
|
|
5775
|
+
/**
|
|
5776
|
+
* Track, thumb and travel, sized so the thumb keeps an even 2px inset on all
|
|
5777
|
+
* four sides. Travel is stated in px rather than `calc(100% - Npx)`: that form
|
|
5778
|
+
* resolves against the thumb's own width, so the gap silently changed whenever a
|
|
5779
|
+
* thumb size did — `md` ended up with a 0.2px vertical inset and no gap at
|
|
5780
|
+
* either end, which read as a thumb bulging out of its track.
|
|
5781
|
+
*
|
|
5782
|
+
* inner = track - 2px border | thumb = innerHeight - 4 | on = innerWidth - thumb - 2
|
|
5783
|
+
*/
|
|
5775
5784
|
const switchSizes = {
|
|
5785
|
+
// track 28x16 → inner 26x14, thumb 10, on 14
|
|
5776
5786
|
sm: {
|
|
5777
5787
|
switch: 'h-4 w-7',
|
|
5778
|
-
thumb: 'size-
|
|
5779
|
-
translate: 'data-[state=checked]:translate-x-[
|
|
5788
|
+
thumb: 'size-2.5',
|
|
5789
|
+
translate: 'data-[state=unchecked]:translate-x-[2px] data-[state=checked]:translate-x-[14px]',
|
|
5780
5790
|
},
|
|
5791
|
+
// track 32x20 → inner 30x18, thumb 14, on 14
|
|
5781
5792
|
md: {
|
|
5782
|
-
switch: 'h-
|
|
5783
|
-
thumb: 'size-
|
|
5784
|
-
translate: 'data-[state=
|
|
5793
|
+
switch: 'h-5 w-8',
|
|
5794
|
+
thumb: 'size-3.5',
|
|
5795
|
+
translate: 'data-[state=unchecked]:translate-x-[2px] data-[state=checked]:translate-x-[14px]',
|
|
5785
5796
|
},
|
|
5797
|
+
// track 44x24 → inner 42x22, thumb 18, on 22
|
|
5786
5798
|
lg: {
|
|
5787
5799
|
switch: 'h-6 w-11',
|
|
5788
|
-
thumb: 'size-
|
|
5789
|
-
translate: 'data-[state=checked]:translate-x-[
|
|
5800
|
+
thumb: 'size-[1.125rem]',
|
|
5801
|
+
translate: 'data-[state=unchecked]:translate-x-[2px] data-[state=checked]:translate-x-[22px]',
|
|
5790
5802
|
},
|
|
5791
5803
|
};
|
|
5792
5804
|
|
|
@@ -5797,7 +5809,7 @@ function ToggleSwitch({ checked = false, onCheckedChange, disabled = false, id,
|
|
|
5797
5809
|
}
|
|
5798
5810
|
};
|
|
5799
5811
|
const currentSize = switchSizes[size];
|
|
5800
|
-
const switchButton = (jsxRuntime.jsx("button", { type: "button", role: "switch", "aria-checked": checked, "data-state": checked ? 'checked' : 'unchecked', value: checked ? 'on' : 'off', "data-slot": "switch", disabled: disabled, onClick: handleClick, id: id, name: name, className: cn('peer inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent transition-all outline-none', 'focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:ring-[3px]', 'disabled:cursor-not-allowed disabled:opacity-50', 'data-[state=unchecked]:bg-muted', 'data-[state=checked]:bg-primary', currentSize.switch, className), ...props, children: jsxRuntime.jsx("span", { "data-state": checked ? 'checked' : 'unchecked', "data-slot": "switch-thumb", className: cn('pointer-events-none block rounded-full ring-0 transition-transform', 'bg-card data-[state=checked]:bg-primary-foreground',
|
|
5812
|
+
const switchButton = (jsxRuntime.jsx("button", { type: "button", role: "switch", "aria-checked": checked, "data-state": checked ? 'checked' : 'unchecked', value: checked ? 'on' : 'off', "data-slot": "switch", disabled: disabled, onClick: handleClick, id: id, name: name, className: cn('peer inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent transition-all outline-none', 'focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:ring-[3px]', 'disabled:cursor-not-allowed disabled:opacity-50', 'data-[state=unchecked]:bg-muted', 'data-[state=checked]:bg-primary', currentSize.switch, className), ...props, children: jsxRuntime.jsx("span", { "data-state": checked ? 'checked' : 'unchecked', "data-slot": "switch-thumb", className: cn('pointer-events-none block rounded-full ring-0 transition-transform', 'bg-card data-[state=checked]:bg-primary-foreground', currentSize.thumb, currentSize.translate) }) }));
|
|
5801
5813
|
if (!label) {
|
|
5802
5814
|
return switchButton;
|
|
5803
5815
|
}
|
|
@@ -58466,33 +58478,39 @@ function ZoomSplitViewer({ src, alt = 'Preview', zoom = 2, lensSize = 160, paneO
|
|
|
58466
58478
|
}) })), isTouchDevice && (jsxRuntime.jsx("p", { className: `text-xs text-muted-foreground text-center mt-2 ${isMobile ? 'text-2xs' : ''}`, children: isMobile ? 'Touch & hold to zoom' : 'Touch and hold to zoom' }))] }));
|
|
58467
58479
|
}
|
|
58468
58480
|
|
|
58469
|
-
|
|
58470
|
-
|
|
58471
|
-
|
|
58472
|
-
|
|
58473
|
-
|
|
58474
|
-
|
|
58475
|
-
},
|
|
58476
|
-
md: {
|
|
58477
|
-
track: { width: 44, height: 24 },
|
|
58478
|
-
thumb: 20,
|
|
58479
|
-
on: 22,
|
|
58480
|
-
off: 2,
|
|
58481
|
-
},
|
|
58482
|
-
lg: {
|
|
58483
|
-
track: { width: 52, height: 28 },
|
|
58484
|
-
thumb: 24,
|
|
58485
|
-
on: 26,
|
|
58486
|
-
off: 2,
|
|
58487
|
-
},
|
|
58481
|
+
/** 1px border on the track, and the gap between thumb and track. */
|
|
58482
|
+
const TRACK_BORDER = 1;
|
|
58483
|
+
const THUMB_INSET = 2;
|
|
58484
|
+
const TRACK_SIZE = {
|
|
58485
|
+
sm: { width: 28, height: 16 },
|
|
58486
|
+
md: { width: 44, height: 24 },
|
|
58487
|
+
lg: { width: 52, height: 28 },
|
|
58488
58488
|
};
|
|
58489
|
+
/**
|
|
58490
|
+
* Thumb size and travel are derived from the track rather than listed per size:
|
|
58491
|
+
* hardcoding them left the thumb 1px from the top and bottom but flush against
|
|
58492
|
+
* the inner right edge when on, so it bulged past the track's rounded end.
|
|
58493
|
+
* Deriving keeps the inset equal on all four sides at every size.
|
|
58494
|
+
*/
|
|
58495
|
+
function switchGeometry(size) {
|
|
58496
|
+
const track = TRACK_SIZE[size];
|
|
58497
|
+
const innerWidth = track.width - TRACK_BORDER * 2;
|
|
58498
|
+
const innerHeight = track.height - TRACK_BORDER * 2;
|
|
58499
|
+
const thumb = innerHeight - THUMB_INSET * 2;
|
|
58500
|
+
return {
|
|
58501
|
+
track,
|
|
58502
|
+
thumb,
|
|
58503
|
+
off: THUMB_INSET,
|
|
58504
|
+
on: innerWidth - thumb - THUMB_INSET,
|
|
58505
|
+
};
|
|
58506
|
+
}
|
|
58489
58507
|
const Switch = React__namespace.forwardRef(({ checked = false, onCheckedChange, disabled = false, id, name, className, size = 'md', 'aria-label': ariaLabel, }, ref) => {
|
|
58490
58508
|
const handleClick = () => {
|
|
58491
58509
|
if (!disabled && onCheckedChange) {
|
|
58492
58510
|
onCheckedChange(!checked);
|
|
58493
58511
|
}
|
|
58494
58512
|
};
|
|
58495
|
-
const dims =
|
|
58513
|
+
const dims = switchGeometry(size);
|
|
58496
58514
|
return (jsxRuntime.jsx("button", { type: "button", role: "switch", "aria-checked": checked, "aria-label": ariaLabel, "data-state": checked ? 'checked' : 'unchecked', disabled: disabled, onClick: handleClick, ref: ref, id: id, name: name, style: {
|
|
58497
58515
|
width: dims.track.width,
|
|
58498
58516
|
height: dims.track.height,
|
|
@@ -64653,6 +64671,8 @@ const FILE_TYPE_PATTERNS = {
|
|
|
64653
64671
|
DOCUMENT: /\.(doc|docx|xls|xlsx|ppt|pptx)($|\?)/i,
|
|
64654
64672
|
VIDEO: /\.(mp4|m4v|avi|mov|wmv|flv|webm|mkv|ogv|mpe?g|3gp)($|\?)/i,
|
|
64655
64673
|
AUDIO: /\.(mp3|wav|flac|aac|ogg)($|\?)/i,
|
|
64674
|
+
/** Interactive viewer pages (supplier 360° spinners), not media files. */
|
|
64675
|
+
EMBED: /\.html?($|\?|#)/i,
|
|
64656
64676
|
};
|
|
64657
64677
|
const isFileType = {
|
|
64658
64678
|
pdf: (url) => FILE_TYPE_PATTERNS.PDF.test(url),
|
|
@@ -64660,6 +64680,7 @@ const isFileType = {
|
|
|
64660
64680
|
document: (url) => FILE_TYPE_PATTERNS.DOCUMENT.test(url),
|
|
64661
64681
|
video: (url) => FILE_TYPE_PATTERNS.VIDEO.test(url),
|
|
64662
64682
|
audio: (url) => FILE_TYPE_PATTERNS.AUDIO.test(url),
|
|
64683
|
+
embed: (url) => FILE_TYPE_PATTERNS.EMBED.test(url),
|
|
64663
64684
|
};
|
|
64664
64685
|
|
|
64665
64686
|
/** Seek to ~1st frame for static video thumbnails (HTML5 media fragment). */
|
|
@@ -64675,6 +64696,12 @@ const createVideoMediaItem = (src, index, idPrefix = 'vid') => ({
|
|
|
64675
64696
|
src,
|
|
64676
64697
|
thumbSrc: videoThumbnailSrc(src),
|
|
64677
64698
|
});
|
|
64699
|
+
/**
|
|
64700
|
+
* True when a "video" is really an interactive viewer page. Supplier 360°
|
|
64701
|
+
* spinners (Vision360, Varni) serve `text/html`, so `<video>` renders nothing
|
|
64702
|
+
* and there is no frame to seek for a thumbnail — they need an iframe.
|
|
64703
|
+
*/
|
|
64704
|
+
const isEmbedMediaItem = (item) => item.kind === 'video' && isFileType.embed(item.src);
|
|
64678
64705
|
const isPdfMediaItem = (item) => item.isPdf === true ||
|
|
64679
64706
|
isFileType.pdf(item.src) ||
|
|
64680
64707
|
(item.kind === 'certificate' && !isFileType.image(item.src));
|
|
@@ -65782,9 +65809,22 @@ const PdfPreview = ({ item }) => {
|
|
|
65782
65809
|
const docsViewer = `https://docs.google.com/gview?embedded=1&url=${encodeURIComponent(item.src)}`;
|
|
65783
65810
|
return (jsxRuntime.jsx("object", { data: item.src, type: "application/pdf", className: "h-full w-full bg-card", "aria-label": item.name ?? 'Certificate PDF', children: jsxRuntime.jsx("iframe", { title: item.name ?? 'Certificate PDF', className: "h-full w-full border-0 bg-card", src: docsViewer }) }));
|
|
65784
65811
|
};
|
|
65812
|
+
/**
|
|
65813
|
+
* Videos arrive as either a real file or a supplier's 360° viewer page. The URL
|
|
65814
|
+
* settles most cases, but not every viewer ends in `.html` (v360, loupe360),
|
|
65815
|
+
* so a `<video>` that fails to load falls back to the iframe as well. Remounted
|
|
65816
|
+
* per selection via `key`, which resets that fallback.
|
|
65817
|
+
*/
|
|
65818
|
+
const VideoOrEmbed = ({ item }) => {
|
|
65819
|
+
const [useEmbed, setUseEmbed] = React.useState(() => isEmbedMediaItem(item));
|
|
65820
|
+
if (useEmbed) {
|
|
65821
|
+
return (jsxRuntime.jsx("iframe", { src: item.src, title: item.name ?? '360\u00B0 viewer', className: "h-full w-full border-0 bg-card", allowFullScreen: true }));
|
|
65822
|
+
}
|
|
65823
|
+
return (jsxRuntime.jsx("video", { src: item.src, controls: true, onError: () => setUseEmbed(true), className: "h-full w-full object-cover", "aria-label": item.name ?? 'Video' }));
|
|
65824
|
+
};
|
|
65785
65825
|
const MainMedia = ({ item }) => {
|
|
65786
65826
|
if (item.kind === 'video') {
|
|
65787
|
-
return
|
|
65827
|
+
return jsxRuntime.jsx(VideoOrEmbed, { item: item });
|
|
65788
65828
|
}
|
|
65789
65829
|
if (isPdfMediaItem(item)) {
|
|
65790
65830
|
return jsxRuntime.jsx(PdfPreview, { item: item });
|
|
@@ -65794,7 +65834,7 @@ const MainMedia = ({ item }) => {
|
|
|
65794
65834
|
const Thumbnail = ({ item, isActive, onSelect }) => {
|
|
65795
65835
|
const Icon = KIND_ICON[item.kind];
|
|
65796
65836
|
const isPdf = isPdfMediaItem(item);
|
|
65797
|
-
const isVideoWithoutThumb = item.kind === 'video' && !item.thumbSrc;
|
|
65837
|
+
const isVideoWithoutThumb = item.kind === 'video' && (!item.thumbSrc || isEmbedMediaItem(item));
|
|
65798
65838
|
return (jsxRuntime.jsxs("button", { type: "button", onClick: onSelect, "aria-label": `Select ${item.name ?? item.kind}`, "aria-pressed": isActive, className: cn('group relative flex aspect-square w-full cursor-pointer overflow-hidden rounded-lg border transition-colors', isActive
|
|
65799
65839
|
? 'border-primary ring-2 ring-primary/30'
|
|
65800
65840
|
: 'border-border hover:border-primary/40'), children: [isPdf ? (jsxRuntime.jsxs("span", { className: "flex h-full w-full flex-col items-center justify-center gap-1 bg-muted p-2 text-muted-foreground", children: [jsxRuntime.jsx(Icon, { size: 20 }), jsxRuntime.jsx("span", { className: "text-[10px] font-medium uppercase", children: "PDF" })] })) : isVideoWithoutThumb ? (jsxRuntime.jsx("div", { className: "h-full w-full flex items-center justify-center bg-muted", children: jsxRuntime.jsx(Icon, { size: 24, className: "text-muted-foreground" }) })) : item.kind === 'video' ? (jsxRuntime.jsx("video", { src: item.thumbSrc ?? item.src, muted: true, playsInline: true, preload: "metadata", className: "h-full w-full object-cover", "aria-hidden": "true" })) : (jsxRuntime.jsx("img", { src: item.thumbSrc ?? item.src, alt: "", className: "h-full w-full object-cover" })), !isPdf && item.kind !== 'image' && !isVideoWithoutThumb && (jsxRuntime.jsx("span", { className: "pointer-events-none absolute inset-0 flex items-center justify-center bg-black/30 text-white", children: jsxRuntime.jsx(Icon, { size: 20 }) })), isVideoWithoutThumb && (jsxRuntime.jsx("span", { className: "pointer-events-none absolute inset-0 flex items-center justify-center bg-black/30" }))] }));
|
|
@@ -65815,7 +65855,7 @@ const MediaGallery = ({ items, thumbsVisible = 4, hideTabs = false, mainAspectCl
|
|
|
65815
65855
|
(kinds.length > 0 ? (jsxRuntime.jsx(Tabs, { value: activeKind ?? undefined, onValueChange: (v) => setActiveKind(v), tabStyle: "boxed", size: "sm", children: jsxRuntime.jsx(TabsList, { children: kinds.map((kind) => {
|
|
65816
65856
|
const Icon = KIND_ICON[kind];
|
|
65817
65857
|
return (jsxRuntime.jsx(TabsTrigger, { value: kind, icon: jsxRuntime.jsx(Icon, { size: 14 }), children: MEDIA_KIND_LABEL[kind] }, kind));
|
|
65818
|
-
}) }) })) : (jsxRuntime.jsx("div", { className: "h-9", "aria-hidden": "true" }))), selected && isZoomableImage ? (jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsx(ZoomSplitViewer, { src: selected.src, alt: selected.name ?? 'Media' }), !hideDownload && (jsxRuntime.jsx("div", { className: "absolute right-3 top-3 z-20", children: jsxRuntime.jsx("button", { type: "button", onClick: handleDownload, "aria-label": "Download media", className: "inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border border-border bg-card text-foreground transition-all hover:border-primary hover:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:border-primary focus-visible:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:outline-none", children: jsxRuntime.jsx(Download, { className: "h-4 w-4" }) }) }))] })) : selected ? (jsxRuntime.jsxs("div", { className: cn('relative overflow-hidden rounded-xl border border-border bg-muted', mainAspectClassName), children: [jsxRuntime.jsx(MainMedia, { item: selected }), !hideDownload && (jsxRuntime.jsx("div", { className: "absolute right-3 top-3", children: jsxRuntime.jsx("button", { type: "button", onClick: handleDownload, "aria-label": "Download media", className: "inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border border-border bg-card text-foreground transition-all hover:border-primary hover:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:border-primary focus-visible:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:outline-none", children: jsxRuntime.jsx(Download, { className: "h-4 w-4" }) }) }))] })) : (jsxRuntime.jsx("div", { className: cn('flex items-center justify-center rounded-xl border border-dashed border-border bg-muted/40 text-sm text-muted-foreground', mainAspectClassName), children: emptyText })), visibleItems.length > 1 && (jsxRuntime.jsx("div", { className: "grid gap-3", style: {
|
|
65858
|
+
}) }) })) : (jsxRuntime.jsx("div", { className: "h-9", "aria-hidden": "true" }))), selected && isZoomableImage ? (jsxRuntime.jsxs("div", { className: "relative", children: [jsxRuntime.jsx(ZoomSplitViewer, { src: selected.src, alt: selected.name ?? 'Media' }), !hideDownload && (jsxRuntime.jsx("div", { className: "absolute right-3 top-3 z-20", children: jsxRuntime.jsx("button", { type: "button", onClick: handleDownload, "aria-label": "Download media", className: "inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border border-border bg-card text-foreground transition-all hover:border-primary hover:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:border-primary focus-visible:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:outline-none", children: jsxRuntime.jsx(Download, { className: "h-4 w-4" }) }) }))] })) : selected ? (jsxRuntime.jsxs("div", { className: cn('relative overflow-hidden rounded-xl border border-border bg-muted', mainAspectClassName), children: [jsxRuntime.jsx(MainMedia, { item: selected }, selected.id), !hideDownload && !isEmbedMediaItem(selected) && (jsxRuntime.jsx("div", { className: "absolute right-3 top-3", children: jsxRuntime.jsx("button", { type: "button", onClick: handleDownload, "aria-label": "Download media", className: "inline-flex h-9 w-9 cursor-pointer items-center justify-center rounded-md border border-border bg-card text-foreground transition-all hover:border-primary hover:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:border-primary focus-visible:shadow-[0_0_0_4px_rgba(49,122,81,0.10)] focus-visible:outline-none", children: jsxRuntime.jsx(Download, { className: "h-4 w-4" }) }) }))] })) : (jsxRuntime.jsx("div", { className: cn('flex items-center justify-center rounded-xl border border-dashed border-border bg-muted/40 text-sm text-muted-foreground', mainAspectClassName), children: emptyText })), visibleItems.length > 1 && (jsxRuntime.jsx("div", { className: "grid gap-3", style: {
|
|
65819
65859
|
gridTemplateColumns: `repeat(${Math.min(visibleItems.length, thumbsVisible)}, minmax(0, 1fr))`,
|
|
65820
65860
|
}, children: visibleItems.slice(0, thumbsVisible).map((item) => (jsxRuntime.jsx(Thumbnail, { item: item, isActive: selected?.id === item.id, onSelect: () => setSelected(item) }, item.id))) }))] }));
|
|
65821
65861
|
};
|
|
@@ -66116,7 +66156,13 @@ function CreateFormPageHeader({ title, onBack, backLabel = 'Go back', }) {
|
|
|
66116
66156
|
function CreateFormPageShell({ title, onBack, children, backLabel, scrollable = false, containerClassName, }) {
|
|
66117
66157
|
const content = (jsxRuntime.jsxs("div", { className: cn('mx-auto w-full max-w-4xl px-4 py-4', containerClassName), children: [jsxRuntime.jsx(CreateFormPageHeader, { title: title, onBack: onBack, backLabel: backLabel }), children] }));
|
|
66118
66158
|
if (scrollable) {
|
|
66119
|
-
|
|
66159
|
+
// `shrink-0` is the load-bearing part. As a flex item in the shell's
|
|
66160
|
+
// `flex-col overflow-y-auto` parent this div was shrunk to the parent's
|
|
66161
|
+
// height while its content overflowed, so the background stopped one
|
|
66162
|
+
// screenful down and taller forms showed the page background below it.
|
|
66163
|
+
// `min-h-full` alone cannot fix that — it resolves to the same shrunken
|
|
66164
|
+
// height. The parent already scrolls, so no inner scroller is needed.
|
|
66165
|
+
return (jsxRuntime.jsx("div", { className: "min-h-full shrink-0 bg-card", children: content }));
|
|
66120
66166
|
}
|
|
66121
66167
|
return content;
|
|
66122
66168
|
}
|