@proef/common-ui 0.0.0-stage → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/assets/imagem-6ee08a37d9.png +0 -0
- package/dist/esm/assets/imagem-6fcae1b87b.png +0 -0
- package/dist/esm/index.js +324 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/legacy/assets/svgs/proef-footer-logo.svg.js +5 -0
- package/dist/esm/legacy/assets/svgs/proef-footer-logo.svg.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Acronym/Acronym.css +43 -0
- package/dist/esm/legacy/components/atoms/Acronym/Acronym.js +31 -0
- package/dist/esm/legacy/components/atoms/Acronym/Acronym.js.map +1 -0
- package/dist/esm/legacy/components/atoms/BreadCrumb/BreadCrumb.css +36 -0
- package/dist/esm/legacy/components/atoms/BreadCrumb/BreadCrumb.js +57 -0
- package/dist/esm/legacy/components/atoms/BreadCrumb/BreadCrumb.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Button/variants/ActionButton.css +218 -0
- package/dist/esm/legacy/components/atoms/Button/variants/ActionButton.js +50 -0
- package/dist/esm/legacy/components/atoms/Button/variants/ActionButton.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Button/variants/FilterButton.css +56 -0
- package/dist/esm/legacy/components/atoms/Button/variants/FilterButton.js +34 -0
- package/dist/esm/legacy/components/atoms/Button/variants/FilterButton.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Button/variants/IconButton.css +74 -0
- package/dist/esm/legacy/components/atoms/Button/variants/IconButton.js +29 -0
- package/dist/esm/legacy/components/atoms/Button/variants/IconButton.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Button/variants/MainButton.css +99 -0
- package/dist/esm/legacy/components/atoms/Button/variants/MainButton.js +36 -0
- package/dist/esm/legacy/components/atoms/Button/variants/MainButton.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Button/variants/TabButton.css +63 -0
- package/dist/esm/legacy/components/atoms/Button/variants/TabButton.js +21 -0
- package/dist/esm/legacy/components/atoms/Button/variants/TabButton.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Field/Field.css +171 -0
- package/dist/esm/legacy/components/atoms/Field/Field.js +70 -0
- package/dist/esm/legacy/components/atoms/Field/Field.js.map +1 -0
- package/dist/esm/legacy/components/atoms/IconText/IconText.css +10 -0
- package/dist/esm/legacy/components/atoms/IconText/IconText.js +25 -0
- package/dist/esm/legacy/components/atoms/IconText/IconText.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Icone/Icone.js +24 -0
- package/dist/esm/legacy/components/atoms/Icone/Icone.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Input/Input.css +12 -0
- package/dist/esm/legacy/components/atoms/Input/Input.js +28 -0
- package/dist/esm/legacy/components/atoms/Input/Input.js.map +1 -0
- package/dist/esm/legacy/components/atoms/InputData/InputData.js +25 -0
- package/dist/esm/legacy/components/atoms/InputData/InputData.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Label/Label.css +192 -0
- package/dist/esm/legacy/components/atoms/Label/Label.js +13 -0
- package/dist/esm/legacy/components/atoms/Label/Label.js.map +1 -0
- package/dist/esm/legacy/components/atoms/MultiTagPickerTag/MultiTagPickerTag.css +40 -0
- package/dist/esm/legacy/components/atoms/MultiTagPickerTag/MultiTagPickerTag.js +21 -0
- package/dist/esm/legacy/components/atoms/MultiTagPickerTag/MultiTagPickerTag.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Select/Select.css +16 -0
- package/dist/esm/legacy/components/atoms/Select/Select.js +27 -0
- package/dist/esm/legacy/components/atoms/Select/Select.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Stack/Stack.js +20 -0
- package/dist/esm/legacy/components/atoms/Stack/Stack.js.map +1 -0
- package/dist/esm/legacy/components/atoms/Switch/CustomSwitch.css +36 -0
- package/dist/esm/legacy/components/atoms/Switch/CustomSwitch.js +29 -0
- package/dist/esm/legacy/components/atoms/Switch/CustomSwitch.js.map +1 -0
- package/dist/esm/legacy/components/charts/Charts.js +349 -0
- package/dist/esm/legacy/components/charts/Charts.js.map +1 -0
- package/dist/esm/legacy/components/layout/AppLauncher/AppLauncher.js +100 -0
- package/dist/esm/legacy/components/layout/AppLauncher/AppLauncher.js.map +1 -0
- package/dist/esm/legacy/components/layout/Error/Error.css +20 -0
- package/dist/esm/legacy/components/layout/Error/Error.js +12 -0
- package/dist/esm/legacy/components/layout/Error/Error.js.map +1 -0
- package/dist/esm/legacy/components/layout/Footer/Footer.css +42 -0
- package/dist/esm/legacy/components/layout/Footer/Footer.js +23 -0
- package/dist/esm/legacy/components/layout/Footer/Footer.js.map +1 -0
- package/dist/esm/legacy/components/layout/Header/Header.css +66 -0
- package/dist/esm/legacy/components/layout/Header/Header.js +37 -0
- package/dist/esm/legacy/components/layout/Header/Header.js.map +1 -0
- package/dist/esm/legacy/components/layout/Layout/Layout.js +31 -0
- package/dist/esm/legacy/components/layout/Layout/Layout.js.map +1 -0
- package/dist/esm/legacy/components/layout/Sidebar/Sidebar.js +38 -0
- package/dist/esm/legacy/components/layout/Sidebar/Sidebar.js.map +1 -0
- package/dist/esm/legacy/components/layout/Spinner/Spinner.css +10 -0
- package/dist/esm/legacy/components/layout/Spinner/Spinner.js +19 -0
- package/dist/esm/legacy/components/layout/Spinner/Spinner.js.map +1 -0
- package/dist/esm/legacy/components/layout/TopBar/TopBar.js +34 -0
- package/dist/esm/legacy/components/layout/TopBar/TopBar.js.map +1 -0
- package/dist/esm/legacy/components/layout/TopNavLayout/TopNavLayout.js +82 -0
- package/dist/esm/legacy/components/layout/TopNavLayout/TopNavLayout.js.map +1 -0
- package/dist/esm/legacy/components/molecules/BarraValor/BarraValor.js +25 -0
- package/dist/esm/legacy/components/molecules/BarraValor/BarraValor.js.map +1 -0
- package/dist/esm/legacy/components/molecules/ColumnPicker/ColumnPicker.js +246 -0
- package/dist/esm/legacy/components/molecules/ColumnPicker/ColumnPicker.js.map +1 -0
- package/dist/esm/legacy/components/molecules/ConfirmModal/ConfirmModal.css +3 -0
- package/dist/esm/legacy/components/molecules/ConfirmModal/ConfirmModal.js +33 -0
- package/dist/esm/legacy/components/molecules/ConfirmModal/ConfirmModal.js.map +1 -0
- package/dist/esm/legacy/components/molecules/DataTable/DataTable.js +1259 -0
- package/dist/esm/legacy/components/molecules/DataTable/DataTable.js.map +1 -0
- package/dist/esm/legacy/components/molecules/FileDropzone/FileDropzone.js +68 -0
- package/dist/esm/legacy/components/molecules/FileDropzone/FileDropzone.js.map +1 -0
- package/dist/esm/legacy/components/molecules/LanguageSwitcher/LanguageSwitcher.js +96 -0
- package/dist/esm/legacy/components/molecules/LanguageSwitcher/LanguageSwitcher.js.map +1 -0
- package/dist/esm/legacy/components/molecules/Modal/Modal.css +54 -0
- package/dist/esm/legacy/components/molecules/Modal/Modal.js +64 -0
- package/dist/esm/legacy/components/molecules/Modal/Modal.js.map +1 -0
- package/dist/esm/legacy/components/molecules/MultiTagPicker/MultiTagPicker.css +97 -0
- package/dist/esm/legacy/components/molecules/MultiTagPicker/MultiTagPicker.js +113 -0
- package/dist/esm/legacy/components/molecules/MultiTagPicker/MultiTagPicker.js.map +1 -0
- package/dist/esm/legacy/components/molecules/PhotoAvatar/PhotoAvatar.js +114 -0
- package/dist/esm/legacy/components/molecules/PhotoAvatar/PhotoAvatar.js.map +1 -0
- package/dist/esm/legacy/components/molecules/SeletorPesquisa/SeletorPesquisa.js +116 -0
- package/dist/esm/legacy/components/molecules/SeletorPesquisa/SeletorPesquisa.js.map +1 -0
- package/dist/esm/legacy/components/molecules/Sidebar/Sidebar.css +69 -0
- package/dist/esm/legacy/components/molecules/Sidebar/Sidebar.js +62 -0
- package/dist/esm/legacy/components/molecules/Sidebar/Sidebar.js.map +1 -0
- package/dist/esm/legacy/components/molecules/UserAvatar/UserAvatar.js +23 -0
- package/dist/esm/legacy/components/molecules/UserAvatar/UserAvatar.js.map +1 -0
- package/dist/esm/legacy/components/organisms/GanttChart/GanttChart.js +162 -0
- package/dist/esm/legacy/components/organisms/GanttChart/GanttChart.js.map +1 -0
- package/dist/esm/legacy/components/organisms/Kanban/Kanban.js +88 -0
- package/dist/esm/legacy/components/organisms/Kanban/Kanban.js.map +1 -0
- package/dist/esm/legacy/components/organisms/LazyLoader/LazyLoader.js +87 -0
- package/dist/esm/legacy/components/organisms/LazyLoader/LazyLoader.js.map +1 -0
- package/dist/esm/legacy/components/organisms/MapaPontos/MapaPontos.js +427 -0
- package/dist/esm/legacy/components/organisms/MapaPontos/MapaPontos.js.map +1 -0
- package/dist/esm/legacy/components/organisms/PainelFiltros/PainelFiltros.js +218 -0
- package/dist/esm/legacy/components/organisms/PainelFiltros/PainelFiltros.js.map +1 -0
- package/dist/esm/legacy/components/organisms/PesquisaRapida/PesquisaRapida.js +147 -0
- package/dist/esm/legacy/components/organisms/PesquisaRapida/PesquisaRapida.js.map +1 -0
- package/dist/esm/legacy/components/organisms/Profile/Profile.css +26 -0
- package/dist/esm/legacy/components/organisms/Profile/Profile.js +26 -0
- package/dist/esm/legacy/components/organisms/Profile/Profile.js.map +1 -0
- package/dist/esm/legacy/components/organisms/RoleGuard/RoleGuard.js +79 -0
- package/dist/esm/legacy/components/organisms/RoleGuard/RoleGuard.js.map +1 -0
- package/dist/esm/legacy/components/organisms/Selector/Selector.css +87 -0
- package/dist/esm/legacy/components/organisms/Selector/Selector.js +181 -0
- package/dist/esm/legacy/components/organisms/Selector/Selector.js.map +1 -0
- package/dist/esm/legacy/components/organisms/StatusMatrix/StatusMatrix.js +115 -0
- package/dist/esm/legacy/components/organisms/StatusMatrix/StatusMatrix.js.map +1 -0
- package/dist/esm/legacy/components/ui/Avisos.js +33 -0
- package/dist/esm/legacy/components/ui/Avisos.js.map +1 -0
- package/dist/esm/legacy/components/ui/BarraAcoes.js +19 -0
- package/dist/esm/legacy/components/ui/BarraAcoes.js.map +1 -0
- package/dist/esm/legacy/components/ui/CabecalhoPagina.js +19 -0
- package/dist/esm/legacy/components/ui/CabecalhoPagina.js.map +1 -0
- package/dist/esm/legacy/components/ui/CaixaPesquisa.js +9 -0
- package/dist/esm/legacy/components/ui/CaixaPesquisa.js.map +1 -0
- package/dist/esm/legacy/components/ui/Confirmacao.js +34 -0
- package/dist/esm/legacy/components/ui/Confirmacao.js.map +1 -0
- package/dist/esm/legacy/components/ui/Escolha.js +41 -0
- package/dist/esm/legacy/components/ui/Escolha.js.map +1 -0
- package/dist/esm/legacy/components/ui/FaixaAviso.js +19 -0
- package/dist/esm/legacy/components/ui/FaixaAviso.js.map +1 -0
- package/dist/esm/legacy/components/ui/MenuAcoes.js +116 -0
- package/dist/esm/legacy/components/ui/MenuAcoes.js.map +1 -0
- package/dist/esm/legacy/components/ui/Passos.js +32 -0
- package/dist/esm/legacy/components/ui/Passos.js.map +1 -0
- package/dist/esm/legacy/components/ui/Separadores.js +17 -0
- package/dist/esm/legacy/components/ui/Separadores.js.map +1 -0
- package/dist/esm/legacy/components/ui/TextoAuto.js +33 -0
- package/dist/esm/legacy/components/ui/TextoAuto.js.map +1 -0
- package/dist/esm/legacy/components/ui/Ui.js +263 -0
- package/dist/esm/legacy/components/ui/Ui.js.map +1 -0
- package/dist/esm/legacy/components/ui/painelFlutuante.js +13 -0
- package/dist/esm/legacy/components/ui/painelFlutuante.js.map +1 -0
- package/dist/esm/legacy/constants/Colors.js +33 -0
- package/dist/esm/legacy/constants/Colors.js.map +1 -0
- package/dist/esm/legacy/constants/FontWeight.js +35 -0
- package/dist/esm/legacy/constants/FontWeight.js.map +1 -0
- package/dist/esm/legacy/contexts/apiContext.js +25 -0
- package/dist/esm/legacy/contexts/apiContext.js.map +1 -0
- package/dist/esm/legacy/contexts/authContext.js +85 -0
- package/dist/esm/legacy/contexts/authContext.js.map +1 -0
- package/dist/esm/legacy/contexts/socketContext.js +34 -0
- package/dist/esm/legacy/contexts/socketContext.js.map +1 -0
- package/dist/esm/legacy/hooks/useApi.js +62 -0
- package/dist/esm/legacy/hooks/useApi.js.map +1 -0
- package/dist/esm/legacy/pages/Error/ErrorPage.css +18 -0
- package/dist/esm/legacy/pages/Error/ErrorPage.js +50 -0
- package/dist/esm/legacy/pages/Error/ErrorPage.js.map +1 -0
- package/dist/esm/legacy/pages/Loading/Loading.css +46 -0
- package/dist/esm/legacy/pages/Loading/Loading.js +9 -0
- package/dist/esm/legacy/pages/Loading/Loading.js.map +1 -0
- package/dist/esm/legacy/pages/Login/LoginScreen.js +46 -0
- package/dist/esm/legacy/pages/Login/LoginScreen.js.map +1 -0
- package/dist/esm/legacy/pages/NotFound/NotFound.css +21 -0
- package/dist/esm/legacy/pages/NotFound/NotFound.js +24 -0
- package/dist/esm/legacy/pages/NotFound/NotFound.js.map +1 -0
- package/dist/esm/legacy/styles/themes/ButtonThemes.js +28 -0
- package/dist/esm/legacy/styles/themes/ButtonThemes.js.map +1 -0
- package/dist/esm/legacy/styles/utils/utils.js +7 -0
- package/dist/esm/legacy/styles/utils/utils.js.map +1 -0
- package/dist/esm/legacy/utils/stringUtils.js +35 -0
- package/dist/esm/legacy/utils/stringUtils.js.map +1 -0
- package/dist/esm/v1/capabilities/documents/QRScanning/scanQRCodes.js +157 -0
- package/dist/esm/v1/capabilities/documents/QRScanning/scanQRCodes.js.map +1 -0
- package/dist/esm/v1/capabilities/overlay/useFloatingPanel.js +52 -0
- package/dist/esm/v1/capabilities/overlay/useFloatingPanel.js.map +1 -0
- package/dist/esm/v1/capabilities/theme/useIsDark.js +15 -0
- package/dist/esm/v1/capabilities/theme/useIsDark.js.map +1 -0
- package/dist/esm/v1/capabilities/theme/useTheme.js +66 -0
- package/dist/esm/v1/capabilities/theme/useTheme.js.map +1 -0
- package/dist/esm/v1/components/data/Pagination/Pagination.js +66 -0
- package/dist/esm/v1/components/data/Pagination/Pagination.js.map +1 -0
- package/dist/esm/v1/components/documents/DocumentDropzone/DocumentDropzone.js +307 -0
- package/dist/esm/v1/components/documents/DocumentDropzone/DocumentDropzone.js.map +1 -0
- package/dist/esm/v1/components/feedback/Toast/Toast.js +105 -0
- package/dist/esm/v1/components/feedback/Toast/Toast.js.map +1 -0
- package/dist/esm/v1/components/forms/FormField/FormField.js +59 -0
- package/dist/esm/v1/components/forms/FormField/FormField.js.map +1 -0
- package/dist/esm/v1/components/forms/FormGrid/FormGrid.js +20 -0
- package/dist/esm/v1/components/forms/FormGrid/FormGrid.js.map +1 -0
- package/dist/esm/v1/components/layout/AppShell/AppShell.js +89 -0
- package/dist/esm/v1/components/layout/AppShell/AppShell.js.map +1 -0
- package/dist/esm/v1/components/layout/Page/Page.js +16 -0
- package/dist/esm/v1/components/layout/Page/Page.js.map +1 -0
- package/dist/esm/v1/components/layout/PageHeader/PageHeader.js +26 -0
- package/dist/esm/v1/components/layout/PageHeader/PageHeader.js.map +1 -0
- package/dist/esm/v1/components/layout/SideNav/SideNav.js +287 -0
- package/dist/esm/v1/components/layout/SideNav/SideNav.js.map +1 -0
- package/dist/esm/v1/components/layout/navTrail.js +19 -0
- package/dist/esm/v1/components/layout/navTrail.js.map +1 -0
- package/dist/esm/v1/components/lists/ListFinder/ListFinder.js +271 -0
- package/dist/esm/v1/components/lists/ListFinder/ListFinder.js.map +1 -0
- package/dist/esm/v1/components/lists/ListFinder/labels.js +18 -0
- package/dist/esm/v1/components/lists/ListFinder/labels.js.map +1 -0
- package/dist/esm/v1/components/overlays/ConfirmDialog/ConfirmDialog.js +95 -0
- package/dist/esm/v1/components/overlays/ConfirmDialog/ConfirmDialog.js.map +1 -0
- package/dist/esm/v1/components/overlays/Dialog/Dialog.js +141 -0
- package/dist/esm/v1/components/overlays/Dialog/Dialog.js.map +1 -0
- package/dist/esm/v1/components/overlays/Tooltip/Tooltip.js +98 -0
- package/dist/esm/v1/components/overlays/Tooltip/Tooltip.js.map +1 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipLayer.js +84 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipLayer.js.map +1 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipPanel.js +33 -0
- package/dist/esm/v1/components/overlays/Tooltip/TooltipPanel.js.map +1 -0
- package/dist/esm/v1/components/overlays/topLayer.js +28 -0
- package/dist/esm/v1/components/overlays/topLayer.js.map +1 -0
- package/dist/esm/v1/components/tables/PaginatedTable/PaginatedTable.js +50 -0
- package/dist/esm/v1/components/tables/PaginatedTable/PaginatedTable.js.map +1 -0
- package/dist/esm/v1/components/tables/Table/ColumnFilter.js +292 -0
- package/dist/esm/v1/components/tables/Table/ColumnFilter.js.map +1 -0
- package/dist/esm/v1/components/tables/Table/OverlayScrollbar.js +129 -0
- package/dist/esm/v1/components/tables/Table/OverlayScrollbar.js.map +1 -0
- package/dist/esm/v1/components/tables/Table/Table.js +1410 -0
- package/dist/esm/v1/components/tables/Table/Table.js.map +1 -0
- package/dist/esm/v1/components/tables/Table/labels.js +44 -0
- package/dist/esm/v1/components/tables/Table/labels.js.map +1 -0
- package/dist/esm/v1/foundations/icons/icons.js +227 -0
- package/dist/esm/v1/foundations/icons/icons.js.map +1 -0
- package/dist/esm/v1/primitives/buttons/Button/Button.js +41 -0
- package/dist/esm/v1/primitives/buttons/Button/Button.js.map +1 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/SegmentedControl.js +65 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/SegmentedControl.js.map +1 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/segmentedStyles.js +10 -0
- package/dist/esm/v1/primitives/buttons/SegmentedControl/segmentedStyles.js.map +1 -0
- package/dist/esm/v1/primitives/display/Avatar/Avatar.js +120 -0
- package/dist/esm/v1/primitives/display/Avatar/Avatar.js.map +1 -0
- package/dist/esm/v1/primitives/display/Badge/Badge.js +23 -0
- package/dist/esm/v1/primitives/display/Badge/Badge.js.map +1 -0
- package/dist/esm/v1/primitives/display/Card/Card.js +22 -0
- package/dist/esm/v1/primitives/display/Card/Card.js.map +1 -0
- package/dist/esm/v1/primitives/display/FilterChips/FilterChips.js +45 -0
- package/dist/esm/v1/primitives/display/FilterChips/FilterChips.js.map +1 -0
- package/dist/esm/v1/primitives/display/Kpi/Kpi.js +103 -0
- package/dist/esm/v1/primitives/display/Kpi/Kpi.js.map +1 -0
- package/dist/esm/v1/primitives/display/Notice/Notice.js +71 -0
- package/dist/esm/v1/primitives/display/Notice/Notice.js.map +1 -0
- package/dist/esm/v1/primitives/display/Person/Person.js +14 -0
- package/dist/esm/v1/primitives/display/Person/Person.js.map +1 -0
- package/dist/esm/v1/primitives/display/RichText/RichText.js +12 -0
- package/dist/esm/v1/primitives/display/RichText/RichText.js.map +1 -0
- package/dist/esm/v1/primitives/display/RichText/utils.js +56 -0
- package/dist/esm/v1/primitives/display/RichText/utils.js.map +1 -0
- package/dist/esm/v1/primitives/documents/PdfPreview/PdfPreview.js +137 -0
- package/dist/esm/v1/primitives/documents/PdfPreview/PdfPreview.js.map +1 -0
- package/dist/esm/v1/primitives/documents/PdfPreview/pdfjs.js +26 -0
- package/dist/esm/v1/primitives/documents/PdfPreview/pdfjs.js.map +1 -0
- package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js +37 -0
- package/dist/esm/v1/primitives/forms/Checkbox/Checkbox.js.map +1 -0
- package/dist/esm/v1/primitives/forms/DateInput/DateInput.js +150 -0
- package/dist/esm/v1/primitives/forms/DateInput/DateInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/LookupInput/LookupInput.js +37 -0
- package/dist/esm/v1/primitives/forms/LookupInput/LookupInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/RichTextEditor/RichTextEditor.js +253 -0
- package/dist/esm/v1/primitives/forms/RichTextEditor/RichTextEditor.js.map +1 -0
- package/dist/esm/v1/primitives/forms/SearchInput/SearchInput.js +43 -0
- package/dist/esm/v1/primitives/forms/SearchInput/SearchInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/SelectInput/SelectInput.js +207 -0
- package/dist/esm/v1/primitives/forms/SelectInput/SelectInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/TextArea/TextArea.js +75 -0
- package/dist/esm/v1/primitives/forms/TextArea/TextArea.js.map +1 -0
- package/dist/esm/v1/primitives/forms/TextInput/TextInput.js +21 -0
- package/dist/esm/v1/primitives/forms/TextInput/TextInput.js.map +1 -0
- package/dist/esm/v1/primitives/forms/field.js +14 -0
- package/dist/esm/v1/primitives/forms/field.js.map +1 -0
- package/dist/esm/v1/primitives/lists/ListItem/ListItem.js +73 -0
- package/dist/esm/v1/primitives/lists/ListItem/ListItem.js.map +1 -0
- package/dist/esm/v1/primitives/navigation/Tabs/Tabs.js +96 -0
- package/dist/esm/v1/primitives/navigation/Tabs/Tabs.js.map +1 -0
- package/dist/style.components.css +3 -0
- package/dist/style.css +2 -0
- package/dist/style.layered.css +2 -0
- package/dist/tailwind.css +24 -0
- package/dist/theme-boot.js +1 -0
- package/dist/theme.css +265 -0
- package/dist/tokens.css +121 -0
- package/dist/types/index.d.ts +14 -0
- package/dist/types/legacy/components/atoms/Acronym/Acronym.d.ts +11 -0
- package/dist/types/legacy/components/atoms/BreadCrumb/BreadCrumb.d.ts +9 -0
- package/dist/types/legacy/components/atoms/Button/variants/ActionButton.d.ts +14 -0
- package/dist/types/legacy/components/atoms/Button/variants/FilterButton.d.ts +12 -0
- package/dist/types/legacy/components/atoms/Button/variants/IconButton.d.ts +22 -0
- package/dist/types/legacy/components/atoms/Button/variants/MainButton.d.ts +17 -0
- package/dist/types/legacy/components/atoms/Button/variants/TabButton.d.ts +14 -0
- package/dist/types/legacy/components/atoms/Field/Field.d.ts +15 -0
- package/dist/types/legacy/components/atoms/IconText/IconText.d.ts +12 -0
- package/dist/types/legacy/components/atoms/Icone/Icone.d.ts +31 -0
- package/dist/types/legacy/components/atoms/Input/Input.d.ts +13 -0
- package/dist/types/legacy/components/atoms/InputData/InputData.d.ts +38 -0
- package/dist/types/legacy/components/atoms/Label/Label.d.ts +11 -0
- package/dist/types/legacy/components/atoms/MultiTagPickerTag/MultiTagPickerTag.d.ts +10 -0
- package/dist/types/legacy/components/atoms/SearchSelect/SearchSelect.d.ts +15 -0
- package/dist/types/legacy/components/atoms/Select/Select.d.ts +16 -0
- package/dist/types/legacy/components/atoms/Stack/Stack.d.ts +9 -0
- package/dist/types/legacy/components/atoms/Switch/CustomSwitch.d.ts +12 -0
- package/dist/types/legacy/components/charts/Charts.d.ts +149 -0
- package/dist/types/legacy/components/layout/AppLauncher/AppLauncher.d.ts +35 -0
- package/dist/types/legacy/components/layout/Error/Error.d.ts +8 -0
- package/dist/types/legacy/components/layout/Footer/Footer.d.ts +11 -0
- package/dist/types/legacy/components/layout/Header/Header.d.ts +16 -0
- package/dist/types/legacy/components/layout/Layout/Layout.d.ts +35 -0
- package/dist/types/legacy/components/layout/Sidebar/Sidebar.d.ts +56 -0
- package/dist/types/legacy/components/layout/Spinner/Spinner.d.ts +5 -0
- package/dist/types/legacy/components/layout/TopBar/TopBar.d.ts +10 -0
- package/dist/types/legacy/components/layout/TopNavLayout/TopNavLayout.d.ts +43 -0
- package/dist/types/legacy/components/molecules/BarraValor/BarraValor.d.ts +28 -0
- package/dist/types/legacy/components/molecules/ColumnPicker/ColumnPicker.d.ts +116 -0
- package/dist/types/legacy/components/molecules/ConfirmModal/ConfirmModal.d.ts +13 -0
- package/dist/types/legacy/components/molecules/DataTable/DataTable.d.ts +344 -0
- package/dist/types/legacy/components/molecules/FileDropzone/FileDropzone.d.ts +25 -0
- package/dist/types/legacy/components/molecules/LanguageSwitcher/LanguageSwitcher.d.ts +33 -0
- package/dist/types/legacy/components/molecules/Modal/Modal.d.ts +22 -0
- package/dist/types/legacy/components/molecules/MultiTagPicker/MultiTagPicker.d.ts +25 -0
- package/dist/types/legacy/components/molecules/PhotoAvatar/PhotoAvatar.d.ts +34 -0
- package/dist/types/legacy/components/molecules/SeletorPesquisa/SeletorPesquisa.d.ts +48 -0
- package/dist/types/legacy/components/molecules/Sidebar/Sidebar.d.ts +12 -0
- package/dist/types/legacy/components/molecules/UserAvatar/UserAvatar.d.ts +19 -0
- package/dist/types/legacy/components/organisms/GanttChart/GanttChart.d.ts +62 -0
- package/dist/types/legacy/components/organisms/Kanban/Kanban.d.ts +44 -0
- package/dist/types/legacy/components/organisms/LazyLoader/LazyLoader.d.ts +16 -0
- package/dist/types/legacy/components/organisms/MapaPontos/MapaPontos.d.ts +206 -0
- package/dist/types/legacy/components/organisms/PainelFiltros/PainelFiltros.d.ts +69 -0
- package/dist/types/legacy/components/organisms/PesquisaRapida/PesquisaRapida.d.ts +53 -0
- package/dist/types/legacy/components/organisms/Profile/Profile.d.ts +12 -0
- package/dist/types/legacy/components/organisms/RoleGuard/RoleGuard.d.ts +37 -0
- package/dist/types/legacy/components/organisms/Selector/Selector.d.ts +20 -0
- package/dist/types/legacy/components/organisms/StatusMatrix/StatusMatrix.d.ts +54 -0
- package/dist/types/legacy/components/ui/Avisos.d.ts +33 -0
- package/dist/types/legacy/components/ui/BarraAcoes.d.ts +19 -0
- package/dist/types/legacy/components/ui/CabecalhoPagina.d.ts +23 -0
- package/dist/types/legacy/components/ui/CaixaPesquisa.d.ts +14 -0
- package/dist/types/legacy/components/ui/Confirmacao.d.ts +24 -0
- package/dist/types/legacy/components/ui/Escolha.d.ts +35 -0
- package/dist/types/legacy/components/ui/FaixaAviso.d.ts +19 -0
- package/dist/types/legacy/components/ui/MenuAcoes.d.ts +31 -0
- package/dist/types/legacy/components/ui/Passos.d.ts +31 -0
- package/dist/types/legacy/components/ui/Separadores.d.ts +19 -0
- package/dist/types/legacy/components/ui/TextoAuto.d.ts +23 -0
- package/dist/types/legacy/components/ui/Ui.d.ts +181 -0
- package/dist/types/legacy/components/ui/painelFlutuante.d.ts +16 -0
- package/dist/types/legacy/constants/Colors.d.ts +28 -0
- package/dist/types/legacy/constants/FontWeight.d.ts +9 -0
- package/dist/types/legacy/contexts/apiContext.d.ts +10 -0
- package/dist/types/legacy/contexts/authContext.d.ts +31 -0
- package/dist/types/legacy/contexts/socketContext.d.ts +16 -0
- package/dist/types/legacy/exports/assets.d.ts +0 -0
- package/dist/types/legacy/exports/atoms.d.ts +19 -0
- package/dist/types/legacy/exports/charts.d.ts +2 -0
- package/dist/types/legacy/exports/constants.d.ts +0 -0
- package/dist/types/legacy/exports/contexts.d.ts +3 -0
- package/dist/types/legacy/exports/hooks.d.ts +4 -0
- package/dist/types/legacy/exports/layout.d.ts +14 -0
- package/dist/types/legacy/exports/molecules.d.ts +21 -0
- package/dist/types/legacy/exports/organisms.d.ts +17 -0
- package/dist/types/legacy/exports/pages.d.ts +5 -0
- package/dist/types/legacy/exports/styles.d.ts +2 -0
- package/dist/types/legacy/exports/types.d.ts +7 -0
- package/dist/types/legacy/exports/ui.d.ts +24 -0
- package/dist/types/legacy/exports/utils.d.ts +1 -0
- package/dist/types/legacy/hooks/useApi.d.ts +19 -0
- package/dist/types/legacy/pages/Error/ErrorPage.d.ts +16 -0
- package/dist/types/legacy/pages/Loading/Loading.d.ts +8 -0
- package/dist/types/legacy/pages/Login/LoginScreen.d.ts +42 -0
- package/dist/types/legacy/pages/NotFound/NotFound.d.ts +8 -0
- package/dist/types/legacy/styles/themes/ButtonThemes.d.ts +6 -0
- package/dist/types/legacy/styles/utils/utils.d.ts +2 -0
- package/dist/types/legacy/types/Fetcher.d.ts +5 -0
- package/dist/types/legacy/types/LoggedUser.d.ts +10 -0
- package/dist/types/legacy/types/SelectableElement.d.ts +6 -0
- package/dist/types/legacy/types/SidebarMenu.d.ts +12 -0
- package/dist/types/legacy/types/themes/AcronymThemes.d.ts +4 -0
- package/dist/types/legacy/types/themes/ButtonThemes.d.ts +21 -0
- package/dist/types/legacy/types/themes/CustomSwitchThemes.d.ts +4 -0
- package/dist/types/legacy/types/themes/IconTextThemes.d.ts +6 -0
- package/dist/types/legacy/utils/keycloak.d.ts +0 -0
- package/dist/types/legacy/utils/stringUtils.d.ts +6 -0
- package/dist/types/v1/capabilities/documents/QRScanning/scanQRCodes.d.ts +25 -0
- package/dist/types/v1/capabilities/overlay/useFloatingPanel.d.ts +20 -0
- package/dist/types/v1/capabilities/theme/useIsDark.d.ts +10 -0
- package/dist/types/v1/capabilities/theme/useTheme.d.ts +29 -0
- package/dist/types/v1/components/data/Pagination/Pagination.d.ts +33 -0
- package/dist/types/v1/components/documents/DocumentDropzone/DocumentDropzone.d.ts +60 -0
- package/dist/types/v1/components/feedback/Toast/Toast.d.ts +51 -0
- package/dist/types/v1/components/forms/FormField/FormField.d.ts +44 -0
- package/dist/types/v1/components/forms/FormGrid/FormGrid.d.ts +23 -0
- package/dist/types/v1/components/layout/AppShell/AppShell.d.ts +35 -0
- package/dist/types/v1/components/layout/Page/Page.d.ts +23 -0
- package/dist/types/v1/components/layout/PageHeader/PageHeader.d.ts +35 -0
- package/dist/types/v1/components/layout/SideNav/SideNav.d.ts +92 -0
- package/dist/types/v1/components/layout/navTrail.d.ts +15 -0
- package/dist/types/v1/components/lists/ListFinder/ListFinder.d.ts +86 -0
- package/dist/types/v1/components/lists/ListFinder/labels.d.ts +24 -0
- package/dist/types/v1/components/overlays/ConfirmDialog/ConfirmDialog.d.ts +59 -0
- package/dist/types/v1/components/overlays/Dialog/Dialog.d.ts +66 -0
- package/dist/types/v1/components/overlays/Tooltip/Tooltip.d.ts +34 -0
- package/dist/types/v1/components/overlays/Tooltip/TooltipLayer.d.ts +18 -0
- package/dist/types/v1/components/overlays/Tooltip/TooltipPanel.d.ts +23 -0
- package/dist/types/v1/components/overlays/topLayer.d.ts +23 -0
- package/dist/types/v1/components/tables/PaginatedTable/PaginatedTable.d.ts +41 -0
- package/dist/types/v1/components/tables/Table/ColumnFilter.d.ts +48 -0
- package/dist/types/v1/components/tables/Table/OverlayScrollbar.d.ts +34 -0
- package/dist/types/v1/components/tables/Table/Table.d.ts +250 -0
- package/dist/types/v1/components/tables/Table/labels.d.ts +54 -0
- package/dist/types/v1/foundations/icons/icons.d.ts +81 -0
- package/dist/types/v1/index.d.ts +86 -0
- package/dist/types/v1/primitives/buttons/Button/Button.d.ts +35 -0
- package/dist/types/v1/primitives/buttons/SegmentedControl/SegmentedControl.d.ts +28 -0
- package/dist/types/v1/primitives/buttons/SegmentedControl/segmentedStyles.d.ts +16 -0
- package/dist/types/v1/primitives/display/Avatar/Avatar.d.ts +30 -0
- package/dist/types/v1/primitives/display/Badge/Badge.d.ts +25 -0
- package/dist/types/v1/primitives/display/Card/Card.d.ts +22 -0
- package/dist/types/v1/primitives/display/FilterChips/FilterChips.d.ts +33 -0
- package/dist/types/v1/primitives/display/Kpi/Kpi.d.ts +68 -0
- package/dist/types/v1/primitives/display/Notice/Notice.d.ts +29 -0
- package/dist/types/v1/primitives/display/Person/Person.d.ts +15 -0
- package/dist/types/v1/primitives/display/RichText/RichText.d.ts +17 -0
- package/dist/types/v1/primitives/display/RichText/utils.d.ts +22 -0
- package/dist/types/v1/primitives/documents/PdfPreview/PdfPreview.d.ts +17 -0
- package/dist/types/v1/primitives/documents/PdfPreview/pdfjs.d.ts +11 -0
- package/dist/types/v1/primitives/forms/Checkbox/Checkbox.d.ts +25 -0
- package/dist/types/v1/primitives/forms/DateInput/DateInput.d.ts +43 -0
- package/dist/types/v1/primitives/forms/LookupInput/LookupInput.d.ts +28 -0
- package/dist/types/v1/primitives/forms/RichTextEditor/RichTextEditor.d.ts +64 -0
- package/dist/types/v1/primitives/forms/SearchInput/SearchInput.d.ts +23 -0
- package/dist/types/v1/primitives/forms/SelectInput/SelectInput.d.ts +70 -0
- package/dist/types/v1/primitives/forms/TextArea/TextArea.d.ts +40 -0
- package/dist/types/v1/primitives/forms/TextInput/TextInput.d.ts +16 -0
- package/dist/types/v1/primitives/forms/field.d.ts +22 -0
- package/dist/types/v1/primitives/lists/ListItem/ListItem.d.ts +67 -0
- package/dist/types/v1/primitives/navigation/Tabs/Tabs.d.ts +58 -0
- package/package.json +125 -6
- package/README.md +0 -3
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
function getAcronym(str) {
|
|
2
|
+
const words = str.split(" ");
|
|
3
|
+
const firstLetter = words[0] ? words[0].charAt(0).toUpperCase() : "";
|
|
4
|
+
const lastLetter = words.length > 1 ? words[words.length - 1].charAt(0).toUpperCase() : "";
|
|
5
|
+
const result = firstLetter + lastLetter;
|
|
6
|
+
return result;
|
|
7
|
+
}
|
|
8
|
+
function getFirstAndLastName(str) {
|
|
9
|
+
const words = str.split(" ");
|
|
10
|
+
let firstAndLast = "";
|
|
11
|
+
if (words.length > 0) {
|
|
12
|
+
firstAndLast += words[0];
|
|
13
|
+
if (words.length > 1) {
|
|
14
|
+
firstAndLast += " ";
|
|
15
|
+
firstAndLast += words[words.length - 1];
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return firstAndLast;
|
|
19
|
+
}
|
|
20
|
+
function normalize(string) {
|
|
21
|
+
return string.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();
|
|
22
|
+
}
|
|
23
|
+
function partialMatchWithUsername(search, username) {
|
|
24
|
+
if (search === "") return true;
|
|
25
|
+
const names = normalize(username).split(" ");
|
|
26
|
+
const searchNames = normalize(search).split(" ");
|
|
27
|
+
const matchAllNames = searchNames.every((searchName) => names.some((n) => n.includes(searchName)));
|
|
28
|
+
return matchAllNames;
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
getAcronym,
|
|
32
|
+
getFirstAndLastName,
|
|
33
|
+
partialMatchWithUsername
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=stringUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stringUtils.js","sources":["../../../../src/legacy/utils/stringUtils.ts"],"sourcesContent":["\r\n// Returns acronym from string\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport function getAcronym(str: string) {\r\n const words = str.split(' ')\r\n const firstLetter = words[0] ? words[0].charAt(0).toUpperCase() : ''\r\n const lastLetter = words.length > 1 ? words[words.length - 1].charAt(0).toUpperCase() : ''\r\n const result = firstLetter + lastLetter\r\n\r\n return result\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport function getFirstAndLastName(str: string) {\r\n const words = str.split(' ')\r\n let firstAndLast = ''\r\n\r\n if (words.length > 0) {\r\n firstAndLast += words[0]\r\n if (words.length > 1) {\r\n firstAndLast += \" \"\r\n firstAndLast += words[words.length - 1]\r\n }\r\n }\r\n\r\n return firstAndLast\r\n}\r\n\r\nfunction normalize(string: string) {\r\n return string.normalize(\"NFD\").replace(/[\\u0300-\\u036f]/g, \"\").toLowerCase()\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport function partialMatchWithUsername(search: string, username: string) {\r\n if (search === \"\") return true\r\n const names = normalize(username).split(\" \")\r\n const searchNames = normalize(search).split(\" \")\r\n\r\n const matchAllNames = searchNames.every(searchName => names.some(n => n.includes(searchName)))\r\n\r\n return matchAllNames\r\n}"],"names":[],"mappings":"AAGO,SAAS,WAAW,KAAa;AACpC,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,QAAM,cAAc,MAAM,CAAC,IAAI,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,YAAA,IAAgB;AAClE,QAAM,aAAa,MAAM,SAAS,IAAI,MAAM,MAAM,SAAS,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB;AACxF,QAAM,SAAS,cAAc;AAE7B,SAAO;AACX;AAGO,SAAS,oBAAoB,KAAa;AAC7C,QAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,MAAI,eAAe;AAEnB,MAAI,MAAM,SAAS,GAAG;AAClB,oBAAgB,MAAM,CAAC;AACvB,QAAI,MAAM,SAAS,GAAG;AAClB,sBAAgB;AAChB,sBAAgB,MAAM,MAAM,SAAS,CAAC;AAAA,IAC1C;AAAA,EACJ;AAEA,SAAO;AACX;AAEA,SAAS,UAAU,QAAgB;AAC/B,SAAO,OAAO,UAAU,KAAK,EAAE,QAAQ,oBAAoB,EAAE,EAAE,YAAA;AACnE;AAGO,SAAS,yBAAyB,QAAgB,UAAkB;AACvE,MAAI,WAAW,GAAI,QAAO;AAC1B,QAAM,QAAQ,UAAU,QAAQ,EAAE,MAAM,GAAG;AAC3C,QAAM,cAAc,UAAU,MAAM,EAAE,MAAM,GAAG;AAE/C,QAAM,gBAAgB,YAAY,MAAM,CAAA,eAAc,MAAM,KAAK,CAAA,MAAK,EAAE,SAAS,UAAU,CAAC,CAAC;AAE7F,SAAO;AACX;"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { loadPdfjs } from "../../../primitives/documents/PdfPreview/pdfjs.js";
|
|
2
|
+
let wasmUrl = null;
|
|
3
|
+
let enginesPromise = null;
|
|
4
|
+
function configureQRScanner(options) {
|
|
5
|
+
wasmUrl = options.wasmUrl;
|
|
6
|
+
}
|
|
7
|
+
function loadEngines() {
|
|
8
|
+
if (!enginesPromise) {
|
|
9
|
+
enginesPromise = Promise.all([import("qr-scanner"), import("zxing-wasm/reader"), import("@zxing/library")]).then(([qrScanner, zxingWasm, zxingJs]) => {
|
|
10
|
+
if (wasmUrl) {
|
|
11
|
+
const url = wasmUrl;
|
|
12
|
+
zxingWasm.prepareZXingModule({ overrides: { locateFile: (path, prefix) => path.endsWith(".wasm") ? url : prefix + path } });
|
|
13
|
+
}
|
|
14
|
+
return { QrScanner: qrScanner.default, readBarcodes: zxingWasm.readBarcodes, zxingJs };
|
|
15
|
+
}).catch((e) => {
|
|
16
|
+
enginesPromise = null;
|
|
17
|
+
throw e;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return enginesPromise;
|
|
21
|
+
}
|
|
22
|
+
const UPSCALE_TARGET = 800;
|
|
23
|
+
const BINARIZERS = ["LocalAverage", "GlobalHistogram", "FixedThreshold"];
|
|
24
|
+
function loadImage(file) {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const img = new Image();
|
|
27
|
+
const url = URL.createObjectURL(file);
|
|
28
|
+
img.onload = () => {
|
|
29
|
+
URL.revokeObjectURL(url);
|
|
30
|
+
resolve(img);
|
|
31
|
+
};
|
|
32
|
+
img.onerror = () => {
|
|
33
|
+
URL.revokeObjectURL(url);
|
|
34
|
+
reject(new Error("Imagem ilegível"));
|
|
35
|
+
};
|
|
36
|
+
img.src = url;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
async function drawVariant(file, contrast) {
|
|
40
|
+
const img = await loadImage(file);
|
|
41
|
+
const scale = Math.max(1, UPSCALE_TARGET / Math.min(img.naturalWidth, img.naturalHeight));
|
|
42
|
+
const canvas = document.createElement("canvas");
|
|
43
|
+
canvas.width = Math.round(img.naturalWidth * scale);
|
|
44
|
+
canvas.height = Math.round(img.naturalHeight * scale);
|
|
45
|
+
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
46
|
+
ctx.imageSmoothingEnabled = true;
|
|
47
|
+
ctx.imageSmoothingQuality = "high";
|
|
48
|
+
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
|
|
49
|
+
if (contrast) {
|
|
50
|
+
const d = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
51
|
+
const px = d.data;
|
|
52
|
+
for (let i = 0; i < px.length; i += 4) {
|
|
53
|
+
const g = 0.299 * px[i] + 0.587 * px[i + 1] + 0.114 * px[i + 2];
|
|
54
|
+
px[i] = px[i + 1] = px[i + 2] = Math.max(0, Math.min(255, 128 + contrast * (g - 128)));
|
|
55
|
+
}
|
|
56
|
+
ctx.putImageData(d, 0, 0);
|
|
57
|
+
}
|
|
58
|
+
return canvas;
|
|
59
|
+
}
|
|
60
|
+
const pixels = (canvas) => canvas.getContext("2d", { willReadFrequently: true }).getImageData(0, 0, canvas.width, canvas.height);
|
|
61
|
+
async function renderPdfFirstPage(file) {
|
|
62
|
+
const { getDocument } = await loadPdfjs();
|
|
63
|
+
const pdf = await getDocument({ data: new Uint8Array(await file.arrayBuffer()) }).promise;
|
|
64
|
+
try {
|
|
65
|
+
const page = await pdf.getPage(1);
|
|
66
|
+
const base = page.getViewport({ scale: 1 });
|
|
67
|
+
const viewport = page.getViewport({ scale: Math.min(4, Math.max(1, 2200 / Math.max(base.width, base.height))) });
|
|
68
|
+
const canvas = document.createElement("canvas");
|
|
69
|
+
canvas.width = Math.ceil(viewport.width);
|
|
70
|
+
canvas.height = Math.ceil(viewport.height);
|
|
71
|
+
const ctx = canvas.getContext("2d", { willReadFrequently: true });
|
|
72
|
+
ctx.fillStyle = "#fff";
|
|
73
|
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
74
|
+
await page.render({ canvasContext: ctx, viewport }).promise;
|
|
75
|
+
return await new Promise((resolve, reject) => canvas.toBlob((b) => b ? resolve(b) : reject(new Error("toBlob falhou")), "image/png"));
|
|
76
|
+
} finally {
|
|
77
|
+
pdf.destroy();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function scanQRCodes(file, options = {}) {
|
|
81
|
+
const until = options.until ?? (() => true);
|
|
82
|
+
const { QrScanner, readBarcodes, zxingJs } = await loadEngines();
|
|
83
|
+
let source = file;
|
|
84
|
+
if (file.type === "application/pdf") {
|
|
85
|
+
try {
|
|
86
|
+
source = await renderPdfFirstPage(file);
|
|
87
|
+
} catch {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
const codes = [];
|
|
92
|
+
const add = (text) => {
|
|
93
|
+
if (text && !codes.includes(text)) codes.push(text);
|
|
94
|
+
};
|
|
95
|
+
const done = () => codes.some(until);
|
|
96
|
+
const qrScanner = async (input) => {
|
|
97
|
+
try {
|
|
98
|
+
add((await QrScanner.scanImage(input, { returnDetailedScanResult: true })).data);
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
const zxingWasm = async (input, all = false) => {
|
|
103
|
+
for (const binarizer of BINARIZERS) {
|
|
104
|
+
try {
|
|
105
|
+
const texts = (await readBarcodes(input, { formats: ["QRCode"], tryHarder: true, tryDenoise: true, binarizer })).filter((r) => r.isValid).map((r) => r.text);
|
|
106
|
+
texts.forEach(add);
|
|
107
|
+
if (texts.length && !all) return;
|
|
108
|
+
} catch {
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const zxingJsDecode = (canvas) => {
|
|
113
|
+
try {
|
|
114
|
+
const { data, width, height } = pixels(canvas);
|
|
115
|
+
const bitmap = new zxingJs.BinaryBitmap(new zxingJs.HybridBinarizer(new zxingJs.RGBLuminanceSource(data, width, height)));
|
|
116
|
+
add(new zxingJs.MultiFormatReader().decode(bitmap).getText());
|
|
117
|
+
} catch {
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
let upscaled = null;
|
|
121
|
+
const collectRemaining = async () => {
|
|
122
|
+
await zxingWasm(source, true);
|
|
123
|
+
upscaled ??= await drawVariant(source).catch(() => null);
|
|
124
|
+
if (upscaled) await zxingWasm(pixels(upscaled), true);
|
|
125
|
+
return codes;
|
|
126
|
+
};
|
|
127
|
+
try {
|
|
128
|
+
await qrScanner(source);
|
|
129
|
+
if (done()) return collectRemaining();
|
|
130
|
+
await zxingWasm(source);
|
|
131
|
+
if (done()) return collectRemaining();
|
|
132
|
+
upscaled = await drawVariant(source);
|
|
133
|
+
await qrScanner(upscaled);
|
|
134
|
+
if (done()) return collectRemaining();
|
|
135
|
+
await zxingWasm(pixels(upscaled));
|
|
136
|
+
if (done()) return collectRemaining();
|
|
137
|
+
zxingJsDecode(upscaled);
|
|
138
|
+
if (done()) return collectRemaining();
|
|
139
|
+
for (const contrast of [2.5, 5]) {
|
|
140
|
+
const canvas = await drawVariant(source, contrast);
|
|
141
|
+
await qrScanner(canvas);
|
|
142
|
+
if (done()) return collectRemaining();
|
|
143
|
+
await zxingWasm(pixels(canvas));
|
|
144
|
+
if (done()) return collectRemaining();
|
|
145
|
+
zxingJsDecode(canvas);
|
|
146
|
+
if (done()) return collectRemaining();
|
|
147
|
+
}
|
|
148
|
+
} catch {
|
|
149
|
+
return codes;
|
|
150
|
+
}
|
|
151
|
+
return codes.length ? collectRemaining() : codes;
|
|
152
|
+
}
|
|
153
|
+
export {
|
|
154
|
+
configureQRScanner,
|
|
155
|
+
scanQRCodes
|
|
156
|
+
};
|
|
157
|
+
//# sourceMappingURL=scanQRCodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scanQRCodes.js","sources":["../../../../../../src/v1/capabilities/documents/QRScanning/scanQRCodes.ts"],"sourcesContent":["/**\n * Leitura de QR codes em imagens e PDFs, no browser.\n *\n * Só encontra os códigos e devolve o texto de cada um; o que fazer com eles\n * (ex: interpretar o QR de uma fatura) é da app.\n *\n * Adaptado de uma app interna. Os leitores\n * automáticos falham em imagens de baixa resolução (miniaturas arrastadas do\n * email ou do explorador), por isso tenta-se, por ordem do mais rápido ao mais\n * lento, três motores sobre quatro versões da imagem:\n * - motores: qr-scanner, zxing-wasm (3 estratégias de binarização) e\n * @zxing/library (o mais lento, último recurso);\n * - imagem: original, ampliada, e ampliada a cinzento com contraste ×2,5 e ×5.\n * Os PDFs são primeiro desenhados (1.ª página) e lidos como imagem.\n *\n * As bibliotecas (~1 MB, com o WebAssembly) só são carregadas na primeira leitura.\n */\nimport { loadPdfjs } from '../../../primitives/documents/PdfPreview/pdfjs'\n\nexport interface ScanQRCodesOptions {\n /**\n * Continuar a procurar até um código satisfazer esta condição (ex: ser o QR\n * de uma fatura). Um documento pode ter vários QR codes e o primeiro a ser\n * lido é arbitrário. Por omissão, pára no primeiro código encontrado.\n */\n until?: (code: string) => boolean\n}\n\nlet wasmUrl: string | null = null\nlet enginesPromise: Promise<Engines> | null = null\n\n/**\n * Indica onde está o `zxing_reader.wasm` servido pela app. Chamar uma vez no\n * arranque, antes da primeira leitura. Sem isto, o ficheiro é descarregado da\n * CDN jsDelivr (pode ser bloqueado por redes ou políticas de segurança).\n */\nexport function configureQRScanner(options: { wasmUrl: string }) {\n wasmUrl = options.wasmUrl\n}\n\ntype Engines = {\n QrScanner: typeof import('qr-scanner').default\n readBarcodes: typeof import('zxing-wasm/reader').readBarcodes\n zxingJs: typeof import('@zxing/library')\n}\n\nfunction loadEngines(): Promise<Engines> {\n if (!enginesPromise) {\n enginesPromise = Promise.all([import('qr-scanner'), import('zxing-wasm/reader'), import('@zxing/library')])\n .then(([qrScanner, zxingWasm, zxingJs]) => {\n if (wasmUrl) {\n const url = wasmUrl\n zxingWasm.prepareZXingModule({ overrides: { locateFile: (path: string, prefix: string) => (path.endsWith('.wasm') ? url : prefix + path) } })\n }\n return { QrScanner: qrScanner.default, readBarcodes: zxingWasm.readBarcodes, zxingJs }\n })\n .catch((e) => {\n enginesPromise = null\n throw e\n })\n }\n return enginesPromise\n}\n\n// Abaixo deste lado mais curto (px), a imagem é ampliada antes de ler.\nconst UPSCALE_TARGET = 800\nconst BINARIZERS = ['LocalAverage', 'GlobalHistogram', 'FixedThreshold'] as const\n\nfunction loadImage(file: Blob): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image()\n const url = URL.createObjectURL(file)\n img.onload = () => {\n URL.revokeObjectURL(url)\n resolve(img)\n }\n img.onerror = () => {\n URL.revokeObjectURL(url)\n reject(new Error('Imagem ilegível'))\n }\n img.src = url\n })\n}\n\n/** Imagem ampliada; com `contrast`, também a cinzento com o contraste esticado à volta de 128. */\nasync function drawVariant(file: Blob, contrast?: number): Promise<HTMLCanvasElement> {\n const img = await loadImage(file)\n const scale = Math.max(1, UPSCALE_TARGET / Math.min(img.naturalWidth, img.naturalHeight))\n const canvas = document.createElement('canvas')\n canvas.width = Math.round(img.naturalWidth * scale)\n canvas.height = Math.round(img.naturalHeight * scale)\n const ctx = canvas.getContext('2d', { willReadFrequently: true })!\n ctx.imageSmoothingEnabled = true\n ctx.imageSmoothingQuality = 'high'\n ctx.drawImage(img, 0, 0, canvas.width, canvas.height)\n if (contrast) {\n const d = ctx.getImageData(0, 0, canvas.width, canvas.height)\n const px = d.data\n for (let i = 0; i < px.length; i += 4) {\n const g = 0.299 * px[i] + 0.587 * px[i + 1] + 0.114 * px[i + 2]\n px[i] = px[i + 1] = px[i + 2] = Math.max(0, Math.min(255, 128 + contrast * (g - 128)))\n }\n ctx.putImageData(d, 0, 0)\n }\n return canvas\n}\n\nconst pixels = (canvas: HTMLCanvasElement) => canvas.getContext('2d', { willReadFrequently: true })!.getImageData(0, 0, canvas.width, canvas.height)\n\n/** 1.ª página do PDF como PNG, numa escala que mantém o QR legível (lado maior ≈ 2200 px). */\nasync function renderPdfFirstPage(file: File): Promise<Blob> {\n const { getDocument } = await loadPdfjs()\n const pdf = await getDocument({ data: new Uint8Array(await file.arrayBuffer()) }).promise\n try {\n const page = await pdf.getPage(1)\n const base = page.getViewport({ scale: 1 })\n const viewport = page.getViewport({ scale: Math.min(4, Math.max(1, 2200 / Math.max(base.width, base.height))) })\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', { willReadFrequently: true })!\n ctx.fillStyle = '#fff'\n ctx.fillRect(0, 0, canvas.width, canvas.height)\n await page.render({ canvasContext: ctx, viewport }).promise\n return await new Promise<Blob>((resolve, reject) => canvas.toBlob((b) => (b ? resolve(b) : reject(new Error('toBlob falhou'))), 'image/png'))\n } finally {\n pdf.destroy()\n }\n}\n\n/**\n * Lê os QR codes de uma imagem ou PDF (1.ª página).\n *\n * Devolve o texto de cada código encontrado, sem repetidos, pela ordem em que\n * foram lidos; vazio se não houver nenhum ou se o ficheiro não se puder ler.\n * Depois de encontrar o que procura, faz ainda uma passagem para recolher os\n * outros códigos da página (ex: QR do banco ao lado do QR fiscal).\n */\nexport async function scanQRCodes(file: File, options: ScanQRCodesOptions = {}): Promise<string[]> {\n const until = options.until ?? (() => true)\n const { QrScanner, readBarcodes, zxingJs } = await loadEngines()\n\n let source: Blob = file\n if (file.type === 'application/pdf') {\n try {\n source = await renderPdfFirstPage(file)\n } catch {\n return []\n }\n }\n\n const codes: string[] = []\n const add = (text: string | null | undefined) => {\n if (text && !codes.includes(text)) codes.push(text)\n }\n const done = () => codes.some(until)\n\n const qrScanner = async (input: Blob | HTMLCanvasElement) => {\n try {\n add((await QrScanner.scanImage(input, { returnDetailedScanResult: true })).data)\n } catch {\n /* nada encontrado */\n }\n }\n // O único motor que devolve todos os códigos da imagem. `all`: correr todas as\n // estratégias e juntar o que cada uma encontra (uma pode ver um código e falhar outro).\n const zxingWasm = async (input: Blob | ImageData, all = false) => {\n for (const binarizer of BINARIZERS) {\n try {\n const texts = (await readBarcodes(input, { formats: ['QRCode'], tryHarder: true, tryDenoise: true, binarizer }))\n .filter((r) => r.isValid)\n .map((r) => r.text)\n texts.forEach(add)\n if (texts.length && !all) return\n } catch {\n /* estratégia seguinte */\n }\n }\n }\n const zxingJsDecode = (canvas: HTMLCanvasElement) => {\n try {\n const { data, width, height } = pixels(canvas)\n const bitmap = new zxingJs.BinaryBitmap(new zxingJs.HybridBinarizer(new zxingJs.RGBLuminanceSource(data, width, height)))\n add(new zxingJs.MultiFormatReader().decode(bitmap).getText())\n } catch {\n /* nada encontrado */\n }\n }\n\n let upscaled: HTMLCanvasElement | null = null\n const collectRemaining = async () => {\n await zxingWasm(source, true)\n upscaled ??= await drawVariant(source).catch(() => null)\n if (upscaled) await zxingWasm(pixels(upscaled), true)\n return codes\n }\n\n try {\n // 1–2. Original: o mais rápido primeiro.\n await qrScanner(source)\n if (done()) return collectRemaining()\n await zxingWasm(source)\n if (done()) return collectRemaining()\n\n // 3. Ampliada (cores intactas): ajuda nas miniaturas.\n upscaled = await drawVariant(source)\n await qrScanner(upscaled)\n if (done()) return collectRemaining()\n await zxingWasm(pixels(upscaled))\n if (done()) return collectRemaining()\n zxingJsDecode(upscaled)\n if (done()) return collectRemaining()\n\n // 4. Ampliada a cinzento com contraste: para imagens difíceis.\n for (const contrast of [2.5, 5]) {\n const canvas = await drawVariant(source, contrast)\n await qrScanner(canvas)\n if (done()) return collectRemaining()\n await zxingWasm(pixels(canvas))\n if (done()) return collectRemaining()\n zxingJsDecode(canvas)\n if (done()) return collectRemaining()\n }\n } catch {\n // Imagem ilegível: devolve o que já tiver encontrado.\n return codes\n }\n\n return codes.length ? collectRemaining() : codes\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useState, useRef, useCallback, useLayoutEffect, useEffect } from "react";
|
|
2
|
+
const PANEL_CLASS = "fixed z-[60] min-w-[10rem] max-h-72 overflow-auto rounded-xl border border-slate-200 bg-white py-1 text-sm shadow-lg dark:border-slate-700 dark:bg-slate-900";
|
|
3
|
+
const itemClass = (active, danger = false) => `w-full flex items-center gap-2.5 px-3 py-2 text-left cursor-pointer select-none ${danger ? "text-red-600 dark:text-red-300" : "text-slate-700 dark:text-slate-200"} ${active ? "bg-slate-100 dark:bg-slate-800" : "bg-transparent hover:bg-slate-50 dark:hover:bg-slate-800"}`;
|
|
4
|
+
function useFloatingPanel(align = "left") {
|
|
5
|
+
const [open, setOpen] = useState(false);
|
|
6
|
+
const triggerRef = useRef(null);
|
|
7
|
+
const panelRef = useRef(null);
|
|
8
|
+
const [pos, setPos] = useState(null);
|
|
9
|
+
const close = useCallback(() => setOpen(false), []);
|
|
10
|
+
useLayoutEffect(() => {
|
|
11
|
+
if (!open || !triggerRef.current) {
|
|
12
|
+
setPos(null);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const r = triggerRef.current.getBoundingClientRect();
|
|
16
|
+
const height = panelRef.current?.offsetHeight ?? 240;
|
|
17
|
+
const horizontal = align === "right" ? { right: window.innerWidth - r.right } : { left: r.left };
|
|
18
|
+
const fitsBelow = r.bottom + 4 + height <= window.innerHeight - 8;
|
|
19
|
+
setPos({
|
|
20
|
+
...horizontal,
|
|
21
|
+
minWidth: r.width,
|
|
22
|
+
...fitsBelow || r.top < height ? { top: r.bottom + 4 } : { bottom: window.innerHeight - r.top + 4 }
|
|
23
|
+
});
|
|
24
|
+
}, [open, align]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (!open) return;
|
|
27
|
+
const click = (e) => {
|
|
28
|
+
const t = e.target;
|
|
29
|
+
if (!triggerRef.current?.contains(t) && !panelRef.current?.contains(t)) setOpen(false);
|
|
30
|
+
};
|
|
31
|
+
const scroll = (e) => {
|
|
32
|
+
if (!panelRef.current?.contains(e.target)) setOpen(false);
|
|
33
|
+
};
|
|
34
|
+
const resize = () => setOpen(false);
|
|
35
|
+
document.addEventListener("mousedown", click);
|
|
36
|
+
window.addEventListener("scroll", scroll, true);
|
|
37
|
+
window.addEventListener("resize", resize);
|
|
38
|
+
return () => {
|
|
39
|
+
document.removeEventListener("mousedown", click);
|
|
40
|
+
window.removeEventListener("scroll", scroll, true);
|
|
41
|
+
window.removeEventListener("resize", resize);
|
|
42
|
+
};
|
|
43
|
+
}, [open]);
|
|
44
|
+
const style = pos ?? { top: 0, left: 0, visibility: "hidden" };
|
|
45
|
+
return { open, setOpen, close, triggerRef, panelRef, style };
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
PANEL_CLASS,
|
|
49
|
+
itemClass,
|
|
50
|
+
useFloatingPanel
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=useFloatingPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFloatingPanel.js","sources":["../../../../../src/v1/capabilities/overlay/useFloatingPanel.ts"],"sourcesContent":["import { useCallback, useEffect, useLayoutEffect, useRef, useState, type CSSProperties } from 'react'\r\n\r\n/**\r\n * Aspeto comum das listas suspensas (SelectInput, MenuAcoes): cartão arredondado com sombra, nos dois temas.\r\n * Um só sítio para ficarem iguais.\r\n */\r\nexport const PANEL_CLASS =\r\n 'fixed z-[60] min-w-[10rem] max-h-72 overflow-auto rounded-xl border border-slate-200 bg-white py-1 text-sm shadow-lg dark:border-slate-700 dark:bg-slate-900'\r\n\r\n/** Item de uma lista suspensa; `active` = o que o teclado tem selecionado. */\r\nexport const itemClass = (active: boolean, danger = false) =>\r\n `w-full flex items-center gap-2.5 px-3 py-2 text-left cursor-pointer select-none ${\r\n danger ? 'text-red-600 dark:text-red-300' : 'text-slate-700 dark:text-slate-200'\r\n } ${active ? 'bg-slate-100 dark:bg-slate-800' : 'bg-transparent hover:bg-slate-50 dark:hover:bg-slate-800'}`\r\n\r\n/**\r\n * Painel flutuante preso a um botão: posição fixa (não é cortado por tabelas ou janelas com scroll), abre para\r\n * cima quando não cabe por baixo, fecha ao clicar fora, ao fazer scroll fora dele ou ao redimensionar.\r\n */\r\nexport function useFloatingPanel(align: 'left' | 'right' = 'left') {\r\n const [open, setOpen] = useState(false)\r\n const triggerRef = useRef<HTMLButtonElement>(null)\r\n const panelRef = useRef<HTMLDivElement>(null)\r\n const [pos, setPos] = useState<CSSProperties | null>(null)\r\n\r\n const close = useCallback(() => setOpen(false), [])\r\n\r\n useLayoutEffect(() => {\r\n if (!open || !triggerRef.current) {\r\n setPos(null)\r\n return\r\n }\r\n const r = triggerRef.current.getBoundingClientRect()\r\n const height = panelRef.current?.offsetHeight ?? 240\r\n const horizontal = align === 'right' ? { right: window.innerWidth - r.right } : { left: r.left }\r\n const fitsBelow = r.bottom + 4 + height <= window.innerHeight - 8\r\n setPos({\r\n ...horizontal,\r\n minWidth: r.width,\r\n ...(fitsBelow || r.top < height ? { top: r.bottom + 4 } : { bottom: window.innerHeight - r.top + 4 }),\r\n })\r\n }, [open, align])\r\n\r\n useEffect(() => {\r\n if (!open) return\r\n const click = (e: MouseEvent) => {\r\n const t = e.target as Node\r\n if (!triggerRef.current?.contains(t) && !panelRef.current?.contains(t)) setOpen(false)\r\n }\r\n const scroll = (e: Event) => {\r\n if (!panelRef.current?.contains(e.target as Node)) setOpen(false)\r\n }\r\n const resize = () => setOpen(false)\r\n document.addEventListener('mousedown', click)\r\n window.addEventListener('scroll', scroll, true)\r\n window.addEventListener('resize', resize)\r\n return () => {\r\n document.removeEventListener('mousedown', click)\r\n window.removeEventListener('scroll', scroll, true)\r\n window.removeEventListener('resize', resize)\r\n }\r\n }, [open])\r\n\r\n // Antes de medir, o painel desenha-se invisível (para se saber a altura).\r\n const style: CSSProperties = pos ?? { top: 0, left: 0, visibility: 'hidden' }\r\n return { open, setOpen, close, triggerRef, panelRef, style }\r\n}\r\n"],"names":[],"mappings":";AAMO,MAAM,cACX;AAGK,MAAM,YAAY,CAAC,QAAiB,SAAS,UAClD,mFACE,SAAS,mCAAmC,oCAC9C,IAAI,SAAS,mCAAmC,0DAA0D;AAMrG,SAAS,iBAAiB,QAA0B,QAAQ;AACjE,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,aAAa,OAA0B,IAAI;AACjD,QAAM,WAAW,OAAuB,IAAI;AAC5C,QAAM,CAAC,KAAK,MAAM,IAAI,SAA+B,IAAI;AAEzD,QAAM,QAAQ,YAAY,MAAM,QAAQ,KAAK,GAAG,CAAA,CAAE;AAElD,kBAAgB,MAAM;AACpB,QAAI,CAAC,QAAQ,CAAC,WAAW,SAAS;AAChC,aAAO,IAAI;AACX;AAAA,IACF;AACA,UAAM,IAAI,WAAW,QAAQ,sBAAA;AAC7B,UAAM,SAAS,SAAS,SAAS,gBAAgB;AACjD,UAAM,aAAa,UAAU,UAAU,EAAE,OAAO,OAAO,aAAa,EAAE,MAAA,IAAU,EAAE,MAAM,EAAE,KAAA;AAC1F,UAAM,YAAY,EAAE,SAAS,IAAI,UAAU,OAAO,cAAc;AAChE,WAAO;AAAA,MACL,GAAG;AAAA,MACH,UAAU,EAAE;AAAA,MACZ,GAAI,aAAa,EAAE,MAAM,SAAS,EAAE,KAAK,EAAE,SAAS,EAAA,IAAM,EAAE,QAAQ,OAAO,cAAc,EAAE,MAAM,EAAA;AAAA,IAAE,CACpG;AAAA,EACH,GAAG,CAAC,MAAM,KAAK,CAAC;AAEhB,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,CAAC,MAAkB;AAC/B,YAAM,IAAI,EAAE;AACZ,UAAI,CAAC,WAAW,SAAS,SAAS,CAAC,KAAK,CAAC,SAAS,SAAS,SAAS,CAAC,WAAW,KAAK;AAAA,IACvF;AACA,UAAM,SAAS,CAAC,MAAa;AAC3B,UAAI,CAAC,SAAS,SAAS,SAAS,EAAE,MAAc,WAAW,KAAK;AAAA,IAClE;AACA,UAAM,SAAS,MAAM,QAAQ,KAAK;AAClC,aAAS,iBAAiB,aAAa,KAAK;AAC5C,WAAO,iBAAiB,UAAU,QAAQ,IAAI;AAC9C,WAAO,iBAAiB,UAAU,MAAM;AACxC,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,KAAK;AAC/C,aAAO,oBAAoB,UAAU,QAAQ,IAAI;AACjD,aAAO,oBAAoB,UAAU,MAAM;AAAA,IAC7C;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAGT,QAAM,QAAuB,OAAO,EAAE,KAAK,GAAG,MAAM,GAAG,YAAY,SAAA;AACnE,SAAO,EAAE,MAAM,SAAS,OAAO,YAAY,UAAU,MAAA;AACvD;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useState, useEffect } from "react";
|
|
2
|
+
function useIsDark() {
|
|
3
|
+
const [isDark, setIsDark] = useState(() => typeof document !== "undefined" && document.documentElement.classList.contains("dark"));
|
|
4
|
+
useEffect(() => {
|
|
5
|
+
const el = document.documentElement;
|
|
6
|
+
const obs = new MutationObserver(() => setIsDark(el.classList.contains("dark")));
|
|
7
|
+
obs.observe(el, { attributes: true, attributeFilter: ["class"] });
|
|
8
|
+
return () => obs.disconnect();
|
|
9
|
+
}, []);
|
|
10
|
+
return isDark;
|
|
11
|
+
}
|
|
12
|
+
export {
|
|
13
|
+
useIsDark
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=useIsDark.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useIsDark.js","sources":["../../../../../src/v1/capabilities/theme/useIsDark.ts"],"sourcesContent":["import { useEffect, useState } from 'react'\r\n\r\n/**\r\n * Se a app está em escuro agora (a classe `.dark` no `<html>`), e muda quando o\r\n * tema muda.\r\n *\r\n * Para o que não pode usar o `dark:` do Tailwind e precisa das cores em\r\n * JavaScript: gráficos, `<iframe>`, SVG com cores por props. O componente volta\r\n * a desenhar quando o tema muda.\r\n */\r\nexport function useIsDark(): boolean {\r\n const [isDark, setIsDark] = useState(() => typeof document !== 'undefined' && document.documentElement.classList.contains('dark'))\r\n useEffect(() => {\r\n const el = document.documentElement\r\n const obs = new MutationObserver(() => setIsDark(el.classList.contains('dark')))\r\n obs.observe(el, { attributes: true, attributeFilter: ['class'] })\r\n return () => obs.disconnect()\r\n }, [])\r\n return isDark\r\n}\r\n\r\nexport default useIsDark\r\n"],"names":[],"mappings":";AAUO,SAAS,YAAqB;AACnC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,MAAM,OAAO,aAAa,eAAe,SAAS,gBAAgB,UAAU,SAAS,MAAM,CAAC;AACjI,YAAU,MAAM;AACd,UAAM,KAAK,SAAS;AACpB,UAAM,MAAM,IAAI,iBAAiB,MAAM,UAAU,GAAG,UAAU,SAAS,MAAM,CAAC,CAAC;AAC/E,QAAI,QAAQ,IAAI,EAAE,YAAY,MAAM,iBAAiB,CAAC,OAAO,GAAG;AAChE,WAAO,MAAM,IAAI,WAAA;AAAA,EACnB,GAAG,CAAA,CAAE;AACL,SAAO;AACT;"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { useState, useEffect, useCallback } from "react";
|
|
2
|
+
const THEME_STORAGE_KEY = "theme";
|
|
3
|
+
const LEGACY_KEY = "proef-theme";
|
|
4
|
+
const isTheme = (v) => v === "light" || v === "dark" || v === "system";
|
|
5
|
+
function readStored() {
|
|
6
|
+
try {
|
|
7
|
+
const v = localStorage.getItem(THEME_STORAGE_KEY);
|
|
8
|
+
if (isTheme(v)) return v;
|
|
9
|
+
const old = localStorage.getItem(LEGACY_KEY);
|
|
10
|
+
return isTheme(old) ? old : null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function persist(theme) {
|
|
16
|
+
try {
|
|
17
|
+
localStorage.setItem(THEME_STORAGE_KEY, theme);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const systemPrefersDark = () => typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
22
|
+
function applyTheme(theme) {
|
|
23
|
+
if (typeof document === "undefined") return;
|
|
24
|
+
document.documentElement.classList.toggle("dark", theme === "dark" || theme === "system" && systemPrefersDark());
|
|
25
|
+
}
|
|
26
|
+
const themeBootScript = `(function(){try{var k='${THEME_STORAGE_KEY}',o='${LEGACY_KEY}',v=localStorage.getItem(k)||localStorage.getItem(o)||'system';if(v==='dark'||(v==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches))document.documentElement.classList.add('dark')}catch(e){}})();`;
|
|
27
|
+
const ORDER = ["system", "light", "dark"];
|
|
28
|
+
function useTheme() {
|
|
29
|
+
const [theme, setThemeState] = useState(() => readStored() ?? "system");
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
applyTheme(theme);
|
|
32
|
+
}, [theme]);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (theme !== "system" || typeof window === "undefined" || !window.matchMedia) return;
|
|
35
|
+
const mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
36
|
+
const onChange = () => applyTheme("system");
|
|
37
|
+
mq.addEventListener("change", onChange);
|
|
38
|
+
return () => mq.removeEventListener("change", onChange);
|
|
39
|
+
}, [theme]);
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const onStorage = (e) => {
|
|
42
|
+
if (e.key === THEME_STORAGE_KEY) setThemeState(readStored() ?? "system");
|
|
43
|
+
};
|
|
44
|
+
window.addEventListener("storage", onStorage);
|
|
45
|
+
return () => window.removeEventListener("storage", onStorage);
|
|
46
|
+
}, []);
|
|
47
|
+
const setTheme = useCallback((t) => {
|
|
48
|
+
persist(t);
|
|
49
|
+
setThemeState(t);
|
|
50
|
+
}, []);
|
|
51
|
+
const cycle = useCallback(() => {
|
|
52
|
+
setThemeState((prev) => {
|
|
53
|
+
const next = ORDER[(ORDER.indexOf(prev) + 1) % ORDER.length];
|
|
54
|
+
persist(next);
|
|
55
|
+
return next;
|
|
56
|
+
});
|
|
57
|
+
}, []);
|
|
58
|
+
return { theme, setTheme, cycle };
|
|
59
|
+
}
|
|
60
|
+
export {
|
|
61
|
+
THEME_STORAGE_KEY,
|
|
62
|
+
applyTheme,
|
|
63
|
+
themeBootScript,
|
|
64
|
+
useTheme
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=useTheme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useTheme.js","sources":["../../../../../src/v1/capabilities/theme/useTheme.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\r\n\r\nexport type Theme = 'light' | 'dark' | 'system'\r\n\r\n/** Chave da escolha no localStorage. A mesma nos portais (Tickets, AuditoriasIT). */\r\nexport const THEME_STORAGE_KEY = 'theme'\r\n/** Chave antiga do `useTheme` legacy: lida só quando a nova ainda não existe. */\r\nconst LEGACY_KEY = 'proef-theme'\r\n\r\nconst isTheme = (v: string | null): v is Theme => v === 'light' || v === 'dark' || v === 'system'\r\n\r\n/** A escolha guardada, ou `null` se não houver (ou o storage estiver bloqueado). */\r\nfunction readStored(): Theme | null {\r\n try {\r\n const v = localStorage.getItem(THEME_STORAGE_KEY)\r\n if (isTheme(v)) return v\r\n const old = localStorage.getItem(LEGACY_KEY)\r\n return isTheme(old) ? old : null\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nfunction persist(theme: Theme) {\r\n try {\r\n localStorage.setItem(THEME_STORAGE_KEY, theme)\r\n } catch {\r\n // Sem storage (ex: janela privada): o tema aplica-se só nesta sessão.\r\n }\r\n}\r\n\r\nconst systemPrefersDark = () => typeof window !== 'undefined' && window.matchMedia?.('(prefers-color-scheme: dark)').matches\r\n\r\n/** Põe ou tira a classe `.dark` no `<html>`: é a ela que os componentes e os tokens reagem. */\r\nexport function applyTheme(theme: Theme) {\r\n if (typeof document === 'undefined') return\r\n document.documentElement.classList.toggle('dark', theme === 'dark' || (theme === 'system' && systemPrefersDark()))\r\n}\r\n\r\n/**\r\n * Script para pôr no `<head>` do `index.html`, antes do CSS: aplica o tema\r\n * guardado antes da primeira pintura (sem o clarão branco ao abrir em escuro).\r\n *\r\n * O build também o põe em `dist/theme-boot.js`, para a app o injetar no\r\n * `index.html` sem o copiar (ex: num plugin `transformIndexHtml` do Vite).\r\n */\r\nexport const themeBootScript = `(function(){try{var k='${THEME_STORAGE_KEY}',o='${LEGACY_KEY}',v=localStorage.getItem(k)||localStorage.getItem(o)||'system';if(v==='dark'||(v==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches))document.documentElement.classList.add('dark')}catch(e){}})();`\r\n\r\nconst ORDER: Theme[] = ['system', 'light', 'dark']\r\n\r\n/**\r\n * Tema da app: claro, escuro ou o do sistema. Guarda a escolha (sozinho, a cada\r\n * mudança), aplica a classe `.dark` no `<html>`, segue o sistema em `system` e\r\n * acompanha a escolha feita noutro separador.\r\n *\r\n * const { theme, setTheme } = useTheme()\r\n * <AppShell theme={theme} onThemeChange={setTheme} …/>\r\n *\r\n * Para não haver clarão ao abrir, pôr o `themeBootScript` no `index.html`.\r\n */\r\nexport function useTheme(): { theme: Theme; setTheme: (t: Theme) => void; cycle: () => void } {\r\n const [theme, setThemeState] = useState<Theme>(() => readStored() ?? 'system')\r\n\r\n useEffect(() => {\r\n applyTheme(theme)\r\n }, [theme])\r\n\r\n // Em `system`, segue as mudanças do sistema ao vivo.\r\n useEffect(() => {\r\n if (theme !== 'system' || typeof window === 'undefined' || !window.matchMedia) return\r\n const mq = window.matchMedia('(prefers-color-scheme: dark)')\r\n const onChange = () => applyTheme('system')\r\n mq.addEventListener('change', onChange)\r\n return () => mq.removeEventListener('change', onChange)\r\n }, [theme])\r\n\r\n // A escolha feita noutro separador ou janela.\r\n useEffect(() => {\r\n const onStorage = (e: StorageEvent) => {\r\n if (e.key === THEME_STORAGE_KEY) setThemeState(readStored() ?? 'system')\r\n }\r\n window.addEventListener('storage', onStorage)\r\n return () => window.removeEventListener('storage', onStorage)\r\n }, [])\r\n\r\n const setTheme = useCallback((t: Theme) => {\r\n persist(t)\r\n setThemeState(t)\r\n }, [])\r\n\r\n const cycle = useCallback(() => {\r\n setThemeState((prev) => {\r\n const next = ORDER[(ORDER.indexOf(prev) + 1) % ORDER.length]\r\n persist(next)\r\n return next\r\n })\r\n }, [])\r\n\r\n return { theme, setTheme, cycle }\r\n}\r\n\r\nexport default useTheme\r\n"],"names":[],"mappings":";AAKO,MAAM,oBAAoB;AAEjC,MAAM,aAAa;AAEnB,MAAM,UAAU,CAAC,MAAiC,MAAM,WAAW,MAAM,UAAU,MAAM;AAGzF,SAAS,aAA2B;AAClC,MAAI;AACF,UAAM,IAAI,aAAa,QAAQ,iBAAiB;AAChD,QAAI,QAAQ,CAAC,EAAG,QAAO;AACvB,UAAM,MAAM,aAAa,QAAQ,UAAU;AAC3C,WAAO,QAAQ,GAAG,IAAI,MAAM;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,QAAQ,OAAc;AAC7B,MAAI;AACF,iBAAa,QAAQ,mBAAmB,KAAK;AAAA,EAC/C,QAAQ;AAAA,EAER;AACF;AAEA,MAAM,oBAAoB,MAAM,OAAO,WAAW,eAAe,OAAO,aAAa,8BAA8B,EAAE;AAG9G,SAAS,WAAW,OAAc;AACvC,MAAI,OAAO,aAAa,YAAa;AACrC,WAAS,gBAAgB,UAAU,OAAO,QAAQ,UAAU,UAAW,UAAU,YAAY,mBAAoB;AACnH;AASO,MAAM,kBAAkB,0BAA0B,iBAAiB,QAAQ,UAAU;AAE5F,MAAM,QAAiB,CAAC,UAAU,SAAS,MAAM;AAY1C,SAAS,WAA8E;AAC5F,QAAM,CAAC,OAAO,aAAa,IAAI,SAAgB,MAAM,WAAA,KAAgB,QAAQ;AAE7E,YAAU,MAAM;AACd,eAAW,KAAK;AAAA,EAClB,GAAG,CAAC,KAAK,CAAC;AAGV,YAAU,MAAM;AACd,QAAI,UAAU,YAAY,OAAO,WAAW,eAAe,CAAC,OAAO,WAAY;AAC/E,UAAM,KAAK,OAAO,WAAW,8BAA8B;AAC3D,UAAM,WAAW,MAAM,WAAW,QAAQ;AAC1C,OAAG,iBAAiB,UAAU,QAAQ;AACtC,WAAO,MAAM,GAAG,oBAAoB,UAAU,QAAQ;AAAA,EACxD,GAAG,CAAC,KAAK,CAAC;AAGV,YAAU,MAAM;AACd,UAAM,YAAY,CAAC,MAAoB;AACrC,UAAI,EAAE,QAAQ,kBAAmB,eAAc,WAAA,KAAgB,QAAQ;AAAA,IACzE;AACA,WAAO,iBAAiB,WAAW,SAAS;AAC5C,WAAO,MAAM,OAAO,oBAAoB,WAAW,SAAS;AAAA,EAC9D,GAAG,CAAA,CAAE;AAEL,QAAM,WAAW,YAAY,CAAC,MAAa;AACzC,YAAQ,CAAC;AACT,kBAAc,CAAC;AAAA,EACjB,GAAG,CAAA,CAAE;AAEL,QAAM,QAAQ,YAAY,MAAM;AAC9B,kBAAc,CAAC,SAAS;AACtB,YAAM,OAAO,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,MAAM,MAAM;AAC3D,cAAQ,IAAI;AACZ,aAAO;AAAA,IACT,CAAC;AAAA,EACH,GAAG,CAAA,CAAE;AAEL,SAAO,EAAE,OAAO,UAAU,MAAA;AAC5B;"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
import Button from "../../../primitives/buttons/Button/Button.js";
|
|
3
|
+
import { SelectInput } from "../../../primitives/forms/SelectInput/SelectInput.js";
|
|
4
|
+
const DEFAULT_PAGINATION_LABELS = {
|
|
5
|
+
page: "Page {page} of {pages}",
|
|
6
|
+
total: "{count} results",
|
|
7
|
+
perPage: "Per page",
|
|
8
|
+
prev: "Previous",
|
|
9
|
+
next: "Next"
|
|
10
|
+
};
|
|
11
|
+
function ChevronLeft() {
|
|
12
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, viewBox: "0 0 24 24", width: 13, height: 13, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "m15 18-6-6 6-6" }) });
|
|
13
|
+
}
|
|
14
|
+
function ChevronRight() {
|
|
15
|
+
return /* @__PURE__ */ jsx("svg", { "aria-hidden": true, viewBox: "0 0 24 24", width: 12, height: 12, fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
|
|
16
|
+
}
|
|
17
|
+
function Pagination({
|
|
18
|
+
page,
|
|
19
|
+
pages,
|
|
20
|
+
onPageChange,
|
|
21
|
+
total,
|
|
22
|
+
pageSize,
|
|
23
|
+
pageSizeOptions,
|
|
24
|
+
onPageSizeChange,
|
|
25
|
+
labels,
|
|
26
|
+
className = ""
|
|
27
|
+
}) {
|
|
28
|
+
const L = { ...DEFAULT_PAGINATION_LABELS, ...labels };
|
|
29
|
+
const totalPaginas = Math.max(1, pages);
|
|
30
|
+
const opcoes = pageSizeOptions && pageSize != null ? [.../* @__PURE__ */ new Set([...pageSizeOptions, pageSize])].sort((a, b) => a - b) : [];
|
|
31
|
+
return /* @__PURE__ */ jsxs("nav", { "aria-label": L.page.replace("{page}", String(page)).replace("{pages}", String(totalPaginas)), className: `flex flex-wrap items-center justify-between gap-2 ${className}`, children: [
|
|
32
|
+
/* @__PURE__ */ jsxs("span", { className: "text-[10px] font-black uppercase tracking-widest text-muted-foreground", children: [
|
|
33
|
+
total != null && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
34
|
+
L.total.replace("{count}", total.toLocaleString()),
|
|
35
|
+
" · "
|
|
36
|
+
] }),
|
|
37
|
+
L.page.replace("{page}", String(page)).replace("{pages}", String(totalPaginas))
|
|
38
|
+
] }),
|
|
39
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [
|
|
40
|
+
opcoes.length > 0 && onPageSizeChange && /* @__PURE__ */ jsxs("label", { className: "mr-2 flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest text-muted-foreground", children: [
|
|
41
|
+
L.perPage,
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
SelectInput,
|
|
44
|
+
{
|
|
45
|
+
"aria-label": L.perPage,
|
|
46
|
+
value: String(pageSize),
|
|
47
|
+
onChange: (e) => onPageSizeChange(Number(e.target.value)),
|
|
48
|
+
className: "w-20 normal-case tracking-normal font-normal",
|
|
49
|
+
children: opcoes.map((n) => /* @__PURE__ */ jsx("option", { value: n, children: n }, n))
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsx(Button, { variant: "secondary", size: "sm", icon: /* @__PURE__ */ jsx(ChevronLeft, {}), disabled: page <= 1, onClick: () => onPageChange(page - 1), children: L.prev }),
|
|
54
|
+
/* @__PURE__ */ jsxs(Button, { variant: "secondary", size: "sm", disabled: page >= totalPaginas, onClick: () => onPageChange(page + 1), children: [
|
|
55
|
+
L.next,
|
|
56
|
+
/* @__PURE__ */ jsx(ChevronRight, {})
|
|
57
|
+
] })
|
|
58
|
+
] })
|
|
59
|
+
] });
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
DEFAULT_PAGINATION_LABELS,
|
|
63
|
+
Pagination,
|
|
64
|
+
Pagination as default
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=Pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pagination.js","sources":["../../../../../../src/v1/components/data/Pagination/Pagination.tsx"],"sourcesContent":["import React from 'react'\r\nimport Button from '../../../primitives/buttons/Button/Button'\r\nimport SelectInput from '../../../primitives/forms/SelectInput/SelectInput'\r\n\r\nexport interface PaginationLabels {\r\n /** \"{page}\" e \"{pages}\" são substituídos (ex: \"Página {page} de {pages}\"). */\r\n page: string\r\n /** \"{count}\" é substituído pelo total de registos (ex: \"{count} resultados\"). */\r\n total: string\r\n perPage: string\r\n prev: string\r\n next: string\r\n}\r\n\r\nexport const DEFAULT_PAGINATION_LABELS: PaginationLabels = {\r\n page: 'Page {page} of {pages}',\r\n total: '{count} results',\r\n perPage: 'Per page',\r\n prev: 'Previous',\r\n next: 'Next',\r\n}\r\n\r\nexport interface PaginationProps {\r\n /** Página atual, a contar de 1. */\r\n page: number\r\n /** Número de páginas. */\r\n pages: number\r\n onPageChange: (page: number) => void\r\n /** Total de registos (mostrado à esquerda). */\r\n total?: number\r\n /** Registos por página e as opções do seletor (sem opções, não há seletor). */\r\n pageSize?: number\r\n pageSizeOptions?: number[]\r\n onPageSizeChange?: (size: number) => void\r\n labels?: Partial<PaginationLabels>\r\n className?: string\r\n}\r\n\r\nfunction ChevronLeft() {\r\n return (\r\n <svg aria-hidden viewBox=\"0 0 24 24\" width={13} height={13} fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m15 18-6-6 6-6\" />\r\n </svg>\r\n )\r\n}\r\n\r\nfunction ChevronRight() {\r\n return (\r\n <svg aria-hidden viewBox=\"0 0 24 24\" width={12} height={12} fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\r\n <path d=\"m9 18 6-6-6-6\" />\r\n </svg>\r\n )\r\n}\r\n\r\n/**\r\n * Paginação por baixo de uma lista: \"Página 1 de 4\", o total, quantos por página e\r\n * Anterior/Seguinte. É a mesma que a `DataTable` mostra; usar esta quando a app pagina\r\n * no servidor (a tabela recebe só a página atual).\r\n */\r\nexport default function Pagination({\r\n page,\r\n pages,\r\n onPageChange,\r\n total,\r\n pageSize,\r\n pageSizeOptions,\r\n onPageSizeChange,\r\n labels,\r\n className = '',\r\n}: PaginationProps) {\r\n const L = { ...DEFAULT_PAGINATION_LABELS, ...labels }\r\n const totalPaginas = Math.max(1, pages)\r\n const opcoes = pageSizeOptions && pageSize != null ? [...new Set([...pageSizeOptions, pageSize])].sort((a, b) => a - b) : []\r\n return (\r\n <nav aria-label={L.page.replace('{page}', String(page)).replace('{pages}', String(totalPaginas))} className={`flex flex-wrap items-center justify-between gap-2 ${className}`}>\r\n <span className=\"text-[10px] font-black uppercase tracking-widest text-muted-foreground\">\r\n {total != null && <>{L.total.replace('{count}', total.toLocaleString())} · </>}\r\n {L.page.replace('{page}', String(page)).replace('{pages}', String(totalPaginas))}\r\n </span>\r\n <div className=\"flex flex-wrap items-center gap-1.5\">\r\n {opcoes.length > 0 && onPageSizeChange && (\r\n <label className=\"mr-2 flex items-center gap-1.5 text-[10px] font-black uppercase tracking-widest text-muted-foreground\">\r\n {L.perPage}\r\n <SelectInput\r\n aria-label={L.perPage}\r\n value={String(pageSize)}\r\n onChange={(e) => onPageSizeChange(Number(e.target.value))}\r\n className=\"w-20 normal-case tracking-normal font-normal\"\r\n >\r\n {opcoes.map((n) => (\r\n <option key={n} value={n}>\r\n {n}\r\n </option>\r\n ))}\r\n </SelectInput>\r\n </label>\r\n )}\r\n <Button variant=\"secondary\" size=\"sm\" icon={<ChevronLeft />} disabled={page <= 1} onClick={() => onPageChange(page - 1)}>\r\n {L.prev}\r\n </Button>\r\n <Button variant=\"secondary\" size=\"sm\" disabled={page >= totalPaginas} onClick={() => onPageChange(page + 1)}>\r\n {L.next}\r\n <ChevronRight />\r\n </Button>\r\n </div>\r\n </nav>\r\n )\r\n}\r\n\r\nexport { Pagination }\r\n"],"names":[],"mappings":";;;AAcO,MAAM,4BAA8C;AAAA,EACzD,MAAM;AAAA,EACN,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,MAAM;AACR;AAkBA,SAAS,cAAc;AACrB,SACE,oBAAC,OAAA,EAAI,eAAW,MAAC,SAAQ,aAAY,OAAO,IAAI,QAAQ,IAAI,MAAK,QAAO,QAAO,gBAAe,aAAa,GAAG,eAAc,SAAQ,gBAAe,SACjJ,UAAA,oBAAC,QAAA,EAAK,GAAE,iBAAA,CAAiB,EAAA,CAC3B;AAEJ;AAEA,SAAS,eAAe;AACtB,SACE,oBAAC,OAAA,EAAI,eAAW,MAAC,SAAQ,aAAY,OAAO,IAAI,QAAQ,IAAI,MAAK,QAAO,QAAO,gBAAe,aAAa,GAAG,eAAc,SAAQ,gBAAe,SACjJ,UAAA,oBAAC,QAAA,EAAK,GAAE,gBAAA,CAAgB,EAAA,CAC1B;AAEJ;AAOA,SAAwB,WAAW;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AACd,GAAoB;AAClB,QAAM,IAAI,EAAE,GAAG,2BAA2B,GAAG,OAAA;AAC7C,QAAM,eAAe,KAAK,IAAI,GAAG,KAAK;AACtC,QAAM,SAAS,mBAAmB,YAAY,OAAO,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,iBAAiB,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAA;AAC1H,SACE,qBAAC,SAAI,cAAY,EAAE,KAAK,QAAQ,UAAU,OAAO,IAAI,CAAC,EAAE,QAAQ,WAAW,OAAO,YAAY,CAAC,GAAG,WAAW,qDAAqD,SAAS,IACzK,UAAA;AAAA,IAAA,qBAAC,QAAA,EAAK,WAAU,0EACb,UAAA;AAAA,MAAA,SAAS,QAAQ,qBAAA,UAAA,EAAG,UAAA;AAAA,QAAA,EAAE,MAAM,QAAQ,WAAW,MAAM,gBAAgB;AAAA,QAAE;AAAA,MAAA,GAAG;AAAA,MAC1E,EAAE,KAAK,QAAQ,UAAU,OAAO,IAAI,CAAC,EAAE,QAAQ,WAAW,OAAO,YAAY,CAAC;AAAA,IAAA,GACjF;AAAA,IACA,qBAAC,OAAA,EAAI,WAAU,uCACZ,UAAA;AAAA,MAAA,OAAO,SAAS,KAAK,oBACpB,qBAAC,SAAA,EAAM,WAAU,yGACd,UAAA;AAAA,QAAA,EAAE;AAAA,QACH;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,cAAY,EAAE;AAAA,YACd,OAAO,OAAO,QAAQ;AAAA,YACtB,UAAU,CAAC,MAAM,iBAAiB,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YACxD,WAAU;AAAA,YAET,UAAA,OAAO,IAAI,CAAC,MACX,oBAAC,YAAe,OAAO,GACpB,UAAA,EAAA,GADU,CAEb,CACD;AAAA,UAAA;AAAA,QAAA;AAAA,MACH,GACF;AAAA,MAEF,oBAAC,UAAO,SAAQ,aAAY,MAAK,MAAK,0BAAO,aAAA,EAAY,GAAI,UAAU,QAAQ,GAAG,SAAS,MAAM,aAAa,OAAO,CAAC,GACnH,YAAE,MACL;AAAA,MACA,qBAAC,QAAA,EAAO,SAAQ,aAAY,MAAK,MAAK,UAAU,QAAQ,cAAc,SAAS,MAAM,aAAa,OAAO,CAAC,GACvG,UAAA;AAAA,QAAA,EAAE;AAAA,4BACF,cAAA,CAAA,CAAa;AAAA,MAAA,EAAA,CAChB;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|