@proef/common-ui 2.2.1 → 2.2.3

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.
@@ -36,7 +36,9 @@ const DEFAULT_TABLE_LABELS = {
36
36
  min: "Mínimo",
37
37
  max: "Máximo",
38
38
  showList: "Lista de valores",
39
- showRange: "Mín/Máx"
39
+ showRange: "Mín/Máx",
40
+ resizeColumn: "Arrastar para redimensionar · duplo clique para repor",
41
+ resetSort: "Clicar para voltar à ordem inicial"
40
42
  };
41
43
  export {
42
44
  DEFAULT_TABLE_LABELS
@@ -1 +1 @@
1
- {"version":3,"file":"labels.js","sources":["../../../../../../src/v1/components/tables/Table/labels.ts"],"sourcesContent":["/** Os textos da tabela e dos filtros. Por omissão em português; a app troca os que quiser (ex: noutra língua). */\r\nexport interface TableLabels {\r\n /** Sem linhas para mostrar (quando não há `emptyLabel`). */\r\n empty: string\r\n page: string\r\n /** Nome acessível da navegação entre páginas. */\r\n pagination: string\r\n /** O nome das linhas na contagem (`PaginatedTable`), ex: \"linhas\", \"ordens\". */\r\n rowsNoun: (count: number) => string\r\n /** Na contagem filtrada (`PaginatedTable`): \"1 de 120 ordens\". */\r\n of: string\r\n /** Cada opção do tamanho de página (`PaginatedTable`). */\r\n perPage: (size: number) => string\r\n /** Nome acessível da escolha do tamanho de página. */\r\n pageSize: string\r\n prev: string\r\n next: string\r\n apply: string\r\n cancel: string\r\n search: string\r\n noResults: string\r\n clearFilter: string\r\n clearAll: string\r\n clearGroups: string\r\n /** O \"+N\" dos chips que não cabem na barra (`PaginatedTable`), para leitores de ecrã. */\r\n moreChips: (count: number) => string\r\n /** O × de um chip de filtro ou agrupamento. */\r\n removeChip: (chip: string) => string\r\n /** O rótulo do chip de um agrupamento, antes do nome da coluna. */\r\n groupedBy: string\r\n selectAll: string\r\n selectAllFound: (count: number) => string\r\n /** Num chip de filtro com mais de dois valores escolhidos. */\r\n selectedCount: (count: number) => string\r\n loadingOptions: string\r\n filterBy: (column: string) => string\r\n groupBy: (column: string) => string\r\n ungroupBy: (column: string) => string\r\n sortAsc: string\r\n sortDesc: string\r\n sortDateAsc: string\r\n sortDateDesc: string\r\n sortNumAsc: string\r\n sortNumDesc: string\r\n dateFrom: string\r\n dateTo: string\r\n min: string\r\n max: string\r\n /** Numa coluna de números: passar do intervalo para a lista de valores. */\r\n showList: string\r\n /** Numa coluna de números: passar da lista de valores para o intervalo. */\r\n showRange: string\r\n}\r\n\r\nexport const DEFAULT_TABLE_LABELS: TableLabels = {\r\n empty: 'Sem dados',\r\n page: 'Página',\r\n pagination: 'Páginas',\r\n rowsNoun: (count) => (count === 1 ? 'linha' : 'linhas'),\r\n of: 'de',\r\n perPage: (size) => `${size} por página`,\r\n pageSize: 'Linhas por página',\r\n prev: 'Anterior',\r\n next: 'Seguinte',\r\n apply: 'Aplicar',\r\n cancel: 'Cancelar',\r\n search: 'Pesquisar…',\r\n noResults: 'Sem resultados',\r\n clearFilter: 'Limpar filtro',\r\n clearAll: 'Limpar todos',\r\n clearGroups: 'Limpar agrupamentos',\r\n moreChips: (count) => `Mais ${count} ${count === 1 ? 'filtro' : 'filtros'}`,\r\n removeChip: (chip) => `Remover ${chip}`,\r\n groupedBy: 'Agrupado por',\r\n selectAll: 'Selecionar tudo',\r\n selectAllFound: (count) => `Selecionar os ${count} encontrados`,\r\n selectedCount: (count) => `${count} sel.`,\r\n loadingOptions: 'A carregar opções de todas as páginas…',\r\n filterBy: (column) => `Filtrar ${column}`,\r\n groupBy: (column) => `Agrupar por ${column}`,\r\n ungroupBy: (column) => `Remover agrupamento por ${column}`,\r\n sortAsc: 'Ordenar A→Z',\r\n sortDesc: 'Ordenar Z→A',\r\n sortDateAsc: 'Ordenar antigo → recente',\r\n sortDateDesc: 'Ordenar recente → antigo',\r\n sortNumAsc: 'Ordenar menor → maior',\r\n sortNumDesc: 'Ordenar maior → menor',\r\n dateFrom: 'De',\r\n dateTo: 'Até',\r\n min: 'Mínimo',\r\n max: 'Máximo',\r\n showList: 'Lista de valores',\r\n showRange: 'Mín/Máx',\r\n}\r\n"],"names":[],"mappings":"AAsDO,MAAM,uBAAoC;AAAA,EAC/C,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,UAAU,CAAC,UAAW,UAAU,IAAI,UAAU;AAAA,EAC9C,IAAI;AAAA,EACJ,SAAS,CAAC,SAAS,GAAG,IAAI;AAAA,EAC1B,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAU,QAAQ,KAAK,IAAI,UAAU,IAAI,WAAW,SAAS;AAAA,EACzE,YAAY,CAAC,SAAS,WAAW,IAAI;AAAA,EACrC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,gBAAgB,CAAC,UAAU,iBAAiB,KAAK;AAAA,EACjD,eAAe,CAAC,UAAU,GAAG,KAAK;AAAA,EAClC,gBAAgB;AAAA,EAChB,UAAU,CAAC,WAAW,WAAW,MAAM;AAAA,EACvC,SAAS,CAAC,WAAW,eAAe,MAAM;AAAA,EAC1C,WAAW,CAAC,WAAW,2BAA2B,MAAM;AAAA,EACxD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,UAAU;AAAA,EACV,WAAW;AACb;"}
1
+ {"version":3,"file":"labels.js","sources":["../../../../../../src/v1/components/tables/Table/labels.ts"],"sourcesContent":["/** Os textos da tabela e dos filtros. Por omissão em português; a app troca os que quiser (ex: noutra língua). */\r\nexport interface TableLabels {\r\n /** Sem linhas para mostrar (quando não há `emptyLabel`). */\r\n empty: string\r\n page: string\r\n /** Nome acessível da navegação entre páginas. */\r\n pagination: string\r\n /** O nome das linhas na contagem (`PaginatedTable`), ex: \"linhas\", \"ordens\". */\r\n rowsNoun: (count: number) => string\r\n /** Na contagem filtrada (`PaginatedTable`): \"1 de 120 ordens\". */\r\n of: string\r\n /** Cada opção do tamanho de página (`PaginatedTable`). */\r\n perPage: (size: number) => string\r\n /** Nome acessível da escolha do tamanho de página. */\r\n pageSize: string\r\n prev: string\r\n next: string\r\n apply: string\r\n cancel: string\r\n search: string\r\n noResults: string\r\n clearFilter: string\r\n clearAll: string\r\n clearGroups: string\r\n /** O \"+N\" dos chips que não cabem na barra (`PaginatedTable`), para leitores de ecrã. */\r\n moreChips: (count: number) => string\r\n /** O × de um chip de filtro ou agrupamento. */\r\n removeChip: (chip: string) => string\r\n /** O rótulo do chip de um agrupamento, antes do nome da coluna. */\r\n groupedBy: string\r\n selectAll: string\r\n selectAllFound: (count: number) => string\r\n /** Num chip de filtro com mais de dois valores escolhidos. */\r\n selectedCount: (count: number) => string\r\n loadingOptions: string\r\n filterBy: (column: string) => string\r\n groupBy: (column: string) => string\r\n ungroupBy: (column: string) => string\r\n sortAsc: string\r\n sortDesc: string\r\n sortDateAsc: string\r\n sortDateDesc: string\r\n sortNumAsc: string\r\n sortNumDesc: string\r\n dateFrom: string\r\n dateTo: string\r\n min: string\r\n max: string\r\n /** Numa coluna de números: passar do intervalo para a lista de valores. */\r\n showList: string\r\n /** Numa coluna de números: passar da lista de valores para o intervalo. */\r\n showRange: string\r\n /** Dica da pega entre colunas (`resizableColumns`). */\r\n resizeColumn: string\r\n /** Dica do cabeçalho ordenado: um novo clique volta à ordem inicial. */\r\n resetSort: string\r\n}\r\n\r\nexport const DEFAULT_TABLE_LABELS: TableLabels = {\r\n empty: 'Sem dados',\r\n page: 'Página',\r\n pagination: 'Páginas',\r\n rowsNoun: (count) => (count === 1 ? 'linha' : 'linhas'),\r\n of: 'de',\r\n perPage: (size) => `${size} por página`,\r\n pageSize: 'Linhas por página',\r\n prev: 'Anterior',\r\n next: 'Seguinte',\r\n apply: 'Aplicar',\r\n cancel: 'Cancelar',\r\n search: 'Pesquisar…',\r\n noResults: 'Sem resultados',\r\n clearFilter: 'Limpar filtro',\r\n clearAll: 'Limpar todos',\r\n clearGroups: 'Limpar agrupamentos',\r\n moreChips: (count) => `Mais ${count} ${count === 1 ? 'filtro' : 'filtros'}`,\r\n removeChip: (chip) => `Remover ${chip}`,\r\n groupedBy: 'Agrupado por',\r\n selectAll: 'Selecionar tudo',\r\n selectAllFound: (count) => `Selecionar os ${count} encontrados`,\r\n selectedCount: (count) => `${count} sel.`,\r\n loadingOptions: 'A carregar opções de todas as páginas…',\r\n filterBy: (column) => `Filtrar ${column}`,\r\n groupBy: (column) => `Agrupar por ${column}`,\r\n ungroupBy: (column) => `Remover agrupamento por ${column}`,\r\n sortAsc: 'Ordenar A→Z',\r\n sortDesc: 'Ordenar Z→A',\r\n sortDateAsc: 'Ordenar antigo → recente',\r\n sortDateDesc: 'Ordenar recente → antigo',\r\n sortNumAsc: 'Ordenar menor → maior',\r\n sortNumDesc: 'Ordenar maior → menor',\r\n dateFrom: 'De',\r\n dateTo: 'Até',\r\n min: 'Mínimo',\r\n max: 'Máximo',\r\n showList: 'Lista de valores',\r\n showRange: 'Mín/Máx',\r\n resizeColumn: 'Arrastar para redimensionar · duplo clique para repor',\r\n resetSort: 'Clicar para voltar à ordem inicial',\r\n}\r\n"],"names":[],"mappings":"AA0DO,MAAM,uBAAoC;AAAA,EAC/C,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,UAAU,CAAC,UAAW,UAAU,IAAI,UAAU;AAAA,EAC9C,IAAI;AAAA,EACJ,SAAS,CAAC,SAAS,GAAG,IAAI;AAAA,EAC1B,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AAAA,EACV,aAAa;AAAA,EACb,WAAW,CAAC,UAAU,QAAQ,KAAK,IAAI,UAAU,IAAI,WAAW,SAAS;AAAA,EACzE,YAAY,CAAC,SAAS,WAAW,IAAI;AAAA,EACrC,WAAW;AAAA,EACX,WAAW;AAAA,EACX,gBAAgB,CAAC,UAAU,iBAAiB,KAAK;AAAA,EACjD,eAAe,CAAC,UAAU,GAAG,KAAK;AAAA,EAClC,gBAAgB;AAAA,EAChB,UAAU,CAAC,WAAW,WAAW,MAAM;AAAA,EACvC,SAAS,CAAC,WAAW,eAAe,MAAM;AAAA,EAC1C,WAAW,CAAC,WAAW,2BAA2B,MAAM;AAAA,EACxD,SAAS;AAAA,EACT,UAAU;AAAA,EACV,aAAa;AAAA,EACb,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,KAAK;AAAA,EACL,UAAU;AAAA,EACV,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AACb;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PdfPreview.js","sources":["../../../../../../src/v1/primitives/documents/PdfPreview/PdfPreview.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type { PDFDocumentProxy } from 'pdfjs-dist'\nimport { loadPdfjs } from './pdfjs'\n\nexport interface PdfPreviewProps {\n file: File\n /** Texto alternativo das páginas e mensagem quando o PDF não abre. */\n label: string\n /** Imagem da 1.ª página já renderizada pela app, para aparecer de imediato. */\n initialFirstPage?: string\n className?: string\n}\n\n// Proporção A4 vertical, usada até se saber o tamanho real da página.\nconst DEFAULT_ASPECT = 0.707\n\nasync function renderPage(pdf: PDFDocumentProxy, pageNum: number, maxSide = 1200): Promise<string> {\n const page = await pdf.getPage(pageNum)\n const base = page.getViewport({ scale: 1 })\n const scale = Math.min(3, Math.max(1, maxSide / Math.max(base.width, base.height)))\n const viewport = page.getViewport({ scale })\n const canvas = document.createElement('canvas')\n canvas.width = Math.ceil(viewport.width)\n canvas.height = Math.ceil(viewport.height)\n const ctx = canvas.getContext('2d')!\n ctx.fillStyle = '#fff'\n ctx.fillRect(0, 0, canvas.width, canvas.height)\n await page.render({ canvasContext: ctx, viewport }).promise\n return canvas.toDataURL('image/jpeg', 0.85)\n}\n\n/**\n * Pré-visualização de PDF com pdf.js: as páginas em coluna, com scroll vertical\n * e sem a barra de ferramentas do visualizador nativo (que transborda em caixas\n * estreitas). Cada página só é renderizada quando se aproxima da área visível.\n *\n * **Usado por:** [DocumentDropzone](?path=/docs/v1-components-documents-documentdropzone--docs) (quando o ficheiro é um PDF).\n */\nexport default function PdfPreview({ file, label, initialFirstPage, className = '' }: PdfPreviewProps) {\n const [pdf, setPdf] = useState<PDFDocumentProxy | null>(null)\n const [numPages, setNumPages] = useState(0)\n const [aspect, setAspect] = useState<number | null>(null)\n const [imgByPage, setImgByPage] = useState<Record<number, string>>(initialFirstPage ? { 1: initialFirstPage } : {})\n const [failed, setFailed] = useState(false)\n\n const scrollRef = useRef<HTMLDivElement>(null)\n const slotRefs = useRef<(HTMLDivElement | null)[]>([])\n const requested = useRef<Set<number>>(new Set(initialFirstPage ? [1] : []))\n\n useEffect(() => {\n let alive = true\n let opened: PDFDocumentProxy | null = null\n let idleId = 0\n setPdf(null)\n setNumPages(0)\n setAspect(null)\n setFailed(false)\n // Não semear a página 1 com initialFirstPage aqui: ao mudar de ficheiro, a\n // prop ainda traz a imagem do anterior. O efeito seguinte adota-a quando chegar.\n setImgByPage({})\n requested.current = new Set()\n slotRefs.current = []\n\n const open = async () => {\n try {\n const { getDocument } = await loadPdfjs()\n const data = new Uint8Array(await file.arrayBuffer())\n const doc = await getDocument({ data }).promise\n if (!alive) {\n doc.destroy()\n return\n }\n opened = doc\n setPdf(doc)\n setNumPages(doc.numPages)\n const { width, height } = (await doc.getPage(1)).getViewport({ scale: 1 })\n if (alive && height > 0) setAspect(width / height)\n } catch {\n if (alive) setFailed(true)\n }\n }\n\n // O parse corre na thread principal: espera que a animação de entrada acabe\n // e que a página fique livre, com um limite para nunca ficar parado.\n const timer = window.setTimeout(() => {\n if (typeof requestIdleCallback === 'function') idleId = requestIdleCallback(open, { timeout: 1200 })\n else open()\n }, 500)\n\n return () => {\n alive = false\n opened?.destroy()\n window.clearTimeout(timer)\n if (idleId && typeof cancelIdleCallback === 'function') cancelIdleCallback(idleId)\n }\n }, [file])\n\n useEffect(() => {\n if (!initialFirstPage) return\n requested.current.add(1)\n setImgByPage((cur) => (cur[1] ? cur : { ...cur, 1: initialFirstPage }))\n }, [initialFirstPage])\n\n const requestPage = useCallback(\n (p: number) => {\n if (!pdf || requested.current.has(p)) return\n requested.current.add(p)\n renderPage(pdf, p)\n .then((url) => setImgByPage((cur) => ({ ...cur, [p]: url })))\n .catch(() => {\n requested.current.delete(p)\n })\n },\n [pdf],\n )\n\n useEffect(() => {\n if (!pdf || !numPages) return\n const io = new IntersectionObserver(\n (entries) => {\n for (const e of entries) {\n if (!e.isIntersecting) continue\n requestPage(Number((e.target as HTMLElement).dataset.page))\n io.unobserve(e.target)\n }\n },\n { root: scrollRef.current, rootMargin: '400px 0px' },\n )\n slotRefs.current.forEach((el) => el && io.observe(el))\n return () => io.disconnect()\n }, [pdf, numPages, requestPage])\n\n const count = numPages || 1\n const slotAspect = aspect ?? DEFAULT_ASPECT\n\n if (failed) {\n return (\n <div className={`flex h-full w-full flex-col items-center justify-center gap-2.5 bg-card text-muted-foreground ${className}`}>\n <svg width=\"44\" height=\"44\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" aria-hidden>\n <path d=\"M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7z\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n <path d=\"M14 2v5h5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n <span className=\"text-xs\">{label}</span>\n </div>\n )\n }\n\n return (\n <div\n ref={scrollRef}\n className={`flex h-full min-h-0 w-full flex-col items-center gap-3.5 overflow-x-hidden overflow-y-auto bg-card px-4 pt-3.5 pb-[18px] [&::-webkit-scrollbar]:w-2.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-2 [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-scrollbar [&::-webkit-scrollbar-thumb]:bg-clip-padding [&::-webkit-scrollbar-thumb:hover]:bg-scrollbar-hover ${className}`}\n >\n {Array.from({ length: count }, (_, i) => {\n const p = i + 1\n const url = imgByPage[p]\n return (\n <div\n key={p}\n ref={(el) => {\n slotRefs.current[i] = el\n }}\n data-page={p}\n style={{ aspectRatio: String(slotAspect) }}\n className=\"flex w-full flex-none items-center justify-center overflow-hidden rounded border border-border bg-white shadow-page\"\n >\n {url ? (\n <img src={url} alt={`${label} — ${p}/${count}`} className=\"block h-full w-full object-contain\" />\n ) : (\n <span role=\"status\" aria-label={label} className=\"inline-block h-[22px] w-[22px] animate-spin rounded-full border-[2.5px] border-primary/20 border-t-primary\" />\n )}\n </div>\n )\n })}\n </div>\n )\n}\n"],"names":[],"mappings":";;;AAcA,MAAM,iBAAiB;AAEvB,eAAe,WAAW,KAAuB,SAAiB,UAAU,MAAuB;AACjG,QAAM,OAAO,MAAM,IAAI,QAAQ,OAAO;AACtC,QAAM,OAAO,KAAK,YAAY,EAAE,OAAO,GAAG;AAC1C,QAAM,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,KAAK,IAAI,KAAK,OAAO,KAAK,MAAM,CAAC,CAAC;AAClF,QAAM,WAAW,KAAK,YAAY,EAAE,OAAO;AAC3C,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,QAAQ,KAAK,KAAK,SAAS,KAAK;AACvC,SAAO,SAAS,KAAK,KAAK,SAAS,MAAM;AACzC,QAAM,MAAM,OAAO,WAAW,IAAI;AAClC,MAAI,YAAY;AAChB,MAAI,SAAS,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;AAC9C,QAAM,KAAK,OAAO,EAAE,eAAe,KAAK,SAAA,CAAU,EAAE;AACpD,SAAO,OAAO,UAAU,cAAc,IAAI;AAC5C;AASA,SAAwB,WAAW,EAAE,MAAM,OAAO,kBAAkB,YAAY,MAAuB;AACrG,QAAM,CAAC,KAAK,MAAM,IAAI,SAAkC,IAAI;AAC5D,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,CAAC;AAC1C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAwB,IAAI;AACxD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAiC,mBAAmB,EAAE,GAAG,iBAAA,IAAqB,EAAE;AAClH,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,YAAY,OAAuB,IAAI;AAC7C,QAAM,WAAW,OAAkC,EAAE;AACrD,QAAM,YAAY,OAAoB,IAAI,IAAI,mBAAmB,CAAC,CAAC,IAAI,CAAA,CAAE,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,QAAQ;AACZ,QAAI,SAAkC;AACtC,QAAI,SAAS;AACb,WAAO,IAAI;AACX,gBAAY,CAAC;AACb,cAAU,IAAI;AACd,cAAU,KAAK;AAGf,iBAAa,CAAA,CAAE;AACf,cAAU,8BAAc,IAAA;AACxB,aAAS,UAAU,CAAA;AAEnB,UAAM,OAAO,YAAY;AACvB,UAAI;AACF,cAAM,EAAE,gBAAgB,MAAM,UAAA;AAC9B,cAAM,OAAO,IAAI,WAAW,MAAM,KAAK,aAAa;AACpD,cAAM,MAAM,MAAM,YAAY,EAAE,KAAA,CAAM,EAAE;AACxC,YAAI,CAAC,OAAO;AACV,cAAI,QAAA;AACJ;AAAA,QACF;AACA,iBAAS;AACT,eAAO,GAAG;AACV,oBAAY,IAAI,QAAQ;AACxB,cAAM,EAAE,OAAO,OAAA,KAAY,MAAM,IAAI,QAAQ,CAAC,GAAG,YAAY,EAAE,OAAO,GAAG;AACzE,YAAI,SAAS,SAAS,EAAG,WAAU,QAAQ,MAAM;AAAA,MACnD,QAAQ;AACN,YAAI,iBAAiB,IAAI;AAAA,MAC3B;AAAA,IACF;AAIA,UAAM,QAAQ,OAAO,WAAW,MAAM;AACpC,UAAI,OAAO,wBAAwB,WAAY,UAAS,oBAAoB,MAAM,EAAE,SAAS,MAAM;AAAA,UAC9F,MAAA;AAAA,IACP,GAAG,GAAG;AAEN,WAAO,MAAM;AACX,cAAQ;AACR,cAAQ,QAAA;AACR,aAAO,aAAa,KAAK;AACzB,UAAI,UAAU,OAAO,uBAAuB,+BAA+B,MAAM;AAAA,IACnF;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,YAAU,MAAM;AACd,QAAI,CAAC,iBAAkB;AACvB,cAAU,QAAQ,IAAI,CAAC;AACvB,iBAAa,CAAC,QAAS,IAAI,CAAC,IAAI,MAAM,EAAE,GAAG,KAAK,GAAG,kBAAmB;AAAA,EACxE,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM,cAAc;AAAA,IAClB,CAAC,MAAc;AACb,UAAI,CAAC,OAAO,UAAU,QAAQ,IAAI,CAAC,EAAG;AACtC,gBAAU,QAAQ,IAAI,CAAC;AACvB,iBAAW,KAAK,CAAC,EACd,KAAK,CAAC,QAAQ,aAAa,CAAC,SAAS,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,IAAA,EAAM,CAAC,EAC3D,MAAM,MAAM;AACX,kBAAU,QAAQ,OAAO,CAAC;AAAA,MAC5B,CAAC;AAAA,IACL;AAAA,IACA,CAAC,GAAG;AAAA,EAAA;AAGN,YAAU,MAAM;AACd,QAAI,CAAC,OAAO,CAAC,SAAU;AACvB,UAAM,KAAK,IAAI;AAAA,MACb,CAAC,YAAY;AACX,mBAAW,KAAK,SAAS;AACvB,cAAI,CAAC,EAAE,eAAgB;AACvB,sBAAY,OAAQ,EAAE,OAAuB,QAAQ,IAAI,CAAC;AAC1D,aAAG,UAAU,EAAE,MAAM;AAAA,QACvB;AAAA,MACF;AAAA,MACA,EAAE,MAAM,UAAU,SAAS,YAAY,YAAA;AAAA,IAAY;AAErD,aAAS,QAAQ,QAAQ,CAAC,OAAO,MAAM,GAAG,QAAQ,EAAE,CAAC;AACrD,WAAO,MAAM,GAAG,WAAA;AAAA,EAClB,GAAG,CAAC,KAAK,UAAU,WAAW,CAAC;AAE/B,QAAM,QAAQ,YAAY;AAC1B,QAAM,aAAa,UAAU;AAE7B,MAAI,QAAQ;AACV,WACE,qBAAC,OAAA,EAAI,WAAW,iGAAiG,SAAS,IACxH,UAAA;AAAA,MAAA,qBAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,QAAO,gBAAe,aAAY,OAAM,eAAW,MAC7G,UAAA;AAAA,QAAA,oBAAC,UAAK,GAAE,8DAA6D,eAAc,SAAQ,gBAAe,SAAQ;AAAA,4BACjH,QAAA,EAAK,GAAE,aAAY,eAAc,SAAQ,gBAAe,QAAA,CAAQ;AAAA,MAAA,GACnE;AAAA,MACA,oBAAC,QAAA,EAAK,WAAU,WAAW,UAAA,MAAA,CAAM;AAAA,IAAA,GACnC;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAK;AAAA,MACL,WAAW,4fAA4f,SAAS;AAAA,MAE/gB,UAAA,MAAM,KAAK,EAAE,QAAQ,SAAS,CAAC,GAAG,MAAM;AACvC,cAAM,IAAI,IAAI;AACd,cAAM,MAAM,UAAU,CAAC;AACvB,eACE;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,KAAK,CAAC,OAAO;AACX,uBAAS,QAAQ,CAAC,IAAI;AAAA,YACxB;AAAA,YACA,aAAW;AAAA,YACX,OAAO,EAAE,aAAa,OAAO,UAAU,EAAA;AAAA,YACvC,WAAU;AAAA,YAET,UAAA,0BACE,OAAA,EAAI,KAAK,KAAK,KAAK,GAAG,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,WAAU,sCAAqC,IAE/F,oBAAC,QAAA,EAAK,MAAK,UAAS,cAAY,OAAO,WAAU,6GAAA,CAA6G;AAAA,UAAA;AAAA,UAX3J;AAAA,QAAA;AAAA,MAeX,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;"}
1
+ {"version":3,"file":"PdfPreview.js","sources":["../../../../../../src/v1/primitives/documents/PdfPreview/PdfPreview.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useState } from 'react'\r\nimport type { PDFDocumentProxy } from 'pdfjs-dist'\r\nimport { loadPdfjs } from './pdfjs'\r\n\r\nexport interface PdfPreviewProps {\r\n file: File\r\n /** Texto alternativo das páginas e mensagem quando o PDF não abre. */\r\n label: string\r\n /** Imagem da 1.ª página já renderizada pela app, para aparecer de imediato. */\r\n initialFirstPage?: string\r\n className?: string\r\n}\r\n\r\n// Proporção A4 vertical, usada até se saber o tamanho real da página.\r\nconst DEFAULT_ASPECT = 0.707\r\n\r\nasync function renderPage(pdf: PDFDocumentProxy, pageNum: number, maxSide = 1200): Promise<string> {\r\n const page = await pdf.getPage(pageNum)\r\n const base = page.getViewport({ scale: 1 })\r\n const scale = Math.min(3, Math.max(1, maxSide / Math.max(base.width, base.height)))\r\n const viewport = page.getViewport({ scale })\r\n const canvas = document.createElement('canvas')\r\n canvas.width = Math.ceil(viewport.width)\r\n canvas.height = Math.ceil(viewport.height)\r\n const ctx = canvas.getContext('2d')!\r\n ctx.fillStyle = '#fff'\r\n ctx.fillRect(0, 0, canvas.width, canvas.height)\r\n await page.render({ canvasContext: ctx, viewport }).promise\r\n return canvas.toDataURL('image/jpeg', 0.85)\r\n}\r\n\r\n/**\r\n * Pré-visualização de PDF com pdf.js: as páginas em coluna, com scroll vertical\r\n * e sem a barra de ferramentas do visualizador nativo (que transborda em caixas\r\n * estreitas). Cada página só é renderizada quando se aproxima da área visível.\r\n *\r\n * **Usado por:** [DocumentDropzone](?path=/docs/v1-components-documents-documentdropzone--docs) (quando o ficheiro é um PDF).\r\n */\r\nexport default function PdfPreview({ file, label, initialFirstPage, className = '' }: PdfPreviewProps) {\r\n const [pdf, setPdf] = useState<PDFDocumentProxy | null>(null)\r\n const [numPages, setNumPages] = useState(0)\r\n const [aspect, setAspect] = useState<number | null>(null)\r\n const [imgByPage, setImgByPage] = useState<Record<number, string>>(initialFirstPage ? { 1: initialFirstPage } : {})\r\n const [failed, setFailed] = useState(false)\r\n\r\n const scrollRef = useRef<HTMLDivElement>(null)\r\n const slotRefs = useRef<(HTMLDivElement | null)[]>([])\r\n const requested = useRef<Set<number>>(new Set(initialFirstPage ? [1] : []))\r\n\r\n useEffect(() => {\r\n let alive = true\r\n let opened: PDFDocumentProxy | null = null\r\n let idleId = 0\r\n setPdf(null)\r\n setNumPages(0)\r\n setAspect(null)\r\n setFailed(false)\r\n // Não semear a página 1 com initialFirstPage aqui: ao mudar de ficheiro, a\r\n // prop ainda traz a imagem do anterior. O efeito seguinte adota-a quando chegar.\r\n setImgByPage({})\r\n requested.current = new Set()\r\n slotRefs.current = []\r\n\r\n const open = async () => {\r\n try {\r\n const { getDocument } = await loadPdfjs()\r\n const data = new Uint8Array(await file.arrayBuffer())\r\n const doc = await getDocument({ data }).promise\r\n if (!alive) {\r\n doc.destroy()\r\n return\r\n }\r\n opened = doc\r\n setPdf(doc)\r\n setNumPages(doc.numPages)\r\n const { width, height } = (await doc.getPage(1)).getViewport({ scale: 1 })\r\n if (alive && height > 0) setAspect(width / height)\r\n } catch {\r\n if (alive) setFailed(true)\r\n }\r\n }\r\n\r\n // O parse corre na thread principal: espera que a animação de entrada acabe\r\n // e que a página fique livre, com um limite para nunca ficar parado.\r\n const timer = window.setTimeout(() => {\r\n if (typeof requestIdleCallback === 'function') idleId = requestIdleCallback(open, { timeout: 1200 })\r\n else open()\r\n }, 500)\r\n\r\n return () => {\r\n alive = false\r\n opened?.destroy()\r\n window.clearTimeout(timer)\r\n if (idleId && typeof cancelIdleCallback === 'function') cancelIdleCallback(idleId)\r\n }\r\n }, [file])\r\n\r\n useEffect(() => {\r\n if (!initialFirstPage) return\r\n requested.current.add(1)\r\n setImgByPage((cur) => (cur[1] ? cur : { ...cur, 1: initialFirstPage }))\r\n }, [initialFirstPage])\r\n\r\n const requestPage = useCallback(\r\n (p: number) => {\r\n if (!pdf || requested.current.has(p)) return\r\n requested.current.add(p)\r\n renderPage(pdf, p)\r\n .then((url) => setImgByPage((cur) => ({ ...cur, [p]: url })))\r\n .catch(() => {\r\n requested.current.delete(p)\r\n })\r\n },\r\n [pdf],\r\n )\r\n\r\n useEffect(() => {\r\n if (!pdf || !numPages) return\r\n const io = new IntersectionObserver(\r\n (entries) => {\r\n for (const e of entries) {\r\n if (!e.isIntersecting) continue\r\n requestPage(Number((e.target as HTMLElement).dataset.page))\r\n io.unobserve(e.target)\r\n }\r\n },\r\n { root: scrollRef.current, rootMargin: '400px 0px' },\r\n )\r\n slotRefs.current.forEach((el) => el && io.observe(el))\r\n return () => io.disconnect()\r\n }, [pdf, numPages, requestPage])\r\n\r\n const count = numPages || 1\r\n const slotAspect = aspect ?? DEFAULT_ASPECT\r\n\r\n if (failed) {\r\n return (\r\n <div className={`flex h-full w-full flex-col items-center justify-center gap-2.5 bg-card text-muted-foreground ${className}`}>\r\n <svg width=\"44\" height=\"44\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" aria-hidden>\r\n <path d=\"M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7z\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\r\n <path d=\"M14 2v5h5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\r\n </svg>\r\n <span className=\"text-xs\">{label}</span>\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <div\r\n ref={scrollRef}\r\n className={`flex h-full min-h-0 w-full flex-col items-center gap-3.5 overflow-x-hidden overflow-y-auto bg-card px-4 pt-3.5 pb-[18px] [&::-webkit-scrollbar]:w-2.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb]:border-2 [&::-webkit-scrollbar-thumb]:border-solid [&::-webkit-scrollbar-thumb]:border-transparent [&::-webkit-scrollbar-thumb]:bg-scrollbar [&::-webkit-scrollbar-thumb]:bg-clip-padding [&::-webkit-scrollbar-thumb:hover]:bg-scrollbar-hover ${className}`}\r\n >\r\n {Array.from({ length: count }, (_, i) => {\r\n const p = i + 1\r\n const url = imgByPage[p]\r\n return (\r\n <div\r\n key={p}\r\n ref={(el) => {\r\n slotRefs.current[i] = el\r\n }}\r\n data-page={p}\r\n style={{ aspectRatio: String(slotAspect) }}\r\n className=\"flex w-full flex-none items-center justify-center overflow-hidden rounded border border-border bg-white shadow-page\"\r\n >\r\n {url ? (\r\n <img src={url} alt={`${label} — ${p}/${count}`} className=\"block h-full w-full object-contain\" />\r\n ) : (\r\n <span role=\"status\" aria-label={label} className=\"inline-block h-[22px] w-[22px] animate-spin rounded-full border-[2.5px] border-primary/20 border-t-primary\" />\r\n )}\r\n </div>\r\n )\r\n })}\r\n </div>\r\n )\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pdfjs.js","sources":["../../../../../../src/v1/primitives/documents/PdfPreview/pdfjs.ts"],"sourcesContent":["import type * as PdfJs from 'pdfjs-dist'\n\ntype PdfJsModule = typeof PdfJs\n\nlet workerSrc: string | null = null\nlet loaded: PdfJsModule | null = null\nlet loading: Promise<PdfJsModule> | null = null\n\n/**\n * Indica ao pdf.js onde está o worker (`pdf.worker.min.mjs`) servido pela app.\n * Chamar uma vez no arranque. Se a app já define `GlobalWorkerOptions.workerSrc`\n * pela sua própria cópia do pdf.js (a mesma, quando deduplicada), não é preciso.\n */\nexport function configurePdfWorker(src: string) {\n workerSrc = src\n if (loaded) loaded.GlobalWorkerOptions.workerSrc = src\n}\n\n/** Carrega o pdf.js só quando há um PDF para mostrar; depois fica em cache. */\nexport function loadPdfjs(): Promise<PdfJsModule> {\n if (!loading) {\n loading = import('pdfjs-dist')\n .then((pdfjs) => {\n // Salvaguarda: se o pdf.js não chegar (ex: ambiente sem ele), cai no ícone.\n if (typeof pdfjs.getDocument !== 'function') throw new Error('pdfjs-dist indisponível')\n if (workerSrc) pdfjs.GlobalWorkerOptions.workerSrc = workerSrc\n loaded = pdfjs\n return pdfjs\n })\n .catch((e) => {\n loading = null\n throw e\n })\n }\n return loading\n}\n"],"names":[],"mappings":"AAIA,IAAI,YAA2B;AAC/B,IAAI,SAA6B;AACjC,IAAI,UAAuC;AAOpC,SAAS,mBAAmB,KAAa;AAC9C,cAAY;AACZ,MAAI,OAAQ,QAAO,oBAAoB,YAAY;AACrD;AAGO,SAAS,YAAkC;AAChD,MAAI,CAAC,SAAS;AACZ,cAAU,OAAO,YAAY,EAC1B,KAAK,CAAC,UAAU;AAEf,UAAI,OAAO,MAAM,gBAAgB,WAAY,OAAM,IAAI,MAAM,yBAAyB;AACtF,UAAI,UAAW,OAAM,oBAAoB,YAAY;AACrD,eAAS;AACT,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,gBAAU;AACV,YAAM;AAAA,IACR,CAAC;AAAA,EACL;AACA,SAAO;AACT;"}
1
+ {"version":3,"file":"pdfjs.js","sources":["../../../../../../src/v1/primitives/documents/PdfPreview/pdfjs.ts"],"sourcesContent":["import type * as PdfJs from 'pdfjs-dist'\r\n\r\ntype PdfJsModule = typeof PdfJs\r\n\r\nlet workerSrc: string | null = null\r\nlet loaded: PdfJsModule | null = null\r\nlet loading: Promise<PdfJsModule> | null = null\r\n\r\n/**\r\n * Indica ao pdf.js onde está o worker (`pdf.worker.min.mjs`) servido pela app.\r\n * Chamar uma vez no arranque. Se a app já define `GlobalWorkerOptions.workerSrc`\r\n * pela sua própria cópia do pdf.js (a mesma, quando deduplicada), não é preciso.\r\n */\r\nexport function configurePdfWorker(src: string) {\r\n workerSrc = src\r\n if (loaded) loaded.GlobalWorkerOptions.workerSrc = src\r\n}\r\n\r\n/** Carrega o pdf.js só quando há um PDF para mostrar; depois fica em cache. */\r\nexport function loadPdfjs(): Promise<PdfJsModule> {\r\n if (!loading) {\r\n loading = import('pdfjs-dist')\r\n .then((pdfjs) => {\r\n // Salvaguarda: se o pdf.js não chegar (ex: ambiente sem ele), cai no ícone.\r\n if (typeof pdfjs.getDocument !== 'function') throw new Error('pdfjs-dist indisponível')\r\n if (workerSrc) pdfjs.GlobalWorkerOptions.workerSrc = workerSrc\r\n loaded = pdfjs\r\n return pdfjs\r\n })\r\n .catch((e) => {\r\n loading = null\r\n throw e\r\n })\r\n }\r\n return loading\r\n}\r\n"],"names":[],"mappings":"AAIA,IAAI,YAA2B;AAC/B,IAAI,SAA6B;AACjC,IAAI,UAAuC;AAOpC,SAAS,mBAAmB,KAAa;AAC9C,cAAY;AACZ,MAAI,OAAQ,QAAO,oBAAoB,YAAY;AACrD;AAGO,SAAS,YAAkC;AAChD,MAAI,CAAC,SAAS;AACZ,cAAU,OAAO,YAAY,EAC1B,KAAK,CAAC,UAAU;AAEf,UAAI,OAAO,MAAM,gBAAgB,WAAY,OAAM,IAAI,MAAM,yBAAyB;AACtF,UAAI,UAAW,OAAM,oBAAoB,YAAY;AACrD,eAAS;AACT,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,gBAAU;AACV,YAAM;AAAA,IACR,CAAC;AAAA,EACL;AACA,SAAO;AACT;"}
@@ -1 +1 @@
1
- {"version":3,"file":"TextInput.js","sources":["../../../../../../src/v1/primitives/forms/TextInput/TextInput.tsx"],"sourcesContent":["import React, { forwardRef } from 'react'\nimport { fieldClasses, readOnlyClasses, useField } from '../field'\n\nexport interface TextInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\n /** Marca o campo a vermelho (ex: obrigatório por preencher ao submeter). */\n invalid?: boolean\n}\n\n/**\n * Campo de texto de uma linha (também data, número, etc. pelo `type`).\n *\n * Dentro de um [FormField](?path=/docs/v1-components-forms-formfield--docs) fica\n * ligado à etiqueta automaticamente.\n *\n * **Aceita os atributos HTML do [&lt;input&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input)**, com o mesmo comportamento: `value`/`onChange`, `required`, `disabled`, `readOnly`, `name`, `placeholder`, `type`, `min`/`max`, `maxLength`, `pattern`, `ref`, ...\n * Só os próprios do V1 aparecem na tabela abaixo.\n */\nconst TextInput = forwardRef<HTMLInputElement, TextInputProps>(function TextInput({ invalid, className = '', id, required, ...props }, ref) {\n const field = useField()\n return (\n <input\n ref={ref}\n id={id ?? field.id}\n required={required ?? field.required}\n aria-invalid={invalid || undefined}\n className={`h-control ${fieldClasses} ${readOnlyClasses} ${className}`}\n {...props}\n />\n )\n})\n\nexport default TextInput\n"],"names":["TextInput"],"mappings":";;;AAiBA,MAAM,YAAY,WAA6C,SAASA,WAAU,EAAE,SAAS,YAAY,IAAI,IAAI,UAAU,GAAG,MAAA,GAAS,KAAK;AAC1I,QAAM,QAAQ,SAAA;AACd,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,IAAI,MAAM,MAAM;AAAA,MAChB,UAAU,YAAY,MAAM;AAAA,MAC5B,gBAAc,WAAW;AAAA,MACzB,WAAW,aAAa,YAAY,IAAI,eAAe,IAAI,SAAS;AAAA,MACnE,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;"}
1
+ {"version":3,"file":"TextInput.js","sources":["../../../../../../src/v1/primitives/forms/TextInput/TextInput.tsx"],"sourcesContent":["import React, { forwardRef } from 'react'\r\nimport { fieldClasses, readOnlyClasses, useField } from '../field'\r\n\r\nexport interface TextInputProps extends React.InputHTMLAttributes<HTMLInputElement> {\r\n /** Marca o campo a vermelho (ex: obrigatório por preencher ao submeter). */\r\n invalid?: boolean\r\n}\r\n\r\n/**\r\n * Campo de texto de uma linha (também data, número, etc. pelo `type`).\r\n *\r\n * Dentro de um [FormField](?path=/docs/v1-components-forms-formfield--docs) fica\r\n * ligado à etiqueta automaticamente.\r\n *\r\n * **Aceita os atributos HTML do [&lt;input&gt;](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/input)**, com o mesmo comportamento: `value`/`onChange`, `required`, `disabled`, `readOnly`, `name`, `placeholder`, `type`, `min`/`max`, `maxLength`, `pattern`, `ref`, ...\r\n * Só os próprios do V1 aparecem na tabela abaixo.\r\n */\r\nconst TextInput = forwardRef<HTMLInputElement, TextInputProps>(function TextInput({ invalid, className = '', id, required, ...props }, ref) {\r\n const field = useField()\r\n return (\r\n <input\r\n ref={ref}\r\n id={id ?? field.id}\r\n required={required ?? field.required}\r\n aria-invalid={invalid || undefined}\r\n className={`h-control ${fieldClasses} ${readOnlyClasses} ${className}`}\r\n {...props}\r\n />\r\n )\r\n})\r\n\r\nexport default TextInput\r\n"],"names":["TextInput"],"mappings":";;;AAiBA,MAAM,YAAY,WAA6C,SAASA,WAAU,EAAE,SAAS,YAAY,IAAI,IAAI,UAAU,GAAG,MAAA,GAAS,KAAK;AAC1I,QAAM,QAAQ,SAAA;AACd,SACE;AAAA,IAAC;AAAA,IAAA;AAAA,MACC;AAAA,MACA,IAAI,MAAM,MAAM;AAAA,MAChB,UAAU,YAAY,MAAM;AAAA,MAC5B,gBAAc,WAAW;AAAA,MACzB,WAAW,aAAa,YAAY,IAAI,eAAe,IAAI,SAAS;AAAA,MACnE,GAAG;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;"}