@pallasoft/ps-file-components 1.2.3 → 1.3.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.
@@ -6,8 +6,8 @@ const ps_design_system_1 = require("@pallasoft/ps-design-system");
6
6
  const ps_icons_1 = require("@pallasoft/ps-icons");
7
7
  const ps_file_icon_button_classes_1 = require("../constants/ps-file-icon-button-classes");
8
8
  const PsFileIconButton = ({ disabled = false, download, href, iconKey, label, onClick, tone = 'neutral', }) => {
9
- const className = ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-ink/55 transition disabled:pointer-events-none disabled:opacity-40', ps_file_icon_button_classes_1.PsFileIconButtonClasses[tone]);
10
- const icon = (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: iconKey });
9
+ const className = ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring ps-control-square ps-control-compact inline-flex shrink-0 items-center justify-center rounded-ps-control text-ink/55 transition disabled:pointer-events-none disabled:opacity-40', ps_file_icon_button_classes_1.PsFileIconButtonClasses[tone]);
10
+ const icon = ((0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: iconKey }));
11
11
  return href === undefined ? ((0, jsx_runtime_1.jsx)("button", { "aria-label": label, className: className, disabled: disabled, onClick: onClick, title: label, type: 'button', children: icon })) : ((0, jsx_runtime_1.jsx)("a", { "aria-label": label, className: className, download: download, href: href, title: label, children: icon }));
12
12
  };
13
13
  exports.PsFileIconButton = PsFileIconButton;
@@ -11,8 +11,9 @@ export interface PsFilePickerProps {
11
11
  maxSizeBytes?: number;
12
12
  maxSizeLabel?: string;
13
13
  multiple?: boolean;
14
+ touchLabel?: string;
14
15
  onError?: (message: string) => void;
15
16
  onFileLoad?: (file: File) => void;
16
17
  onFilesSelect?: (files: File[]) => void;
17
18
  }
18
- export declare const PsFilePicker: ({ accept, acceptLabel, className, disabled, dropLabel, isLoading, labels, maxSizeBytes, maxSizeLabel, multiple, onError, onFileLoad, onFilesSelect, }: PsFilePickerProps) => import("react").JSX.Element;
19
+ export declare const PsFilePicker: ({ accept, acceptLabel, className, disabled, dropLabel, isLoading, labels, maxSizeBytes, maxSizeLabel, multiple, onError, onFileLoad, onFilesSelect, touchLabel, }: PsFilePickerProps) => import("react").JSX.Element;
@@ -7,7 +7,7 @@ const ps_design_system_1 = require("@pallasoft/ps-design-system");
7
7
  const ps_icons_1 = require("@pallasoft/ps-icons");
8
8
  const ps_file_picker_labels_1 = require("../constants/ps-file-picker-labels");
9
9
  const ps_file_selection_service_1 = require("../services/ps-file-selection-service");
10
- const PsFilePicker = ({ accept, acceptLabel, className, disabled = false, dropLabel, isLoading = false, labels, maxSizeBytes, maxSizeLabel, multiple = false, onError, onFileLoad, onFilesSelect, }) => {
10
+ const PsFilePicker = ({ accept, acceptLabel, className, disabled = false, dropLabel, isLoading = false, labels, maxSizeBytes, maxSizeLabel, multiple = false, onError, onFileLoad, onFilesSelect, touchLabel, }) => {
11
11
  const [isDragging, setIsDragging] = (0, react_1.useState)(false);
12
12
  const acceptAttr = (0, react_1.useMemo)(() => accept.join(','), [accept]);
13
13
  const text = { ...ps_file_picker_labels_1.PsFilePickerLabels, ...labels };
@@ -40,9 +40,9 @@ const PsFilePicker = ({ accept, acceptLabel, className, disabled = false, dropLa
40
40
  if (!disabled)
41
41
  setIsDragging(isOver);
42
42
  };
43
- return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('relative flex h-48 w-full flex-col items-center justify-center rounded-lg border-2 border-dashed border-line p-4 transition-all hover:border-primary/50 hover:bg-primary/5 sm:h-64', isDragging ? 'border-primary bg-primary/10' : '', disabled ? 'pointer-events-none opacity-60' : '', className), onDragEnter: (event) => onDrag(event, true), onDragLeave: (event) => onDrag(event, false), onDragOver: (event) => onDrag(event, true), onDrop: (event) => {
43
+ return ((0, jsx_runtime_1.jsxs)("div", { className: ps_design_system_1.PallasoftClassNameService.merge('relative flex h-48 w-full flex-col items-center justify-center rounded-ps-control border-2 border-dashed border-line p-4 transition-all hover:border-primary/50 hover:bg-primary/5 sm:h-64', isDragging ? 'border-primary bg-primary/10' : '', disabled ? 'pointer-events-none opacity-60' : '', className), onDragEnter: (event) => onDrag(event, true), onDragLeave: (event) => onDrag(event, false), onDragOver: (event) => onDrag(event, true), onDrop: (event) => {
44
44
  onDrag(event, false);
45
45
  select(event.dataTransfer.files);
46
- }, children: [(0, jsx_runtime_1.jsxs)("div", { className: 'pointer-events-none flex flex-col items-center gap-3 text-center', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { className: 'h-8 w-8 text-primary', iconKey: ps_icons_1.PsIconKey.Upload }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-body-2 font-medium text-ink sm:text-body-1', children: isDragging ? text.dropActive : dropLabel }), (0, jsx_runtime_1.jsx)("p", { className: 'mt-1 text-body-3 text-ink/60 sm:text-body-2', children: text.browse }), maxSizeLabel ? (0, jsx_runtime_1.jsx)("p", { className: 'mt-3 text-body-3 text-ink/60', children: maxSizeLabel }) : null, (0, jsx_runtime_1.jsxs)("p", { className: 'text-body-3 text-ink/60', children: [text.formats, " ", acceptLabel] })] })] }), (0, jsx_runtime_1.jsx)("input", { accept: acceptAttr, "aria-disabled": disabled, "aria-label": dropLabel, className: 'absolute inset-0 h-full w-full cursor-pointer opacity-0', disabled: disabled, multiple: multiple, onChange: onChange, type: 'file' })] }));
46
+ }, children: [(0, jsx_runtime_1.jsxs)("div", { className: 'pointer-events-none flex flex-col items-center gap-3 text-center', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { className: 'h-8 w-8 text-primary', iconKey: ps_icons_1.PsIconKey.Upload }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: 'text-body-2 font-medium text-ink sm:text-body-1', children: isDragging ? (text.dropActive) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("span", { className: touchLabel === undefined ? '' : '[@media(pointer:coarse)]:hidden', children: dropLabel }), touchLabel === undefined ? null : ((0, jsx_runtime_1.jsx)("span", { className: 'hidden [@media(pointer:coarse)]:inline', children: touchLabel }))] })) }), (0, jsx_runtime_1.jsxs)("p", { className: 'mt-1 text-body-3 text-ink/60 sm:text-body-2', children: [(0, jsx_runtime_1.jsx)("span", { className: '[@media(pointer:coarse)]:hidden', children: text.browse }), (0, jsx_runtime_1.jsx)("span", { className: 'hidden [@media(pointer:coarse)]:inline', children: text.browseTouch })] }), maxSizeLabel ? (0, jsx_runtime_1.jsx)("p", { className: 'mt-3 text-body-3 text-ink/60', children: maxSizeLabel }) : null, (0, jsx_runtime_1.jsxs)("p", { className: 'text-body-3 text-ink/60', children: [text.formats, " ", acceptLabel] })] })] }), (0, jsx_runtime_1.jsx)("input", { accept: acceptAttr, "aria-disabled": disabled, "aria-label": dropLabel, className: 'absolute inset-0 h-full w-full cursor-pointer opacity-0', disabled: disabled, multiple: multiple, onChange: onChange, type: 'file' })] }));
47
47
  };
48
48
  exports.PsFilePicker = PsFilePicker;
@@ -3,5 +3,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PsFileViewerButton = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const ps_design_system_1 = require("@pallasoft/ps-design-system");
6
- const PsFileViewerButton = ({ children, className, disabled, label, onClick, tone = 'default', }) => ((0, jsx_runtime_1.jsx)("button", { "aria-label": label, className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring inline-flex h-9 min-w-9 shrink-0 items-center justify-center gap-1.5 rounded-full px-2 text-sm text-white/80 transition hover:bg-white/15 hover:text-white disabled:pointer-events-none disabled:opacity-40', tone === 'danger' ? 'hover:bg-danger/80' : '', className), disabled: disabled, onClick: onClick, title: label, type: 'button', children: children }));
6
+ const PsFileViewerButton = ({ children, className, disabled, label, onClick, tone = 'default', }) => ((0, jsx_runtime_1.jsx)("button", { "aria-label": label, className: ps_design_system_1.PallasoftClassNameService.merge('ps-focus-ring ps-control-compact inline-flex min-w-ps-control-compact shrink-0 items-center justify-center gap-1.5 rounded-ps-control px-2 text-sm text-white/80 transition hover:bg-white/15 hover:text-white disabled:pointer-events-none disabled:opacity-40', tone === 'danger' ? 'hover:bg-danger/80' : '', className), disabled: disabled, onClick: onClick, title: label, type: 'button', children: children }));
7
7
  exports.PsFileViewerButton = PsFileViewerButton;
@@ -94,9 +94,9 @@ const PsFileViewer = ({ files, index, isOpen, labels, onClose, onDelete, onIndex
94
94
  file.sizeBytes === undefined ? null : ps_file_size_service_1.PsFileSizeService.format(file.sizeBytes),
95
95
  ]
96
96
  .filter((value) => value !== null)
97
- .join(' · ') })] }) }), canSearch ? ((0, jsx_runtime_1.jsxs)("div", { className: 'order-last flex w-full items-center gap-1 rounded-full bg-white/10 px-3 sm:order-none sm:w-72', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 shrink-0 text-white/60', iconKey: ps_icons_1.PsIconKey.Search }), (0, jsx_runtime_1.jsx)("input", { "aria-label": text.search, className: 'h-9 min-w-0 flex-1 bg-transparent text-sm text-white placeholder:text-white/45 focus:outline-none', onChange: (event) => setSearch(event.target.value), onKeyDown: (event) => {
97
+ .join(' · ') })] }) }), canSearch ? ((0, jsx_runtime_1.jsxs)("div", { className: 'order-last flex w-full items-center gap-1 rounded-ps-control bg-white/10 px-3 sm:order-none sm:w-72', children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 shrink-0 text-white/60', iconKey: ps_icons_1.PsIconKey.Search }), (0, jsx_runtime_1.jsx)("input", { "aria-label": text.search, className: 'h-ps-control-compact min-w-0 flex-1 bg-transparent text-sm text-white placeholder:text-white/45 focus:outline-none', onChange: (event) => setSearch(event.target.value), onKeyDown: (event) => {
98
98
  if (event.key === 'Enter')
99
99
  stepMatch(event.shiftKey ? -1 : 1);
100
- }, placeholder: text.search, ref: searchInput, type: 'search', value: search }), query.trim().length > 0 ? ((0, jsx_runtime_1.jsx)("span", { className: 'shrink-0 text-xs text-white/60', children: matchCount === 0 ? text.noMatches : `${activeMatch + 1} / ${matchCount}` })) : null, (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { disabled: matchCount === 0, label: text.previousMatch, onClick: () => stepMatch(-1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 -rotate-90', iconKey: ps_icons_1.PsIconKey.ChevronRight }) }), (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { disabled: matchCount === 0, label: text.nextMatch, onClick: () => stepMatch(1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 rotate-90', iconKey: ps_icons_1.PsIconKey.ChevronRight }) })] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-0.5', children: [canZoom ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.zoomOut, onClick: () => changeZoom(-ps_file_viewer_config_1.PsFileViewerConfig.zoomStep), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.ZoomOut }) }), (0, jsx_runtime_1.jsxs)(ps_file_viewer_button_1.PsFileViewerButton, { className: 'w-14 text-xs', label: text.zoomReset, onClick: () => setZoom(1), children: [Math.round(zoom * 100), "%"] }), (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.zoomIn, onClick: () => changeZoom(ps_file_viewer_config_1.PsFileViewerConfig.zoomStep), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.ZoomIn }) })] })) : null, canRotate ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.rotate, onClick: () => setRotation((current) => (current + ps_file_viewer_config_1.PsFileViewerConfig.rotateStep) % 360), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Rotate }) })) : null, (0, jsx_runtime_1.jsx)("a", { "aria-label": text.download, className: 'ps-focus-ring inline-flex h-9 w-9 items-center justify-center rounded-full text-white/80 transition hover:bg-white/15 hover:text-white', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, title: text.download, children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Download }) }), onDelete ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.delete, onClick: () => setIsConfirming(true), tone: 'danger', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Trash }) })) : null, (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.close, onClick: onClose, children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-5 w-5', iconKey: ps_icons_1.PsIconKey.Close }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'relative flex min-h-0 flex-1', children: [files.length > 1 ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { className: 'absolute left-2 top-1/2 z-docked h-11 w-11 -translate-y-1/2 bg-black/40', label: text.previous, onClick: () => go(-1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-5 w-5 rotate-180', iconKey: ps_icons_1.PsIconKey.ChevronRight }) })) : null, (0, jsx_runtime_1.jsx)("div", { className: 'flex min-h-0 min-w-0 flex-1 p-3 sm:p-6', children: (0, jsx_runtime_1.jsx)(ps_file_viewer_content_1.PsFileViewerContent, { activeMatch: activeMatch, file: file, labels: text, onMatchCount: setMatchCount, pdfWorkerSrc: pdfWorkerSrc, query: canSearch ? query : '', rotation: rotation, zoom: zoom }, file.id) }), files.length > 1 ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { className: 'absolute right-2 top-1/2 z-docked h-11 w-11 -translate-y-1/2 bg-black/40', label: text.next, onClick: () => go(1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-5 w-5', iconKey: ps_icons_1.PsIconKey.ChevronRight }) })) : null] }), (0, jsx_runtime_1.jsx)(ps_file_delete_confirm_1.PsFileDeleteConfirm, { fileName: file.name, isDeleting: isDeleting, isOpen: isConfirming, labels: text, onCancel: () => setIsConfirming(false), onConfirm: () => void confirmDelete() })] }) }), document.body);
100
+ }, placeholder: text.search, ref: searchInput, type: 'search', value: search }), query.trim().length > 0 ? ((0, jsx_runtime_1.jsx)("span", { className: 'shrink-0 text-xs text-white/60', children: matchCount === 0 ? text.noMatches : `${activeMatch + 1} / ${matchCount}` })) : null, (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { disabled: matchCount === 0, label: text.previousMatch, onClick: () => stepMatch(-1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone -rotate-90', iconKey: ps_icons_1.PsIconKey.ChevronRight }) }), (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { disabled: matchCount === 0, label: text.nextMatch, onClick: () => stepMatch(1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone rotate-90', iconKey: ps_icons_1.PsIconKey.ChevronRight }) })] })) : null, (0, jsx_runtime_1.jsxs)("div", { className: 'flex items-center gap-0.5', children: [canZoom ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.zoomOut, onClick: () => changeZoom(-ps_file_viewer_config_1.PsFileViewerConfig.zoomStep), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.ZoomOut }) }), (0, jsx_runtime_1.jsxs)(ps_file_viewer_button_1.PsFileViewerButton, { className: 'w-14 text-xs', label: text.zoomReset, onClick: () => setZoom(1), children: [Math.round(zoom * 100), "%"] }), (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.zoomIn, onClick: () => changeZoom(ps_file_viewer_config_1.PsFileViewerConfig.zoomStep), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.ZoomIn }) })] })) : null, canRotate ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.rotate, onClick: () => setRotation((current) => (current + ps_file_viewer_config_1.PsFileViewerConfig.rotateStep) % 360), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.Rotate }) })) : null, (0, jsx_runtime_1.jsx)("a", { "aria-label": text.download, className: 'ps-focus-ring ps-control-square ps-control-compact inline-flex items-center justify-center rounded-ps-control text-white/80 transition hover:bg-white/15 hover:text-white', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, title: text.download, children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.Download }) }), onDelete ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.delete, onClick: () => setIsConfirming(true), tone: 'danger', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.Trash }) })) : null, (0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { label: text.close, onClick: onClose, children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.Close }) })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'relative flex min-h-0 flex-1', children: [files.length > 1 ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { className: 'absolute left-2 top-1/2 z-docked size-ps-control -translate-y-1/2 bg-black/40', label: text.previous, onClick: () => go(-1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone rotate-180', iconKey: ps_icons_1.PsIconKey.ChevronRight }) })) : null, (0, jsx_runtime_1.jsx)("div", { className: 'flex min-h-0 min-w-0 flex-1 p-3 sm:p-6', children: (0, jsx_runtime_1.jsx)(ps_file_viewer_content_1.PsFileViewerContent, { activeMatch: activeMatch, file: file, labels: text, onMatchCount: setMatchCount, pdfWorkerSrc: pdfWorkerSrc, query: canSearch ? query : '', rotation: rotation, zoom: zoom }, file.id) }), files.length > 1 ? ((0, jsx_runtime_1.jsx)(ps_file_viewer_button_1.PsFileViewerButton, { className: 'absolute right-2 top-1/2 z-docked size-ps-control -translate-y-1/2 bg-black/40', label: text.next, onClick: () => go(1), children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: ps_icons_1.PsIconKey.ChevronRight }) })) : null] }), (0, jsx_runtime_1.jsx)(ps_file_delete_confirm_1.PsFileDeleteConfirm, { fileName: file.name, isDeleting: isDeleting, isOpen: isConfirming, labels: text, onCancel: () => setIsConfirming(false), onConfirm: () => void confirmDelete() })] }) }), document.body);
101
101
  };
102
102
  exports.PsFileViewer = PsFileViewer;
@@ -4,5 +4,5 @@ exports.PsUnsupportedViewer = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const ps_icons_1 = require("@pallasoft/ps-icons");
6
6
  const ps_file_kind_icon_1 = require("./ps-file-kind-icon");
7
- const PsUnsupportedViewer = ({ file, labels }) => ((0, jsx_runtime_1.jsxs)("div", { className: 'm-auto flex max-w-sm flex-col items-center gap-4 rounded-2xl bg-surface p-8 text-center shadow-2xl', children: [(0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { className: 'h-14 w-14', contentType: file.contentType, name: file.name }), (0, jsx_runtime_1.jsx)("p", { className: 'break-all font-semibold text-ink', children: file.name }), (0, jsx_runtime_1.jsx)("p", { className: 'text-sm text-ink/60', children: labels.unsupported }), (0, jsx_runtime_1.jsxs)("a", { className: 'ps-focus-ring inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-white hover:bg-primary/90', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Download }), labels.download] })] }));
7
+ const PsUnsupportedViewer = ({ file, labels }) => ((0, jsx_runtime_1.jsxs)("div", { className: 'm-auto flex max-w-sm flex-col items-center gap-4 rounded-2xl bg-surface p-8 text-center shadow-2xl', children: [(0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { className: 'h-14 w-14', contentType: file.contentType, name: file.name }), (0, jsx_runtime_1.jsx)("p", { className: 'break-all font-semibold text-ink', children: file.name }), (0, jsx_runtime_1.jsx)("p", { className: 'text-sm text-ink/60', children: labels.unsupported }), (0, jsx_runtime_1.jsxs)("a", { className: 'ps-focus-ring ps-control ps-control-padding inline-flex items-center gap-2 rounded-ps-control bg-primary text-sm font-semibold text-white hover:bg-primary/90', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, children: [(0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Download }), labels.download] })] }));
8
8
  exports.PsUnsupportedViewer = PsUnsupportedViewer;
@@ -19,6 +19,6 @@ const PsUploadRow = ({ item, labels, onCancel, onRemove, onRetry }) => {
19
19
  : item.status === ps_upload_status_1.PsUploadStatus.failed && item.error
20
20
  ? item.error
21
21
  : labels[item.status];
22
- return ((0, jsx_runtime_1.jsxs)("li", { className: 'flex items-center gap-3 rounded-ps-control border border-line px-3 py-2.5', children: [(0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { contentType: item.file.type, name: item.file.name }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 flex-1 flex-col gap-1.5', children: [(0, jsx_runtime_1.jsx)("p", { className: 'truncate text-sm font-medium text-ink', children: item.file.name }), (0, jsx_runtime_1.jsx)(ps_progress_bar_1.PsProgressBar, { label: item.file.name, tone: ps_upload_status_tones_1.PsUploadStatusTones[item.status], value: isProblem ? 1 : item.progress }), (0, jsx_runtime_1.jsxs)("p", { className: `truncate text-xs ${isProblem ? 'text-danger' : item.status === ps_upload_status_1.PsUploadStatus.done ? 'text-success' : 'text-ink/55'}`, role: item.status === ps_upload_status_1.PsUploadStatus.failed ? 'alert' : undefined, children: [size, " \u00B7 ", status] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex w-16 shrink-0 items-center justify-end gap-0.5', children: [isProblem ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Refresh, label: `${labels.retry} ${item.file.name}`, onClick: onRetry })) : null, isActive ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Close, label: `${labels.cancel} ${item.file.name}`, onClick: onCancel, tone: 'danger' })) : item.status === ps_upload_status_1.PsUploadStatus.done ? ((0, jsx_runtime_1.jsx)("span", { className: 'inline-flex h-8 w-8 items-center justify-center text-success', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-label": labels.done, className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check }) })) : ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Close, label: `${labels.remove} ${item.file.name}`, onClick: onRemove }))] })] }));
22
+ return ((0, jsx_runtime_1.jsxs)("li", { className: 'flex items-center gap-3 rounded-ps-control border border-line px-3 py-2.5', children: [(0, jsx_runtime_1.jsx)(ps_file_kind_icon_1.PsFileKindIcon, { contentType: item.file.type, name: item.file.name }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex min-w-0 flex-1 flex-col gap-1.5', children: [(0, jsx_runtime_1.jsx)("p", { className: 'truncate text-sm font-medium text-ink', children: item.file.name }), (0, jsx_runtime_1.jsx)(ps_progress_bar_1.PsProgressBar, { label: item.file.name, tone: ps_upload_status_tones_1.PsUploadStatusTones[item.status], value: isProblem ? 1 : item.progress }), (0, jsx_runtime_1.jsxs)("p", { className: `truncate text-xs ${isProblem ? 'text-danger' : item.status === ps_upload_status_1.PsUploadStatus.done ? 'text-success' : 'text-ink/55'}`, role: item.status === ps_upload_status_1.PsUploadStatus.failed ? 'alert' : undefined, children: [size, " \u00B7 ", status] })] }), (0, jsx_runtime_1.jsxs)("div", { className: 'flex w-16 shrink-0 items-center justify-end gap-0.5', children: [isProblem ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Refresh, label: `${labels.retry} ${item.file.name}`, onClick: onRetry })) : null, isActive ? ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Close, label: `${labels.cancel} ${item.file.name}`, onClick: onCancel, tone: 'danger' })) : item.status === ps_upload_status_1.PsUploadStatus.done ? ((0, jsx_runtime_1.jsx)("span", { className: 'ps-control-square ps-control-compact inline-flex items-center justify-center text-success', children: (0, jsx_runtime_1.jsx)(ps_icons_1.PsIcon, { "aria-label": labels.done, className: 'h-4 w-4', iconKey: ps_icons_1.PsIconKey.Check }) })) : ((0, jsx_runtime_1.jsx)(ps_file_icon_button_1.PsFileIconButton, { iconKey: ps_icons_1.PsIconKey.Close, label: `${labels.remove} ${item.file.name}`, onClick: onRemove }))] })] }));
23
23
  };
24
24
  exports.PsUploadRow = PsUploadRow;
@@ -1,5 +1,6 @@
1
1
  export declare const PsFilePickerLabels: {
2
2
  readonly browse: "or click to browse your files";
3
+ readonly browseTouch: "or tap to choose from your device";
3
4
  readonly dropActive: "Drop to upload";
4
5
  readonly formats: "Accepted formats:";
5
6
  readonly invalidType: "is not a supported file type.";
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.PsFilePickerLabels = void 0;
4
4
  exports.PsFilePickerLabels = {
5
5
  browse: 'or click to browse your files',
6
+ browseTouch: 'or tap to choose from your device',
6
7
  dropActive: 'Drop to upload',
7
8
  formats: 'Accepted formats:',
8
9
  invalidType: 'is not a supported file type.',
@@ -3,7 +3,7 @@ import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
3
3
  import { PsIcon } from '@pallasoft/ps-icons';
4
4
  import { PsFileIconButtonClasses } from '../constants/ps-file-icon-button-classes';
5
5
  export const PsFileIconButton = ({ disabled = false, download, href, iconKey, label, onClick, tone = 'neutral', }) => {
6
- const className = PallasoftClassNameService.merge('ps-focus-ring inline-flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-ink/55 transition disabled:pointer-events-none disabled:opacity-40', PsFileIconButtonClasses[tone]);
7
- const icon = _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: iconKey });
6
+ const className = PallasoftClassNameService.merge('ps-focus-ring ps-control-square ps-control-compact inline-flex shrink-0 items-center justify-center rounded-ps-control text-ink/55 transition disabled:pointer-events-none disabled:opacity-40', PsFileIconButtonClasses[tone]);
7
+ const icon = (_jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: iconKey }));
8
8
  return href === undefined ? (_jsx("button", { "aria-label": label, className: className, disabled: disabled, onClick: onClick, title: label, type: 'button', children: icon })) : (_jsx("a", { "aria-label": label, className: className, download: download, href: href, title: label, children: icon }));
9
9
  };
@@ -1,10 +1,10 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useMemo, useState } from 'react';
3
3
  import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
4
4
  import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
5
5
  import { PsFilePickerLabels } from '../constants/ps-file-picker-labels';
6
6
  import { PsFileSelectionService } from '../services/ps-file-selection-service';
7
- export const PsFilePicker = ({ accept, acceptLabel, className, disabled = false, dropLabel, isLoading = false, labels, maxSizeBytes, maxSizeLabel, multiple = false, onError, onFileLoad, onFilesSelect, }) => {
7
+ export const PsFilePicker = ({ accept, acceptLabel, className, disabled = false, dropLabel, isLoading = false, labels, maxSizeBytes, maxSizeLabel, multiple = false, onError, onFileLoad, onFilesSelect, touchLabel, }) => {
8
8
  const [isDragging, setIsDragging] = useState(false);
9
9
  const acceptAttr = useMemo(() => accept.join(','), [accept]);
10
10
  const text = { ...PsFilePickerLabels, ...labels };
@@ -37,8 +37,8 @@ export const PsFilePicker = ({ accept, acceptLabel, className, disabled = false,
37
37
  if (!disabled)
38
38
  setIsDragging(isOver);
39
39
  };
40
- return (_jsxs("div", { className: PallasoftClassNameService.merge('relative flex h-48 w-full flex-col items-center justify-center rounded-lg border-2 border-dashed border-line p-4 transition-all hover:border-primary/50 hover:bg-primary/5 sm:h-64', isDragging ? 'border-primary bg-primary/10' : '', disabled ? 'pointer-events-none opacity-60' : '', className), onDragEnter: (event) => onDrag(event, true), onDragLeave: (event) => onDrag(event, false), onDragOver: (event) => onDrag(event, true), onDrop: (event) => {
40
+ return (_jsxs("div", { className: PallasoftClassNameService.merge('relative flex h-48 w-full flex-col items-center justify-center rounded-ps-control border-2 border-dashed border-line p-4 transition-all hover:border-primary/50 hover:bg-primary/5 sm:h-64', isDragging ? 'border-primary bg-primary/10' : '', disabled ? 'pointer-events-none opacity-60' : '', className), onDragEnter: (event) => onDrag(event, true), onDragLeave: (event) => onDrag(event, false), onDragOver: (event) => onDrag(event, true), onDrop: (event) => {
41
41
  onDrag(event, false);
42
42
  select(event.dataTransfer.files);
43
- }, children: [_jsxs("div", { className: 'pointer-events-none flex flex-col items-center gap-3 text-center', children: [_jsx(PsIcon, { className: 'h-8 w-8 text-primary', iconKey: PsIconKey.Upload }), _jsxs("div", { children: [_jsx("p", { className: 'text-body-2 font-medium text-ink sm:text-body-1', children: isDragging ? text.dropActive : dropLabel }), _jsx("p", { className: 'mt-1 text-body-3 text-ink/60 sm:text-body-2', children: text.browse }), maxSizeLabel ? _jsx("p", { className: 'mt-3 text-body-3 text-ink/60', children: maxSizeLabel }) : null, _jsxs("p", { className: 'text-body-3 text-ink/60', children: [text.formats, " ", acceptLabel] })] })] }), _jsx("input", { accept: acceptAttr, "aria-disabled": disabled, "aria-label": dropLabel, className: 'absolute inset-0 h-full w-full cursor-pointer opacity-0', disabled: disabled, multiple: multiple, onChange: onChange, type: 'file' })] }));
43
+ }, children: [_jsxs("div", { className: 'pointer-events-none flex flex-col items-center gap-3 text-center', children: [_jsx(PsIcon, { className: 'h-8 w-8 text-primary', iconKey: PsIconKey.Upload }), _jsxs("div", { children: [_jsx("p", { className: 'text-body-2 font-medium text-ink sm:text-body-1', children: isDragging ? (text.dropActive) : (_jsxs(_Fragment, { children: [_jsx("span", { className: touchLabel === undefined ? '' : '[@media(pointer:coarse)]:hidden', children: dropLabel }), touchLabel === undefined ? null : (_jsx("span", { className: 'hidden [@media(pointer:coarse)]:inline', children: touchLabel }))] })) }), _jsxs("p", { className: 'mt-1 text-body-3 text-ink/60 sm:text-body-2', children: [_jsx("span", { className: '[@media(pointer:coarse)]:hidden', children: text.browse }), _jsx("span", { className: 'hidden [@media(pointer:coarse)]:inline', children: text.browseTouch })] }), maxSizeLabel ? _jsx("p", { className: 'mt-3 text-body-3 text-ink/60', children: maxSizeLabel }) : null, _jsxs("p", { className: 'text-body-3 text-ink/60', children: [text.formats, " ", acceptLabel] })] })] }), _jsx("input", { accept: acceptAttr, "aria-disabled": disabled, "aria-label": dropLabel, className: 'absolute inset-0 h-full w-full cursor-pointer opacity-0', disabled: disabled, multiple: multiple, onChange: onChange, type: 'file' })] }));
44
44
  };
@@ -1,3 +1,3 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { PallasoftClassNameService } from '@pallasoft/ps-design-system';
3
- export const PsFileViewerButton = ({ children, className, disabled, label, onClick, tone = 'default', }) => (_jsx("button", { "aria-label": label, className: PallasoftClassNameService.merge('ps-focus-ring inline-flex h-9 min-w-9 shrink-0 items-center justify-center gap-1.5 rounded-full px-2 text-sm text-white/80 transition hover:bg-white/15 hover:text-white disabled:pointer-events-none disabled:opacity-40', tone === 'danger' ? 'hover:bg-danger/80' : '', className), disabled: disabled, onClick: onClick, title: label, type: 'button', children: children }));
3
+ export const PsFileViewerButton = ({ children, className, disabled, label, onClick, tone = 'default', }) => (_jsx("button", { "aria-label": label, className: PallasoftClassNameService.merge('ps-focus-ring ps-control-compact inline-flex min-w-ps-control-compact shrink-0 items-center justify-center gap-1.5 rounded-ps-control px-2 text-sm text-white/80 transition hover:bg-white/15 hover:text-white disabled:pointer-events-none disabled:opacity-40', tone === 'danger' ? 'hover:bg-danger/80' : '', className), disabled: disabled, onClick: onClick, title: label, type: 'button', children: children }));
@@ -91,8 +91,8 @@ export const PsFileViewer = ({ files, index, isOpen, labels, onClose, onDelete,
91
91
  file.sizeBytes === undefined ? null : PsFileSizeService.format(file.sizeBytes),
92
92
  ]
93
93
  .filter((value) => value !== null)
94
- .join(' · ') })] }) }), canSearch ? (_jsxs("div", { className: 'order-last flex w-full items-center gap-1 rounded-full bg-white/10 px-3 sm:order-none sm:w-72', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 shrink-0 text-white/60', iconKey: PsIconKey.Search }), _jsx("input", { "aria-label": text.search, className: 'h-9 min-w-0 flex-1 bg-transparent text-sm text-white placeholder:text-white/45 focus:outline-none', onChange: (event) => setSearch(event.target.value), onKeyDown: (event) => {
94
+ .join(' · ') })] }) }), canSearch ? (_jsxs("div", { className: 'order-last flex w-full items-center gap-1 rounded-ps-control bg-white/10 px-3 sm:order-none sm:w-72', children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 shrink-0 text-white/60', iconKey: PsIconKey.Search }), _jsx("input", { "aria-label": text.search, className: 'h-ps-control-compact min-w-0 flex-1 bg-transparent text-sm text-white placeholder:text-white/45 focus:outline-none', onChange: (event) => setSearch(event.target.value), onKeyDown: (event) => {
95
95
  if (event.key === 'Enter')
96
96
  stepMatch(event.shiftKey ? -1 : 1);
97
- }, placeholder: text.search, ref: searchInput, type: 'search', value: search }), query.trim().length > 0 ? (_jsx("span", { className: 'shrink-0 text-xs text-white/60', children: matchCount === 0 ? text.noMatches : `${activeMatch + 1} / ${matchCount}` })) : null, _jsx(PsFileViewerButton, { disabled: matchCount === 0, label: text.previousMatch, onClick: () => stepMatch(-1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 -rotate-90', iconKey: PsIconKey.ChevronRight }) }), _jsx(PsFileViewerButton, { disabled: matchCount === 0, label: text.nextMatch, onClick: () => stepMatch(1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4 rotate-90', iconKey: PsIconKey.ChevronRight }) })] })) : null, _jsxs("div", { className: 'flex items-center gap-0.5', children: [canZoom ? (_jsxs(_Fragment, { children: [_jsx(PsFileViewerButton, { label: text.zoomOut, onClick: () => changeZoom(-PsFileViewerConfig.zoomStep), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.ZoomOut }) }), _jsxs(PsFileViewerButton, { className: 'w-14 text-xs', label: text.zoomReset, onClick: () => setZoom(1), children: [Math.round(zoom * 100), "%"] }), _jsx(PsFileViewerButton, { label: text.zoomIn, onClick: () => changeZoom(PsFileViewerConfig.zoomStep), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.ZoomIn }) })] })) : null, canRotate ? (_jsx(PsFileViewerButton, { label: text.rotate, onClick: () => setRotation((current) => (current + PsFileViewerConfig.rotateStep) % 360), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Rotate }) })) : null, _jsx("a", { "aria-label": text.download, className: 'ps-focus-ring inline-flex h-9 w-9 items-center justify-center rounded-full text-white/80 transition hover:bg-white/15 hover:text-white', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, title: text.download, children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Download }) }), onDelete ? (_jsx(PsFileViewerButton, { label: text.delete, onClick: () => setIsConfirming(true), tone: 'danger', children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Trash }) })) : null, _jsx(PsFileViewerButton, { label: text.close, onClick: onClose, children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-5 w-5', iconKey: PsIconKey.Close }) })] })] }), _jsxs("div", { className: 'relative flex min-h-0 flex-1', children: [files.length > 1 ? (_jsx(PsFileViewerButton, { className: 'absolute left-2 top-1/2 z-docked h-11 w-11 -translate-y-1/2 bg-black/40', label: text.previous, onClick: () => go(-1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-5 w-5 rotate-180', iconKey: PsIconKey.ChevronRight }) })) : null, _jsx("div", { className: 'flex min-h-0 min-w-0 flex-1 p-3 sm:p-6', children: _jsx(PsFileViewerContent, { activeMatch: activeMatch, file: file, labels: text, onMatchCount: setMatchCount, pdfWorkerSrc: pdfWorkerSrc, query: canSearch ? query : '', rotation: rotation, zoom: zoom }, file.id) }), files.length > 1 ? (_jsx(PsFileViewerButton, { className: 'absolute right-2 top-1/2 z-docked h-11 w-11 -translate-y-1/2 bg-black/40', label: text.next, onClick: () => go(1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'h-5 w-5', iconKey: PsIconKey.ChevronRight }) })) : null] }), _jsx(PsFileDeleteConfirm, { fileName: file.name, isDeleting: isDeleting, isOpen: isConfirming, labels: text, onCancel: () => setIsConfirming(false), onConfirm: () => void confirmDelete() })] }) }), document.body);
97
+ }, placeholder: text.search, ref: searchInput, type: 'search', value: search }), query.trim().length > 0 ? (_jsx("span", { className: 'shrink-0 text-xs text-white/60', children: matchCount === 0 ? text.noMatches : `${activeMatch + 1} / ${matchCount}` })) : null, _jsx(PsFileViewerButton, { disabled: matchCount === 0, label: text.previousMatch, onClick: () => stepMatch(-1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone -rotate-90', iconKey: PsIconKey.ChevronRight }) }), _jsx(PsFileViewerButton, { disabled: matchCount === 0, label: text.nextMatch, onClick: () => stepMatch(1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone rotate-90', iconKey: PsIconKey.ChevronRight }) })] })) : null, _jsxs("div", { className: 'flex items-center gap-0.5', children: [canZoom ? (_jsxs(_Fragment, { children: [_jsx(PsFileViewerButton, { label: text.zoomOut, onClick: () => changeZoom(-PsFileViewerConfig.zoomStep), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.ZoomOut }) }), _jsxs(PsFileViewerButton, { className: 'w-14 text-xs', label: text.zoomReset, onClick: () => setZoom(1), children: [Math.round(zoom * 100), "%"] }), _jsx(PsFileViewerButton, { label: text.zoomIn, onClick: () => changeZoom(PsFileViewerConfig.zoomStep), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.ZoomIn }) })] })) : null, canRotate ? (_jsx(PsFileViewerButton, { label: text.rotate, onClick: () => setRotation((current) => (current + PsFileViewerConfig.rotateStep) % 360), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.Rotate }) })) : null, _jsx("a", { "aria-label": text.download, className: 'ps-focus-ring ps-control-square ps-control-compact inline-flex items-center justify-center rounded-ps-control text-white/80 transition hover:bg-white/15 hover:text-white', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, title: text.download, children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.Download }) }), onDelete ? (_jsx(PsFileViewerButton, { label: text.delete, onClick: () => setIsConfirming(true), tone: 'danger', children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.Trash }) })) : null, _jsx(PsFileViewerButton, { label: text.close, onClick: onClose, children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.Close }) })] })] }), _jsxs("div", { className: 'relative flex min-h-0 flex-1', children: [files.length > 1 ? (_jsx(PsFileViewerButton, { className: 'absolute left-2 top-1/2 z-docked size-ps-control -translate-y-1/2 bg-black/40', label: text.previous, onClick: () => go(-1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone rotate-180', iconKey: PsIconKey.ChevronRight }) })) : null, _jsx("div", { className: 'flex min-h-0 min-w-0 flex-1 p-3 sm:p-6', children: _jsx(PsFileViewerContent, { activeMatch: activeMatch, file: file, labels: text, onMatchCount: setMatchCount, pdfWorkerSrc: pdfWorkerSrc, query: canSearch ? query : '', rotation: rotation, zoom: zoom }, file.id) }), files.length > 1 ? (_jsx(PsFileViewerButton, { className: 'absolute right-2 top-1/2 z-docked size-ps-control -translate-y-1/2 bg-black/40', label: text.next, onClick: () => go(1), children: _jsx(PsIcon, { "aria-hidden": 'true', className: 'size-ps-control-icon-standalone', iconKey: PsIconKey.ChevronRight }) })) : null] }), _jsx(PsFileDeleteConfirm, { fileName: file.name, isDeleting: isDeleting, isOpen: isConfirming, labels: text, onCancel: () => setIsConfirming(false), onConfirm: () => void confirmDelete() })] }) }), document.body);
98
98
  };
@@ -1,4 +1,4 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { PsIcon, PsIconKey } from '@pallasoft/ps-icons';
3
3
  import { PsFileKindIcon } from './ps-file-kind-icon';
4
- export const PsUnsupportedViewer = ({ file, labels }) => (_jsxs("div", { className: 'm-auto flex max-w-sm flex-col items-center gap-4 rounded-2xl bg-surface p-8 text-center shadow-2xl', children: [_jsx(PsFileKindIcon, { className: 'h-14 w-14', contentType: file.contentType, name: file.name }), _jsx("p", { className: 'break-all font-semibold text-ink', children: file.name }), _jsx("p", { className: 'text-sm text-ink/60', children: labels.unsupported }), _jsxs("a", { className: 'ps-focus-ring inline-flex items-center gap-2 rounded-full bg-primary px-4 py-2 text-sm font-semibold text-white hover:bg-primary/90', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Download }), labels.download] })] }));
4
+ export const PsUnsupportedViewer = ({ file, labels }) => (_jsxs("div", { className: 'm-auto flex max-w-sm flex-col items-center gap-4 rounded-2xl bg-surface p-8 text-center shadow-2xl', children: [_jsx(PsFileKindIcon, { className: 'h-14 w-14', contentType: file.contentType, name: file.name }), _jsx("p", { className: 'break-all font-semibold text-ink', children: file.name }), _jsx("p", { className: 'text-sm text-ink/60', children: labels.unsupported }), _jsxs("a", { className: 'ps-focus-ring ps-control ps-control-padding inline-flex items-center gap-2 rounded-ps-control bg-primary text-sm font-semibold text-white hover:bg-primary/90', download: file.name, href: file.downloadUrl === undefined ? file.url : file.downloadUrl, children: [_jsx(PsIcon, { "aria-hidden": 'true', className: 'h-4 w-4', iconKey: PsIconKey.Download }), labels.download] })] }));
@@ -16,5 +16,5 @@ export const PsUploadRow = ({ item, labels, onCancel, onRemove, onRetry }) => {
16
16
  : item.status === PsUploadStatus.failed && item.error
17
17
  ? item.error
18
18
  : labels[item.status];
19
- return (_jsxs("li", { className: 'flex items-center gap-3 rounded-ps-control border border-line px-3 py-2.5', children: [_jsx(PsFileKindIcon, { contentType: item.file.type, name: item.file.name }), _jsxs("div", { className: 'flex min-w-0 flex-1 flex-col gap-1.5', children: [_jsx("p", { className: 'truncate text-sm font-medium text-ink', children: item.file.name }), _jsx(PsProgressBar, { label: item.file.name, tone: PsUploadStatusTones[item.status], value: isProblem ? 1 : item.progress }), _jsxs("p", { className: `truncate text-xs ${isProblem ? 'text-danger' : item.status === PsUploadStatus.done ? 'text-success' : 'text-ink/55'}`, role: item.status === PsUploadStatus.failed ? 'alert' : undefined, children: [size, " \u00B7 ", status] })] }), _jsxs("div", { className: 'flex w-16 shrink-0 items-center justify-end gap-0.5', children: [isProblem ? (_jsx(PsFileIconButton, { iconKey: PsIconKey.Refresh, label: `${labels.retry} ${item.file.name}`, onClick: onRetry })) : null, isActive ? (_jsx(PsFileIconButton, { iconKey: PsIconKey.Close, label: `${labels.cancel} ${item.file.name}`, onClick: onCancel, tone: 'danger' })) : item.status === PsUploadStatus.done ? (_jsx("span", { className: 'inline-flex h-8 w-8 items-center justify-center text-success', children: _jsx(PsIcon, { "aria-label": labels.done, className: 'h-4 w-4', iconKey: PsIconKey.Check }) })) : (_jsx(PsFileIconButton, { iconKey: PsIconKey.Close, label: `${labels.remove} ${item.file.name}`, onClick: onRemove }))] })] }));
19
+ return (_jsxs("li", { className: 'flex items-center gap-3 rounded-ps-control border border-line px-3 py-2.5', children: [_jsx(PsFileKindIcon, { contentType: item.file.type, name: item.file.name }), _jsxs("div", { className: 'flex min-w-0 flex-1 flex-col gap-1.5', children: [_jsx("p", { className: 'truncate text-sm font-medium text-ink', children: item.file.name }), _jsx(PsProgressBar, { label: item.file.name, tone: PsUploadStatusTones[item.status], value: isProblem ? 1 : item.progress }), _jsxs("p", { className: `truncate text-xs ${isProblem ? 'text-danger' : item.status === PsUploadStatus.done ? 'text-success' : 'text-ink/55'}`, role: item.status === PsUploadStatus.failed ? 'alert' : undefined, children: [size, " \u00B7 ", status] })] }), _jsxs("div", { className: 'flex w-16 shrink-0 items-center justify-end gap-0.5', children: [isProblem ? (_jsx(PsFileIconButton, { iconKey: PsIconKey.Refresh, label: `${labels.retry} ${item.file.name}`, onClick: onRetry })) : null, isActive ? (_jsx(PsFileIconButton, { iconKey: PsIconKey.Close, label: `${labels.cancel} ${item.file.name}`, onClick: onCancel, tone: 'danger' })) : item.status === PsUploadStatus.done ? (_jsx("span", { className: 'ps-control-square ps-control-compact inline-flex items-center justify-center text-success', children: _jsx(PsIcon, { "aria-label": labels.done, className: 'h-4 w-4', iconKey: PsIconKey.Check }) })) : (_jsx(PsFileIconButton, { iconKey: PsIconKey.Close, label: `${labels.remove} ${item.file.name}`, onClick: onRemove }))] })] }));
20
20
  };
@@ -1,5 +1,6 @@
1
1
  export const PsFilePickerLabels = {
2
2
  browse: 'or click to browse your files',
3
+ browseTouch: 'or tap to choose from your device',
3
4
  dropActive: 'Drop to upload',
4
5
  formats: 'Accepted formats:',
5
6
  invalidType: 'is not a supported file type.',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pallasoft/ps-file-components",
3
- "version": "1.2.3",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -33,7 +33,6 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@pallasoft/ps-core-components": "^2.13.0",
36
- "@pallasoft/ps-design-system": "^1.7.0",
37
36
  "@pallasoft/ps-icons": "^1.6.0",
38
37
  "@pallasoft/ps-popovers": "^1.5.2",
39
38
  "@pallasoft/ps-utilities": "^2.9.0",
@@ -48,6 +47,7 @@
48
47
  "@commitlint/config-conventional": "^20.0.0",
49
48
  "@eslint/compat": "^2.0.0",
50
49
  "@ianvs/prettier-plugin-sort-imports": "^4.7.0",
50
+ "@pallasoft/ps-design-system": "^1.14.0",
51
51
  "@semantic-release/changelog": "^6.0.3",
52
52
  "@semantic-release/commit-analyzer": "^13.0.0",
53
53
  "@semantic-release/git": "^10.0.1",