@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,54 @@
|
|
|
1
|
+
.cui-modal-overlay {
|
|
2
|
+
position: fixed;
|
|
3
|
+
top: 0;
|
|
4
|
+
left: 0;
|
|
5
|
+
right: 0;
|
|
6
|
+
bottom: 0;
|
|
7
|
+
width: 100%;
|
|
8
|
+
height: 100%;
|
|
9
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
align-items: center;
|
|
13
|
+
z-index: 1000;
|
|
14
|
+
}
|
|
15
|
+
.cui-modal-overlay .cui-modal-content {
|
|
16
|
+
color: var(--dark-blue);
|
|
17
|
+
background-color: white;
|
|
18
|
+
border-radius: 25px;
|
|
19
|
+
min-width: 500px;
|
|
20
|
+
max-width: 90%;
|
|
21
|
+
max-height: 90vh;
|
|
22
|
+
overflow-y: auto;
|
|
23
|
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
|
24
|
+
}
|
|
25
|
+
.cui-modal-overlay .cui-modal-content.cui-modal-sm {
|
|
26
|
+
min-width: 320px;
|
|
27
|
+
width: 400px;
|
|
28
|
+
}
|
|
29
|
+
.cui-modal-overlay .cui-modal-content.cui-modal-md {
|
|
30
|
+
width: 600px;
|
|
31
|
+
}
|
|
32
|
+
.cui-modal-overlay .cui-modal-content.cui-modal-lg {
|
|
33
|
+
width: 900px;
|
|
34
|
+
}
|
|
35
|
+
.cui-modal-overlay .cui-modal-content.cui-modal-xl {
|
|
36
|
+
width: 1200px;
|
|
37
|
+
}
|
|
38
|
+
.cui-modal-overlay .cui-modal-header {
|
|
39
|
+
padding: 1rem 1.5rem;
|
|
40
|
+
border-bottom: 1px solid var(--light-gray-01);
|
|
41
|
+
display: flex;
|
|
42
|
+
justify-content: space-between;
|
|
43
|
+
align-items: center;
|
|
44
|
+
}
|
|
45
|
+
.cui-modal-overlay .cui-modal-title {
|
|
46
|
+
margin: 0;
|
|
47
|
+
font-size: 1.25rem;
|
|
48
|
+
}
|
|
49
|
+
.cui-modal-overlay .cui-modal-body {
|
|
50
|
+
flex: 1;
|
|
51
|
+
overflow-y: auto;
|
|
52
|
+
overflow-x: hidden;
|
|
53
|
+
padding: 2rem 2rem 2rem 2rem;
|
|
54
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { IconButtonThemeStyled } from "../../../styles/themes/ButtonThemes.js";
|
|
3
|
+
import IconButton from "../../atoms/Button/variants/IconButton.js";
|
|
4
|
+
import { faX } from "@fortawesome/free-solid-svg-icons";
|
|
5
|
+
import { RemoveScroll } from "react-remove-scroll";
|
|
6
|
+
import { forwardRef, useRef, useEffect } from "react";
|
|
7
|
+
import { createPortal } from "react-dom";
|
|
8
|
+
import './Modal.css';/* empty css */
|
|
9
|
+
const Modal = forwardRef(
|
|
10
|
+
({ title, onClose, modalOnly, size, children }, ref) => {
|
|
11
|
+
const modalRef = useRef(null);
|
|
12
|
+
const containerRef = ref || modalRef;
|
|
13
|
+
function closeModal() {
|
|
14
|
+
onClose();
|
|
15
|
+
}
|
|
16
|
+
const handleOverlayClick = (e) => {
|
|
17
|
+
if (e.target === e.currentTarget) {
|
|
18
|
+
closeModal();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const handleEsc = (e) => {
|
|
23
|
+
if (e.key === "Escape") {
|
|
24
|
+
closeModal();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
window.addEventListener("keydown", handleEsc);
|
|
28
|
+
return () => {
|
|
29
|
+
window.removeEventListener("keydown", handleEsc);
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
const modalContent = /* @__PURE__ */ jsx(RemoveScroll, { children: /* @__PURE__ */ jsx(
|
|
33
|
+
"div",
|
|
34
|
+
{
|
|
35
|
+
className: "cui-modal-overlay",
|
|
36
|
+
onClick: handleOverlayClick,
|
|
37
|
+
ref: containerRef,
|
|
38
|
+
children: modalOnly ? children : /* @__PURE__ */ jsxs("div", { className: `cui-modal-content${size ? ` cui-modal-${size}` : ""}`, children: [
|
|
39
|
+
/* @__PURE__ */ jsxs("div", { className: "cui-modal-header", children: [
|
|
40
|
+
/* @__PURE__ */ jsx("h2", { className: "cui-modal-title", children: title }),
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
IconButton,
|
|
43
|
+
{
|
|
44
|
+
icon: faX,
|
|
45
|
+
onClick: closeModal,
|
|
46
|
+
theme: IconButtonThemeStyled
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
] }),
|
|
50
|
+
/* @__PURE__ */ jsx("div", { className: "cui-modal-body", children })
|
|
51
|
+
] })
|
|
52
|
+
}
|
|
53
|
+
) });
|
|
54
|
+
if (ref) {
|
|
55
|
+
return modalContent;
|
|
56
|
+
}
|
|
57
|
+
return createPortal(modalContent, document.body);
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
Modal.displayName = "Modal";
|
|
61
|
+
export {
|
|
62
|
+
Modal as default
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=Modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.js","sources":["../../../../../../src/legacy/components/molecules/Modal/Modal.tsx"],"sourcesContent":["import { IconButtonThemeStyled } from '../../../styles/themes/ButtonThemes'\r\nimport IconButton from '../../atoms/Button/variants/IconButton'\r\nimport { faX } from '@fortawesome/free-solid-svg-icons'\r\nimport { RemoveScroll } from 'react-remove-scroll'\r\nimport React, { PropsWithChildren, forwardRef, useRef, useEffect } from 'react'\r\nimport { createPortal } from 'react-dom'\r\nimport './Modal.scss'\r\n\r\n/**\r\n * Largura do modal.\r\n *\r\n * Sem `size` o modal mede-se pelo conteúdo (entre `min-width: 500px` e\r\n * `max-width: 90%`), que é o comportamento histórico — não se define um\r\n * default para não mexer na aparência dos portais que já o usam.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\nexport type ModalSize = 'sm' | 'md' | 'lg' | 'xl'\r\n\r\ntype Props = PropsWithChildren<{\r\n title: string\r\n modalOnly?: boolean\r\n onClose: () => void\r\n /** Largura fixa. Omitir mantém a largura pelo conteúdo. */\r\n size?: ModalSize\r\n}>\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nconst Modal = forwardRef<HTMLDivElement, Props>(\r\n ({ title, onClose, modalOnly, size, children }, ref) => {\r\n const modalRef = useRef<HTMLDivElement>(null)\r\n const containerRef = ref || modalRef\r\n\r\n function closeModal() {\r\n onClose()\r\n }\r\n\r\n const handleOverlayClick = (e: React.MouseEvent<HTMLDivElement>) => {\r\n if (e.target === e.currentTarget) {\r\n closeModal()\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n const handleEsc = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') {\r\n closeModal()\r\n }\r\n }\r\n window.addEventListener('keydown', handleEsc)\r\n\r\n return () => {\r\n window.removeEventListener('keydown', handleEsc)\r\n }\r\n }, [])\r\n\r\n // Create a portal to render the modal content\r\n const modalContent = (\r\n <RemoveScroll>\r\n <div\r\n className=\"cui-modal-overlay\"\r\n onClick={handleOverlayClick}\r\n ref={containerRef}\r\n >\r\n {modalOnly ? (\r\n children\r\n ) : (\r\n <div className={`cui-modal-content${size ? ` cui-modal-${size}` : ''}`}>\r\n <div className=\"cui-modal-header\">\r\n <h2 className=\"cui-modal-title\">{title}</h2>\r\n <IconButton\r\n icon={faX}\r\n onClick={closeModal}\r\n theme={IconButtonThemeStyled}\r\n />\r\n </div>\r\n <div className=\"cui-modal-body\">{children}</div>\r\n </div>\r\n )}\r\n </div>\r\n </RemoveScroll>\r\n )\r\n\r\n // If a ref is provided, let the parent handle the portal rendering\r\n if (ref) {\r\n return modalContent\r\n }\r\n\r\n // Otherwise, create a portal to document.body\r\n return createPortal(modalContent, document.body)\r\n }\r\n)\r\n\r\nModal.displayName = 'Modal'\r\nexport default Modal\r\n"],"names":[],"mappings":";;;;;;;;AA2BA,MAAM,QAAQ;AAAA,EACZ,CAAC,EAAE,OAAO,SAAS,WAAW,MAAM,SAAA,GAAY,QAAQ;AACtD,UAAM,WAAW,OAAuB,IAAI;AAC5C,UAAM,eAAe,OAAO;AAE5B,aAAS,aAAa;AACpB,cAAA;AAAA,IACF;AAEA,UAAM,qBAAqB,CAAC,MAAwC;AAClE,UAAI,EAAE,WAAW,EAAE,eAAe;AAChC,mBAAA;AAAA,MACF;AAAA,IACF;AAEA,cAAU,MAAM;AACd,YAAM,YAAY,CAAC,MAAqB;AACtC,YAAI,EAAE,QAAQ,UAAU;AACtB,qBAAA;AAAA,QACF;AAAA,MACF;AACA,aAAO,iBAAiB,WAAW,SAAS;AAE5C,aAAO,MAAM;AACX,eAAO,oBAAoB,WAAW,SAAS;AAAA,MACjD;AAAA,IACF,GAAG,CAAA,CAAE;AAGL,UAAM,mCACH,cAAA,EACC,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS;AAAA,QACT,KAAK;AAAA,QAEJ,UAAA,YACC,WAEA,qBAAC,OAAA,EAAI,WAAW,oBAAoB,OAAO,cAAc,IAAI,KAAK,EAAE,IAClE,UAAA;AAAA,UAAA,qBAAC,OAAA,EAAI,WAAU,oBACb,UAAA;AAAA,YAAA,oBAAC,MAAA,EAAG,WAAU,mBAAmB,UAAA,OAAM;AAAA,YACvC;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,MAAM;AAAA,gBACN,SAAS;AAAA,gBACT,OAAO;AAAA,cAAA;AAAA,YAAA;AAAA,UACT,GACF;AAAA,UACA,oBAAC,OAAA,EAAI,WAAU,kBAAkB,SAAA,CAAS;AAAA,QAAA,EAAA,CAC5C;AAAA,MAAA;AAAA,IAAA,GAGN;AAIF,QAAI,KAAK;AACP,aAAO;AAAA,IACT;AAGA,WAAO,aAAa,cAAc,SAAS,IAAI;AAAA,EACjD;AACF;AAEA,MAAM,cAAc;"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
.cui-multiTagPicker {
|
|
2
|
+
display: flex;
|
|
3
|
+
width: 100%;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.cui-multiTagPicker-container {
|
|
8
|
+
width: 100%;
|
|
9
|
+
position: relative;
|
|
10
|
+
display: flex;
|
|
11
|
+
justify-content: center;
|
|
12
|
+
align-items: flex-start;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.cui-multiTagPicker-search {
|
|
16
|
+
flex-grow: 1;
|
|
17
|
+
width: 100%;
|
|
18
|
+
min-height: 32px;
|
|
19
|
+
max-height: 100px;
|
|
20
|
+
border-radius: 24px;
|
|
21
|
+
background-color: var(--light-gray-02);
|
|
22
|
+
border: solid rgba(0, 0, 0, 0.2) 1px;
|
|
23
|
+
padding: 5px 10px 5px 35px;
|
|
24
|
+
box-shadow: inset 0px 1px 1px rgb(194, 194, 194);
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-wrap: wrap;
|
|
27
|
+
gap: 6px;
|
|
28
|
+
overflow: auto;
|
|
29
|
+
}
|
|
30
|
+
.cui-multiTagPicker-search .pointer {
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.cui-multiTagPicker-search li {
|
|
35
|
+
min-width: fit-content;
|
|
36
|
+
display: flex;
|
|
37
|
+
align-items: center;
|
|
38
|
+
gap: 6px;
|
|
39
|
+
list-style-type: none;
|
|
40
|
+
background-color: var(--dark-blue);
|
|
41
|
+
border-radius: 15px;
|
|
42
|
+
color: var(--almost-white);
|
|
43
|
+
font-size: 15px;
|
|
44
|
+
padding: 7px 10px 7px 10px;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.cui-multiTagPicker-search input[type=text]:focus {
|
|
48
|
+
outline: none;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.cui-multiTagPicker-input {
|
|
52
|
+
border: none;
|
|
53
|
+
flex-grow: 1;
|
|
54
|
+
background: transparent;
|
|
55
|
+
height: 32px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.cui-multiTagPicker-magnifier {
|
|
59
|
+
position: absolute;
|
|
60
|
+
top: 14px;
|
|
61
|
+
left: 14px;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.cui-multiTagPicker-no-options {
|
|
65
|
+
color: var(--dark-blue);
|
|
66
|
+
font-size: 13px;
|
|
67
|
+
text-align: center;
|
|
68
|
+
margin-top: 15px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.cui-multiTagPicker-spinner {
|
|
72
|
+
margin-top: 20px;
|
|
73
|
+
flex: 1;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.cui-multiTagPicker-options-container {
|
|
77
|
+
flex: 1;
|
|
78
|
+
display: flex;
|
|
79
|
+
flex-direction: column;
|
|
80
|
+
gap: 10px;
|
|
81
|
+
overflow: auto;
|
|
82
|
+
box-sizing: border-box;
|
|
83
|
+
margin-top: 10px;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.cui-multiTagPicker-options {
|
|
87
|
+
flex: 1;
|
|
88
|
+
width: 100%;
|
|
89
|
+
overflow-y: auto;
|
|
90
|
+
overflow-x: hidden;
|
|
91
|
+
box-sizing: border-box;
|
|
92
|
+
display: grid;
|
|
93
|
+
grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
|
|
94
|
+
gap: 10px;
|
|
95
|
+
align-content: start;
|
|
96
|
+
padding: 10px 10px 10px 0px;
|
|
97
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from "react";
|
|
3
|
+
import InfiniteScroll from "react-infinite-scroll-component";
|
|
4
|
+
import { faCircleMinus, faMagnifyingGlass } from "@fortawesome/free-solid-svg-icons";
|
|
5
|
+
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
6
|
+
import { Color } from "../../../constants/Colors.js";
|
|
7
|
+
import Select from "../../atoms/MultiTagPickerTag/MultiTagPickerTag.js";
|
|
8
|
+
import Spinner from "../../layout/Spinner/Spinner.js";
|
|
9
|
+
import './MultiTagPicker.css';/* empty css */
|
|
10
|
+
const MultiTagPicker = (props) => {
|
|
11
|
+
const {
|
|
12
|
+
placeholder,
|
|
13
|
+
noOptionsLabel,
|
|
14
|
+
searchInput,
|
|
15
|
+
editable,
|
|
16
|
+
loading,
|
|
17
|
+
optionsSelected,
|
|
18
|
+
options,
|
|
19
|
+
hasMoreItems,
|
|
20
|
+
handleRemoveItem,
|
|
21
|
+
handleInputChange,
|
|
22
|
+
handleInputKeyDown,
|
|
23
|
+
handleAddItem,
|
|
24
|
+
loadMore
|
|
25
|
+
} = props;
|
|
26
|
+
function handleInputKeyDownInner(event) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
editable && handleInputKeyDown && handleInputKeyDown();
|
|
29
|
+
}
|
|
30
|
+
function handleInputChangeInner(event) {
|
|
31
|
+
editable && handleInputChange && handleInputChange(event.target.value);
|
|
32
|
+
}
|
|
33
|
+
const selectedIds = useMemo(
|
|
34
|
+
() => new Set(optionsSelected.map((o) => o.id)),
|
|
35
|
+
[optionsSelected]
|
|
36
|
+
);
|
|
37
|
+
const showSelected = optionsSelected.map((option) => /* @__PURE__ */ jsxs("li", { children: [
|
|
38
|
+
/* @__PURE__ */ jsx("p", { children: option.label }),
|
|
39
|
+
/* @__PURE__ */ jsx(
|
|
40
|
+
FontAwesomeIcon,
|
|
41
|
+
{
|
|
42
|
+
size: "sm",
|
|
43
|
+
icon: faCircleMinus,
|
|
44
|
+
className: `${editable && "pointer"}`,
|
|
45
|
+
color: "#F8F8F8",
|
|
46
|
+
onClick: () => editable && handleRemoveItem(option.id)
|
|
47
|
+
}
|
|
48
|
+
)
|
|
49
|
+
] }, option.id));
|
|
50
|
+
return /* @__PURE__ */ jsxs("div", { className: "cui-multiTagPicker", children: [
|
|
51
|
+
/* @__PURE__ */ jsxs(
|
|
52
|
+
"form",
|
|
53
|
+
{
|
|
54
|
+
onSubmit: handleInputKeyDownInner,
|
|
55
|
+
className: "cui-multiTagPicker-container",
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx(
|
|
58
|
+
FontAwesomeIcon,
|
|
59
|
+
{
|
|
60
|
+
size: "1x",
|
|
61
|
+
icon: faMagnifyingGlass,
|
|
62
|
+
className: "cui-multiTagPicker-magnifier",
|
|
63
|
+
color: Color.MEDIUM_GRAY_01
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
/* @__PURE__ */ jsxs("div", { className: "cui-multiTagPicker-search", children: [
|
|
67
|
+
showSelected,
|
|
68
|
+
" ",
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
"input",
|
|
71
|
+
{
|
|
72
|
+
className: "cui-multiTagPicker-input",
|
|
73
|
+
type: "text",
|
|
74
|
+
value: searchInput,
|
|
75
|
+
onChange: handleInputChangeInner,
|
|
76
|
+
placeholder: editable ? placeholder : "",
|
|
77
|
+
disabled: !editable || loading
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
] })
|
|
81
|
+
]
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
options.length === 0 && !loading && /* @__PURE__ */ jsx("p", { className: "cui-multiTagPicker-no-options", children: noOptionsLabel }),
|
|
85
|
+
editable && (loading ? /* @__PURE__ */ jsx("div", { className: "cui-multiTagPicker-spinner", children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx("div", { className: "cui-multiTagPicker-options-container", children: /* @__PURE__ */ jsx(
|
|
86
|
+
InfiniteScroll,
|
|
87
|
+
{
|
|
88
|
+
dataLength: options.length,
|
|
89
|
+
next: () => loadMore && loadMore(),
|
|
90
|
+
hasMore: hasMoreItems,
|
|
91
|
+
className: "cui-multiTagPicker-options",
|
|
92
|
+
loader: /* @__PURE__ */ jsx("div", { className: "cui-multiTagPicker-spinner", children: /* @__PURE__ */ jsx(Spinner, {}) }),
|
|
93
|
+
children: options.map((option) => /* @__PURE__ */ jsx(
|
|
94
|
+
Select,
|
|
95
|
+
{
|
|
96
|
+
id: option.id,
|
|
97
|
+
label: option.label,
|
|
98
|
+
selected: selectedIds.has(option.id),
|
|
99
|
+
handleTagChange: (changedTo) => {
|
|
100
|
+
if (changedTo) handleAddItem(option);
|
|
101
|
+
else handleRemoveItem(option.id);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
option.id
|
|
105
|
+
))
|
|
106
|
+
}
|
|
107
|
+
) }))
|
|
108
|
+
] });
|
|
109
|
+
};
|
|
110
|
+
export {
|
|
111
|
+
MultiTagPicker as default
|
|
112
|
+
};
|
|
113
|
+
//# sourceMappingURL=MultiTagPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiTagPicker.js","sources":["../../../../../../src/legacy/components/molecules/MultiTagPicker/MultiTagPicker.tsx"],"sourcesContent":["import React, { ChangeEvent, useMemo } from 'react'\r\nimport InfiniteScroll from 'react-infinite-scroll-component'\r\nimport {\r\n faCircleMinus,\r\n faMagnifyingGlass,\r\n} from '@fortawesome/free-solid-svg-icons'\r\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\r\nimport { Color } from '../../../constants/Colors'\r\n\r\nimport MultiTagPickerTag from '../../atoms/MultiTagPickerTag/MultiTagPickerTag'\r\nimport Spinner from '../../layout/Spinner/Spinner'\r\nimport './MultiTagPicker.scss'\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport interface Option {\r\n id: string\r\n label: string\r\n}\r\n\r\nexport interface MultiTagPickerProps {\r\n placeholder?: string\r\n noOptionsLabel?: string\r\n searchInput: string\r\n editable: boolean\r\n loading: boolean\r\n optionsSelected: Option[]\r\n options: Option[]\r\n hasMoreItems: boolean\r\n\r\n handleInputKeyDown?: () => void\r\n handleInputChange?: (input: string) => void\r\n handleRemoveItem: (itemId: string) => void\r\n handleAddItem: (item: Option) => void\r\n loadMore?: () => void\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nconst MultiTagPicker: React.FC<MultiTagPickerProps> = (\r\n props: MultiTagPickerProps\r\n) => {\r\n const {\r\n placeholder,\r\n noOptionsLabel,\r\n searchInput,\r\n editable,\r\n loading,\r\n optionsSelected,\r\n options,\r\n hasMoreItems,\r\n handleRemoveItem,\r\n handleInputChange,\r\n handleInputKeyDown,\r\n handleAddItem,\r\n loadMore,\r\n } = props\r\n\r\n function handleInputKeyDownInner(event: React.FormEvent<HTMLFormElement>) {\r\n event.preventDefault()\r\n editable && handleInputKeyDown && handleInputKeyDown()\r\n }\r\n\r\n function handleInputChangeInner(event: ChangeEvent<HTMLInputElement>) {\r\n editable && handleInputChange && handleInputChange(event.target.value)\r\n }\r\n\r\n const selectedIds = useMemo(\r\n () => new Set(optionsSelected.map((o) => o.id)),\r\n [optionsSelected]\r\n )\r\n\r\n const showSelected = optionsSelected.map((option: Option) => (\r\n <li key={option.id}>\r\n <p>{option.label}</p>\r\n <FontAwesomeIcon\r\n size=\"sm\"\r\n icon={faCircleMinus}\r\n className={`${editable && 'pointer'}`}\r\n color=\"#F8F8F8\"\r\n onClick={() => editable && handleRemoveItem(option.id)}\r\n />\r\n </li>\r\n ))\r\n\r\n return (\r\n <div className=\"cui-multiTagPicker\">\r\n <form\r\n onSubmit={handleInputKeyDownInner}\r\n className=\"cui-multiTagPicker-container\"\r\n >\r\n <FontAwesomeIcon\r\n size=\"1x\"\r\n icon={faMagnifyingGlass}\r\n className=\"cui-multiTagPicker-magnifier\"\r\n color={Color.MEDIUM_GRAY_01}\r\n />\r\n <div className=\"cui-multiTagPicker-search\">\r\n {showSelected}{' '}\r\n {/* Not using ul around the li to ensure the input is added nicely to the grid*/}\r\n <input\r\n className=\"cui-multiTagPicker-input\"\r\n type=\"text\"\r\n value={searchInput}\r\n onChange={handleInputChangeInner}\r\n placeholder={editable ? placeholder : ''}\r\n disabled={!editable || loading}\r\n />\r\n </div>\r\n </form>\r\n {options.length === 0 && !loading && (\r\n <p className=\"cui-multiTagPicker-no-options\">{noOptionsLabel}</p>\r\n )}\r\n {editable &&\r\n (loading ? (\r\n <div className=\"cui-multiTagPicker-spinner\">\r\n <Spinner />\r\n </div>\r\n ) : (\r\n <div className=\"cui-multiTagPicker-options-container\">\r\n <InfiniteScroll\r\n dataLength={options.length}\r\n next={() => loadMore && loadMore()}\r\n hasMore={hasMoreItems}\r\n className=\"cui-multiTagPicker-options\"\r\n loader={\r\n <div className=\"cui-multiTagPicker-spinner\">\r\n <Spinner />\r\n </div>\r\n }\r\n >\r\n {options.map((option: Option) => (\r\n <MultiTagPickerTag\r\n key={option.id}\r\n id={option.id}\r\n label={option.label}\r\n selected={selectedIds.has(option.id)}\r\n handleTagChange={(changedTo) => {\r\n if (changedTo) handleAddItem(option)\r\n else handleRemoveItem(option.id)\r\n }}\r\n />\r\n ))}\r\n </InfiniteScroll>\r\n </div>\r\n ))}\r\n </div>\r\n )\r\n}\r\n\r\nexport default MultiTagPicker\r\n"],"names":["MultiTagPickerTag"],"mappings":";;;;;;;;;AAqCA,MAAM,iBAAgD,CACpD,UACG;AACH,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAEJ,WAAS,wBAAwB,OAAyC;AACxE,UAAM,eAAA;AACN,gBAAY,sBAAsB,mBAAA;AAAA,EACpC;AAEA,WAAS,uBAAuB,OAAsC;AACpE,gBAAY,qBAAqB,kBAAkB,MAAM,OAAO,KAAK;AAAA,EACvE;AAEA,QAAM,cAAc;AAAA,IAClB,MAAM,IAAI,IAAI,gBAAgB,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;AAAA,IAC9C,CAAC,eAAe;AAAA,EAAA;AAGlB,QAAM,eAAe,gBAAgB,IAAI,CAAC,gCACvC,MAAA,EACC,UAAA;AAAA,IAAA,oBAAC,KAAA,EAAG,iBAAO,MAAA,CAAM;AAAA,IACjB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,MAAM;AAAA,QACN,WAAW,GAAG,YAAY,SAAS;AAAA,QACnC,OAAM;AAAA,QACN,SAAS,MAAM,YAAY,iBAAiB,OAAO,EAAE;AAAA,MAAA;AAAA,IAAA;AAAA,EACvD,KARO,OAAO,EAShB,CACD;AAED,SACE,qBAAC,OAAA,EAAI,WAAU,sBACb,UAAA;AAAA,IAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,UAAU;AAAA,QACV,WAAU;AAAA,QAEV,UAAA;AAAA,UAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL,MAAM;AAAA,cACN,WAAU;AAAA,cACV,OAAO,MAAM;AAAA,YAAA;AAAA,UAAA;AAAA,UAEf,qBAAC,OAAA,EAAI,WAAU,6BACZ,UAAA;AAAA,YAAA;AAAA,YAAc;AAAA,YAEf;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAU;AAAA,gBACV,MAAK;AAAA,gBACL,OAAO;AAAA,gBACP,UAAU;AAAA,gBACV,aAAa,WAAW,cAAc;AAAA,gBACtC,UAAU,CAAC,YAAY;AAAA,cAAA;AAAA,YAAA;AAAA,UACzB,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,IAED,QAAQ,WAAW,KAAK,CAAC,WACxB,oBAAC,KAAA,EAAE,WAAU,iCAAiC,UAAA,eAAA,CAAe;AAAA,IAE9D,aACE,UACC,oBAAC,OAAA,EAAI,WAAU,8BACb,UAAA,oBAAC,SAAA,EAAQ,EAAA,CACX,IAEA,oBAAC,OAAA,EAAI,WAAU,wCACb,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,YAAY,QAAQ;AAAA,QACpB,MAAM,MAAM,YAAY,SAAA;AAAA,QACxB,SAAS;AAAA,QACT,WAAU;AAAA,QACV,QACE,oBAAC,OAAA,EAAI,WAAU,8BACb,UAAA,oBAAC,WAAQ,GACX;AAAA,QAGD,UAAA,QAAQ,IAAI,CAAC,WACZ;AAAA,UAACA;AAAAA,UAAA;AAAA,YAEC,IAAI,OAAO;AAAA,YACX,OAAO,OAAO;AAAA,YACd,UAAU,YAAY,IAAI,OAAO,EAAE;AAAA,YACnC,iBAAiB,CAAC,cAAc;AAC9B,kBAAI,yBAAyB,MAAM;AAAA,kBAC9B,kBAAiB,OAAO,EAAE;AAAA,YACjC;AAAA,UAAA;AAAA,UAPK,OAAO;AAAA,QAAA,CASf;AAAA,MAAA;AAAA,IAAA,GAEL;AAAA,EAAA,GAEN;AAEJ;"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState, useEffect } from "react";
|
|
3
|
+
import * as MsalReact from "@azure/msal-react";
|
|
4
|
+
import UserAvatar from "../UserAvatar/UserAvatar.js";
|
|
5
|
+
const GRAPH = "https://graph.microsoft.com/v1.0";
|
|
6
|
+
const SCOPE_PROPRIO = ["User.Read"];
|
|
7
|
+
const SCOPE_OUTROS = ["User.ReadBasic.All"];
|
|
8
|
+
async function getGraphToken(instance, account, scopes) {
|
|
9
|
+
try {
|
|
10
|
+
const res = await instance.acquireTokenSilent({ scopes, account });
|
|
11
|
+
return res.accessToken;
|
|
12
|
+
} catch (err) {
|
|
13
|
+
if (err?.name === "InteractionRequiredAuthError") {
|
|
14
|
+
const res = await instance.acquireTokenPopup({ scopes });
|
|
15
|
+
return res.accessToken;
|
|
16
|
+
}
|
|
17
|
+
throw err;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function fetchPhotoBlob(token, base) {
|
|
21
|
+
for (const seg of ["/photos/240x240/$value", "/photo/$value"]) {
|
|
22
|
+
const resp = await fetch(`${GRAPH}${base}${seg}`, { headers: { Authorization: `Bearer ${token}` } });
|
|
23
|
+
if (resp.ok) return resp.blob();
|
|
24
|
+
if (resp.status === 404) continue;
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
async function fetchProfile(token, base) {
|
|
30
|
+
const resp = await fetch(`${GRAPH}${base}?$select=displayName,mail,userPrincipalName,jobTitle,department,companyName`, {
|
|
31
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
32
|
+
});
|
|
33
|
+
if (!resp.ok) return null;
|
|
34
|
+
const d = await resp.json();
|
|
35
|
+
return {
|
|
36
|
+
name: d.displayName,
|
|
37
|
+
email: d.mail ?? d.userPrincipalName,
|
|
38
|
+
company: d.companyName,
|
|
39
|
+
department: d.department,
|
|
40
|
+
jobTitle: d.jobTitle
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const photoCache = /* @__PURE__ */ new Map();
|
|
44
|
+
const profileCache = /* @__PURE__ */ new Map();
|
|
45
|
+
function PhotoAvatar({ oid, name, email, className = "", showCard = false, getToken }) {
|
|
46
|
+
const { instance, accounts } = MsalReact.useMsal();
|
|
47
|
+
const account = instance.getActiveAccount() ?? accounts[0];
|
|
48
|
+
const accountKey = account?.homeAccountId ?? null;
|
|
49
|
+
const getTokenRef = useRef(getToken);
|
|
50
|
+
getTokenRef.current = getToken;
|
|
51
|
+
const accountRef = useRef(account);
|
|
52
|
+
accountRef.current = account;
|
|
53
|
+
const temGetToken = Boolean(getToken);
|
|
54
|
+
const cacheKey = temGetToken ? "self" : oid ?? accountKey ?? "me";
|
|
55
|
+
const [url, setUrl] = useState(() => photoCache.get(cacheKey) ?? null);
|
|
56
|
+
const [profile, setProfile] = useState(() => profileCache.get(cacheKey) ?? null);
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (!temGetToken && !accountKey) return void 0;
|
|
59
|
+
let cancelled = false;
|
|
60
|
+
const cachedPhoto = photoCache.get(cacheKey);
|
|
61
|
+
const cachedProfile = profileCache.get(cacheKey);
|
|
62
|
+
if (cachedPhoto !== void 0 && (!showCard || cachedProfile !== void 0)) {
|
|
63
|
+
setUrl(cachedPhoto);
|
|
64
|
+
if (cachedProfile) setProfile(cachedProfile);
|
|
65
|
+
return void 0;
|
|
66
|
+
}
|
|
67
|
+
const resolve = async () => {
|
|
68
|
+
const fornecer = getTokenRef.current;
|
|
69
|
+
if (fornecer) return { token: await fornecer(), base: "/me" };
|
|
70
|
+
const conta = accountRef.current;
|
|
71
|
+
const selfOid = conta.idTokenClaims?.oid;
|
|
72
|
+
const base = !oid || selfOid && selfOid === oid ? "/me" : `/users/${oid}`;
|
|
73
|
+
const scopes = base === "/me" ? SCOPE_PROPRIO : SCOPE_OUTROS;
|
|
74
|
+
const token = await getGraphToken(instance, conta, scopes);
|
|
75
|
+
return { token, base };
|
|
76
|
+
};
|
|
77
|
+
resolve().then(async ({ token, base }) => {
|
|
78
|
+
const blob = await fetchPhotoBlob(token, base);
|
|
79
|
+
const objectUrl = blob ? URL.createObjectURL(blob) : null;
|
|
80
|
+
photoCache.set(cacheKey, objectUrl);
|
|
81
|
+
if (!cancelled) setUrl(objectUrl);
|
|
82
|
+
if (showCard) {
|
|
83
|
+
const prof = await fetchProfile(token, base);
|
|
84
|
+
profileCache.set(cacheKey, prof);
|
|
85
|
+
if (!cancelled && prof) setProfile(prof);
|
|
86
|
+
}
|
|
87
|
+
}).catch(() => {
|
|
88
|
+
photoCache.set(cacheKey, null);
|
|
89
|
+
if (showCard) profileCache.set(cacheKey, null);
|
|
90
|
+
});
|
|
91
|
+
return () => {
|
|
92
|
+
cancelled = true;
|
|
93
|
+
};
|
|
94
|
+
}, [cacheKey, accountKey, temGetToken, showCard, oid, instance]);
|
|
95
|
+
return /* @__PURE__ */ jsx(
|
|
96
|
+
UserAvatar,
|
|
97
|
+
{
|
|
98
|
+
name: name ?? profile?.name,
|
|
99
|
+
email: email ?? profile?.email,
|
|
100
|
+
company: profile?.company,
|
|
101
|
+
department: profile?.department,
|
|
102
|
+
jobTitle: profile?.jobTitle,
|
|
103
|
+
photo: url,
|
|
104
|
+
className: `rounded-full ${className}`,
|
|
105
|
+
showCard
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
export {
|
|
110
|
+
SCOPE_OUTROS,
|
|
111
|
+
SCOPE_PROPRIO,
|
|
112
|
+
PhotoAvatar as default
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=PhotoAvatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PhotoAvatar.js","sources":["../../../../../../src/legacy/components/molecules/PhotoAvatar/PhotoAvatar.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState } from 'react'\r\n// O MSAL é peer opcional: numa app sem ele, o bundler troca-o por um módulo vazio, e\r\n// imports com nome (useMsal, InteractionRequiredAuthError) partiam o build dessa app.\r\nimport * as MsalReact from '@azure/msal-react'\r\nimport type { IPublicClientApplication, AccountInfo } from '@azure/msal-browser'\r\nimport UserAvatar from '../UserAvatar/UserAvatar'\r\n\r\nconst GRAPH = 'https://graph.microsoft.com/v1.0'\r\n\r\n// `User.Read` so da acesso ao proprio utilizador. Para a foto ou o perfil de\r\n// OUTRA pessoa (`/users/<oid>`) e preciso `User.ReadBasic.All`, que a App\r\n// Registration da app consumidora tem de ter com consentimento de\r\n// administrador. Pedir `User.Read` para terceiros arrisca um 403, com o avatar\r\n// a cair nas iniciais sem nada que explique porque.\r\nexport const SCOPE_PROPRIO = ['User.Read']\r\nexport const SCOPE_OUTROS = ['User.ReadBasic.All']\r\n\r\nasync function getGraphToken(\r\n instance: IPublicClientApplication,\r\n account: AccountInfo,\r\n scopes: string[]\r\n): Promise<string> {\r\n try {\r\n const res = await instance.acquireTokenSilent({ scopes, account })\r\n return res.accessToken\r\n } catch (err) {\r\n if ((err as { name?: string } | null)?.name === 'InteractionRequiredAuthError') {\r\n const res = await instance.acquireTokenPopup({ scopes })\r\n return res.accessToken\r\n }\r\n throw err\r\n }\r\n}\r\n\r\n/** Busca a foto (240×240, fallback /photo). null se 404/erro. */\r\nasync function fetchPhotoBlob(token: string, base: string): Promise<Blob | null> {\r\n for (const seg of ['/photos/240x240/$value', '/photo/$value']) {\r\n const resp = await fetch(`${GRAPH}${base}${seg}`, { headers: { Authorization: `Bearer ${token}` } })\r\n if (resp.ok) return resp.blob()\r\n if (resp.status === 404) continue\r\n return null\r\n }\r\n return null\r\n}\r\n\r\nexport interface GraphProfile {\r\n name?: string | null\r\n email?: string | null\r\n company?: string | null\r\n department?: string | null\r\n jobTitle?: string | null\r\n}\r\n\r\n/** Perfil p/ o cartão de hover (mesmo token User.Read). null se erro. */\r\nasync function fetchProfile(token: string, base: string): Promise<GraphProfile | null> {\r\n const resp = await fetch(`${GRAPH}${base}?$select=displayName,mail,userPrincipalName,jobTitle,department,companyName`, {\r\n headers: { Authorization: `Bearer ${token}` },\r\n })\r\n if (!resp.ok) return null\r\n const d = (await resp.json()) as Record<string, string | null>\r\n return {\r\n name: d.displayName,\r\n email: d.mail ?? d.userPrincipalName,\r\n company: d.companyName,\r\n department: d.department,\r\n jobTitle: d.jobTitle,\r\n }\r\n}\r\n\r\ninterface Props {\r\n oid?: string | null\r\n name?: string | null\r\n email?: string | null\r\n className?: string\r\n /** Passa para UserAvatar: cartão de detalhes em hover. Default: off. */\r\n showCard?: boolean\r\n /**\r\n * Fornece um token do Graph (scope `User.Read`) usando o MSAL DA APP.\r\n * PREFERIR isto: evita o `useMsal` interno, que pode ler um `MsalContext`\r\n * diferente quando o bundler duplica o `@azure/msal-react` (→ account null →\r\n * sem foto). Com `getToken`, a foto do próprio (/me) resolve sempre.\r\n * Ex.: `getToken={() => msalInstance.acquireTokenSilent({scopes:['User.Read'],account}).then(r=>r.accessToken)}`\r\n */\r\n getToken?: () => Promise<string>\r\n}\r\n\r\n// Cache em memória (evita refetch entre montagens).\r\n//\r\n// Guarda o OBJECT URL já criado, não o Blob. Com o Blob, cada passagem pelo\r\n// efeito criava um URL novo, o que mudava o estado e disparava outro render —\r\n// e outra passagem. Era um ciclo infinito, visível como a foto a alternar com\r\n// as iniciais.\r\n//\r\n// O URL nunca é revogado: é uma imagem para toda a sessão, partilhada por\r\n// todas as montagens com a mesma chave. Revogá-la ao desmontar partia as que\r\n// ficavam a usá-la.\r\nconst photoCache = new Map<string, string | null>()\r\nconst profileCache = new Map<string, GraphProfile | null>()\r\n\r\n/**\r\n * Avatar com a foto real do MS Graph. Fallback: iniciais (UserAvatar).\r\n * Token: via `getToken` (recomendado) ou, em alternativa, via `useMsal` interno.\r\n * Peers: @azure/msal-react, @azure/msal-browser.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\nexport default function PhotoAvatar({ oid, name, email, className = '', showCard = false, getToken }: Props) {\r\n const { instance, accounts } = MsalReact.useMsal()\r\n const account = instance.getActiveAccount() ?? accounts[0]\r\n\r\n // O MSAL reconstrói o objeto da conta a cada chamada, por isso ele nunca\r\n // serve como dependência do efeito: fazia-o correr em todos os renders. A\r\n // identidade estável é o homeAccountId.\r\n const accountKey = account?.homeAccountId ?? null\r\n\r\n // O getToken é quase sempre uma arrow inline na app, logo também muda a cada\r\n // render. Fica numa ref, fora das dependências; o que importa é se existe.\r\n const getTokenRef = useRef(getToken)\r\n getTokenRef.current = getToken\r\n const accountRef = useRef(account)\r\n accountRef.current = account\r\n const temGetToken = Boolean(getToken)\r\n\r\n const cacheKey = temGetToken ? 'self' : oid ?? accountKey ?? 'me'\r\n\r\n // Arranca já com o que estiver em cache, para não piscar as iniciais ao\r\n // mudar de página.\r\n const [url, setUrl] = useState<string | null>(() => photoCache.get(cacheKey) ?? null)\r\n const [profile, setProfile] = useState<GraphProfile | null>(() => profileCache.get(cacheKey) ?? null)\r\n\r\n useEffect(() => {\r\n if (!temGetToken && !accountKey) return undefined\r\n let cancelled = false\r\n\r\n const cachedPhoto = photoCache.get(cacheKey)\r\n const cachedProfile = profileCache.get(cacheKey)\r\n if (cachedPhoto !== undefined && (!showCard || cachedProfile !== undefined)) {\r\n setUrl(cachedPhoto)\r\n if (cachedProfile) setProfile(cachedProfile)\r\n return undefined\r\n }\r\n\r\n // Token + base do Graph resolvidos 1x, reutilizados p/ foto e perfil.\r\n const resolve = async (): Promise<{ token: string; base: string }> => {\r\n const fornecer = getTokenRef.current\r\n if (fornecer) return { token: await fornecer(), base: '/me' }\r\n const conta = accountRef.current!\r\n const selfOid = (conta.idTokenClaims as { oid?: string } | undefined)?.oid\r\n // A base decide-se ANTES do token, porque e ela que determina o scope.\r\n const base = !oid || (selfOid && selfOid === oid) ? '/me' : `/users/${oid}`\r\n const scopes = base === '/me' ? SCOPE_PROPRIO : SCOPE_OUTROS\r\n const token = await getGraphToken(instance, conta, scopes)\r\n return { token, base }\r\n }\r\n\r\n resolve()\r\n .then(async ({ token, base }) => {\r\n const blob = await fetchPhotoBlob(token, base)\r\n const objectUrl = blob ? URL.createObjectURL(blob) : null\r\n photoCache.set(cacheKey, objectUrl)\r\n if (!cancelled) setUrl(objectUrl)\r\n // Perfil só quando há cartão de hover (evita chamada Graph extra).\r\n if (showCard) {\r\n const prof = await fetchProfile(token, base)\r\n profileCache.set(cacheKey, prof)\r\n if (!cancelled && prof) setProfile(prof)\r\n }\r\n })\r\n .catch(() => {\r\n photoCache.set(cacheKey, null)\r\n if (showCard) profileCache.set(cacheKey, null)\r\n })\r\n\r\n return () => {\r\n cancelled = true\r\n }\r\n }, [cacheKey, accountKey, temGetToken, showCard, oid, instance])\r\n\r\n // Redondo por default (a app pode sobrepor a forma no className, ex: rounded-none).\r\n return (\r\n <UserAvatar\r\n name={name ?? profile?.name}\r\n email={email ?? profile?.email}\r\n company={profile?.company}\r\n department={profile?.department}\r\n jobTitle={profile?.jobTitle}\r\n photo={url}\r\n className={`rounded-full ${className}`}\r\n showCard={showCard}\r\n />\r\n )\r\n}\r\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect, useMemo } from "react";
|
|
3
|
+
function SeletorPesquisa({
|
|
4
|
+
opcoes,
|
|
5
|
+
valor,
|
|
6
|
+
onChange,
|
|
7
|
+
onTextoLivre,
|
|
8
|
+
aCarregar = false,
|
|
9
|
+
erro = false,
|
|
10
|
+
maximo = 20,
|
|
11
|
+
labels,
|
|
12
|
+
icone
|
|
13
|
+
}) {
|
|
14
|
+
const [pesquisa, setPesquisa] = useState("");
|
|
15
|
+
const [aberto, setAberto] = useState(false);
|
|
16
|
+
const caixa = useRef(null);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!aberto) return;
|
|
19
|
+
const aoClicarFora = (e) => {
|
|
20
|
+
if (!caixa.current?.contains(e.target)) setAberto(false);
|
|
21
|
+
};
|
|
22
|
+
const aoEscape = (e) => {
|
|
23
|
+
if (e.key === "Escape") setAberto(false);
|
|
24
|
+
};
|
|
25
|
+
document.addEventListener("mousedown", aoClicarFora);
|
|
26
|
+
document.addEventListener("keydown", aoEscape);
|
|
27
|
+
return () => {
|
|
28
|
+
document.removeEventListener("mousedown", aoClicarFora);
|
|
29
|
+
document.removeEventListener("keydown", aoEscape);
|
|
30
|
+
};
|
|
31
|
+
}, [aberto]);
|
|
32
|
+
const escolhida = useMemo(
|
|
33
|
+
() => opcoes.find((o) => o.valor === valor) ?? null,
|
|
34
|
+
[opcoes, valor]
|
|
35
|
+
);
|
|
36
|
+
const resultados = useMemo(() => {
|
|
37
|
+
const q = pesquisa.trim().toLowerCase();
|
|
38
|
+
if (!q) return opcoes.slice(0, maximo);
|
|
39
|
+
return opcoes.filter((o) => `${o.titulo} ${o.contexto ?? ""}`.toLowerCase().includes(q)).slice(0, maximo);
|
|
40
|
+
}, [opcoes, pesquisa, maximo]);
|
|
41
|
+
if (valor && escolhida) {
|
|
42
|
+
return /* @__PURE__ */ jsxs("div", { className: "cui-seletor-pesquisa flex items-center justify-between gap-3 border border-slate-200 bg-white px-3 py-2 rounded-lg dark:bg-slate-800 dark:border-slate-700", children: [
|
|
43
|
+
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
44
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate font-semibold text-proef-navy dark:text-slate-100", children: escolhida.titulo }),
|
|
45
|
+
escolhida.contexto && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-slate-500 dark:text-slate-400", children: escolhida.contexto })
|
|
46
|
+
] }),
|
|
47
|
+
/* @__PURE__ */ jsx(
|
|
48
|
+
"button",
|
|
49
|
+
{
|
|
50
|
+
type: "button",
|
|
51
|
+
onClick: () => onChange(null),
|
|
52
|
+
"aria-label": labels.limpar,
|
|
53
|
+
className: "shrink-0 px-1 text-slate-400 hover:text-proef-navy dark:hover:text-white",
|
|
54
|
+
children: "×"
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
] });
|
|
58
|
+
}
|
|
59
|
+
return /* @__PURE__ */ jsxs("div", { className: "cui-seletor-pesquisa relative", ref: caixa, children: [
|
|
60
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 border border-slate-200 bg-white px-3 py-2 rounded-lg dark:bg-slate-800 dark:border-slate-700", children: [
|
|
61
|
+
icone,
|
|
62
|
+
/* @__PURE__ */ jsx(
|
|
63
|
+
"input",
|
|
64
|
+
{
|
|
65
|
+
value: pesquisa,
|
|
66
|
+
onChange: (e) => {
|
|
67
|
+
setPesquisa(e.target.value);
|
|
68
|
+
setAberto(true);
|
|
69
|
+
},
|
|
70
|
+
onFocus: () => setAberto(true),
|
|
71
|
+
placeholder: labels.placeholder,
|
|
72
|
+
className: "w-full bg-transparent text-sm outline-none"
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
] }),
|
|
76
|
+
aberto && /* @__PURE__ */ jsxs("div", { className: "absolute z-20 mt-1 max-h-72 w-full overflow-auto border border-slate-200 bg-white shadow-xl rounded-xl dark:bg-slate-900 dark:border-slate-700", children: [
|
|
77
|
+
aCarregar && /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-sm text-slate-400", children: labels.aCarregar }),
|
|
78
|
+
erro && /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-sm text-red-600", children: labels.erro }),
|
|
79
|
+
resultados.map((opcao) => /* @__PURE__ */ jsxs(
|
|
80
|
+
"button",
|
|
81
|
+
{
|
|
82
|
+
type: "button",
|
|
83
|
+
onClick: () => {
|
|
84
|
+
onChange(opcao.valor);
|
|
85
|
+
setPesquisa("");
|
|
86
|
+
setAberto(false);
|
|
87
|
+
},
|
|
88
|
+
className: "block w-full px-3 py-2 text-left hover:bg-slate-50 dark:hover:bg-slate-800",
|
|
89
|
+
children: [
|
|
90
|
+
/* @__PURE__ */ jsx("span", { className: "block truncate text-sm font-medium text-proef-navy dark:text-slate-100", children: opcao.titulo }),
|
|
91
|
+
opcao.contexto && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-slate-500 dark:text-slate-400", children: opcao.contexto })
|
|
92
|
+
]
|
|
93
|
+
},
|
|
94
|
+
opcao.valor
|
|
95
|
+
)),
|
|
96
|
+
!aCarregar && !erro && resultados.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-sm text-slate-400", children: labels.semResultados }),
|
|
97
|
+
onTextoLivre && pesquisa.trim().length > 1 && /* @__PURE__ */ jsx(
|
|
98
|
+
"button",
|
|
99
|
+
{
|
|
100
|
+
type: "button",
|
|
101
|
+
onClick: () => {
|
|
102
|
+
onTextoLivre(pesquisa.trim());
|
|
103
|
+
setPesquisa("");
|
|
104
|
+
setAberto(false);
|
|
105
|
+
},
|
|
106
|
+
className: "block w-full border-t border-slate-100 px-3 py-2 text-left text-sm text-slate-600 hover:bg-slate-50 dark:border-slate-800 dark:text-slate-300 dark:hover:bg-slate-800",
|
|
107
|
+
children: labels.textoLivre ? labels.textoLivre(pesquisa.trim()) : pesquisa.trim()
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
] })
|
|
111
|
+
] });
|
|
112
|
+
}
|
|
113
|
+
export {
|
|
114
|
+
SeletorPesquisa as default
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=SeletorPesquisa.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeletorPesquisa.js","sources":["../../../../../../src/legacy/components/molecules/SeletorPesquisa/SeletorPesquisa.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\r\n\r\n/**\r\n * Seletor com pesquisa, para listas grandes vindas de outro sistema.\r\n *\r\n * Difere do `SearchSelect` em três coisas que o tornavam inutilizável nesses\r\n * casos: cada opção pode ter uma **segunda linha** (contexto — projeto, cliente,\r\n * plano), a pesquisa corre sobre esse contexto e não só sobre o título, e pode\r\n * aceitar **texto livre** quando o que a pessoa quer não está na lista.\r\n *\r\n * Fecha ao clicar fora e com Escape. Parece detalhe, mas dentro de um modal uma\r\n * lista que não fecha tapa o resto do formulário.\r\n * @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy.\r\n */\r\n\r\nexport interface OpcaoPesquisa {\r\n valor: string\r\n titulo: string\r\n /** Segunda linha: contexto que distingue homónimos. Também é pesquisável. */\r\n contexto?: string\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport interface SeletorPesquisaProps {\r\n opcoes: OpcaoPesquisa[]\r\n /** Opção escolhida (`valor`), ou null. */\r\n valor: string | null\r\n onChange: (valor: string | null) => void\r\n /**\r\n * Permite escolher o que foi escrito, mesmo sem estar na lista. Recebe o\r\n * texto; quem usa decide o que fazer com ele.\r\n */\r\n onTextoLivre?: (texto: string) => void\r\n aCarregar?: boolean\r\n erro?: boolean\r\n /** Máximo de opções mostradas — listas longas tornam o painel inútil. */\r\n maximo?: number\r\n labels: {\r\n placeholder: string\r\n semResultados: string\r\n aCarregar: string\r\n erro: string\r\n limpar: string\r\n /** Recebe o texto escrito, ex: `Registar sem tarefa: \"{texto}\"`. */\r\n textoLivre?: (texto: string) => string\r\n }\r\n /** Ícone opcional à esquerda do campo. */\r\n icone?: ReactNode\r\n}\r\n\r\n/** @deprecated Legacy — não usar em código novo. Ver Storybook › Legacy. */\r\nexport default function SeletorPesquisa({\r\n opcoes,\r\n valor,\r\n onChange,\r\n onTextoLivre,\r\n aCarregar = false,\r\n erro = false,\r\n maximo = 20,\r\n labels,\r\n icone,\r\n}: SeletorPesquisaProps) {\r\n const [pesquisa, setPesquisa] = useState('')\r\n const [aberto, setAberto] = useState(false)\r\n const caixa = useRef<HTMLDivElement>(null)\r\n\r\n useEffect(() => {\r\n if (!aberto) return\r\n const aoClicarFora = (e: MouseEvent) => {\r\n if (!caixa.current?.contains(e.target as Node)) setAberto(false)\r\n }\r\n const aoEscape = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') setAberto(false)\r\n }\r\n // `mousedown` e não `click`: fecha antes de o alvo reagir.\r\n document.addEventListener('mousedown', aoClicarFora)\r\n document.addEventListener('keydown', aoEscape)\r\n return () => {\r\n document.removeEventListener('mousedown', aoClicarFora)\r\n document.removeEventListener('keydown', aoEscape)\r\n }\r\n }, [aberto])\r\n\r\n const escolhida = useMemo(\r\n () => opcoes.find((o) => o.valor === valor) ?? null,\r\n [opcoes, valor]\r\n )\r\n\r\n const resultados = useMemo(() => {\r\n const q = pesquisa.trim().toLowerCase()\r\n if (!q) return opcoes.slice(0, maximo)\r\n return opcoes\r\n .filter((o) => `${o.titulo} ${o.contexto ?? ''}`.toLowerCase().includes(q))\r\n .slice(0, maximo)\r\n }, [opcoes, pesquisa, maximo])\r\n\r\n if (valor && escolhida) {\r\n return (\r\n <div className=\"cui-seletor-pesquisa flex items-center justify-between gap-3 border border-slate-200 bg-white px-3 py-2 rounded-lg dark:bg-slate-800 dark:border-slate-700\">\r\n <span className=\"min-w-0\">\r\n <span className=\"block truncate font-semibold text-proef-navy dark:text-slate-100\">{escolhida.titulo}</span>\r\n {escolhida.contexto && (\r\n <span className=\"block truncate text-xs text-slate-500 dark:text-slate-400\">{escolhida.contexto}</span>\r\n )}\r\n </span>\r\n <button\r\n type=\"button\"\r\n onClick={() => onChange(null)}\r\n aria-label={labels.limpar}\r\n className=\"shrink-0 px-1 text-slate-400 hover:text-proef-navy dark:hover:text-white\"\r\n >\r\n ×\r\n </button>\r\n </div>\r\n )\r\n }\r\n\r\n return (\r\n <div className=\"cui-seletor-pesquisa relative\" ref={caixa}>\r\n <div className=\"flex items-center gap-2 border border-slate-200 bg-white px-3 py-2 rounded-lg dark:bg-slate-800 dark:border-slate-700\">\r\n {icone}\r\n <input\r\n value={pesquisa}\r\n onChange={(e) => {\r\n setPesquisa(e.target.value)\r\n setAberto(true)\r\n }}\r\n onFocus={() => setAberto(true)}\r\n placeholder={labels.placeholder}\r\n className=\"w-full bg-transparent text-sm outline-none\"\r\n />\r\n </div>\r\n\r\n {aberto && (\r\n <div className=\"absolute z-20 mt-1 max-h-72 w-full overflow-auto border border-slate-200 bg-white shadow-xl rounded-xl dark:bg-slate-900 dark:border-slate-700\">\r\n {aCarregar && <p className=\"px-3 py-2 text-sm text-slate-400\">{labels.aCarregar}</p>}\r\n {erro && <p className=\"px-3 py-2 text-sm text-red-600\">{labels.erro}</p>}\r\n\r\n {resultados.map((opcao) => (\r\n <button\r\n key={opcao.valor}\r\n type=\"button\"\r\n onClick={() => {\r\n onChange(opcao.valor)\r\n setPesquisa('')\r\n setAberto(false)\r\n }}\r\n className=\"block w-full px-3 py-2 text-left hover:bg-slate-50 dark:hover:bg-slate-800\"\r\n >\r\n <span className=\"block truncate text-sm font-medium text-proef-navy dark:text-slate-100\">\r\n {opcao.titulo}\r\n </span>\r\n {opcao.contexto && (\r\n <span className=\"block truncate text-xs text-slate-500 dark:text-slate-400\">{opcao.contexto}</span>\r\n )}\r\n </button>\r\n ))}\r\n\r\n {!aCarregar && !erro && resultados.length === 0 && (\r\n <p className=\"px-3 py-2 text-sm text-slate-400\">{labels.semResultados}</p>\r\n )}\r\n\r\n {onTextoLivre && pesquisa.trim().length > 1 && (\r\n <button\r\n type=\"button\"\r\n onClick={() => {\r\n onTextoLivre(pesquisa.trim())\r\n setPesquisa('')\r\n setAberto(false)\r\n }}\r\n className=\"block w-full border-t border-slate-100 px-3 py-2 text-left text-sm text-slate-600 hover:bg-slate-50 dark:border-slate-800 dark:text-slate-300 dark:hover:bg-slate-800\"\r\n >\r\n {labels.textoLivre ? labels.textoLivre(pesquisa.trim()) : pesquisa.trim()}\r\n </button>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":[],"mappings":";;AAmDA,SAAwB,gBAAgB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,SAAS;AAAA,EACT;AAAA,EACA;AACF,GAAyB;AACvB,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,EAAE;AAC3C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,QAAQ,OAAuB,IAAI;AAEzC,YAAU,MAAM;AACd,QAAI,CAAC,OAAQ;AACb,UAAM,eAAe,CAAC,MAAkB;AACtC,UAAI,CAAC,MAAM,SAAS,SAAS,EAAE,MAAc,aAAa,KAAK;AAAA,IACjE;AACA,UAAM,WAAW,CAAC,MAAqB;AACrC,UAAI,EAAE,QAAQ,SAAU,WAAU,KAAK;AAAA,IACzC;AAEA,aAAS,iBAAiB,aAAa,YAAY;AACnD,aAAS,iBAAiB,WAAW,QAAQ;AAC7C,WAAO,MAAM;AACX,eAAS,oBAAoB,aAAa,YAAY;AACtD,eAAS,oBAAoB,WAAW,QAAQ;AAAA,IAClD;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,YAAY;AAAA,IAChB,MAAM,OAAO,KAAK,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK;AAAA,IAC/C,CAAC,QAAQ,KAAK;AAAA,EAAA;AAGhB,QAAM,aAAa,QAAQ,MAAM;AAC/B,UAAM,IAAI,SAAS,KAAA,EAAO,YAAA;AAC1B,QAAI,CAAC,EAAG,QAAO,OAAO,MAAM,GAAG,MAAM;AACrC,WAAO,OACJ,OAAO,CAAC,MAAM,GAAG,EAAE,MAAM,IAAI,EAAE,YAAY,EAAE,GAAG,YAAA,EAAc,SAAS,CAAC,CAAC,EACzE,MAAM,GAAG,MAAM;AAAA,EACpB,GAAG,CAAC,QAAQ,UAAU,MAAM,CAAC;AAE7B,MAAI,SAAS,WAAW;AACtB,WACE,qBAAC,OAAA,EAAI,WAAU,8JACb,UAAA;AAAA,MAAA,qBAAC,QAAA,EAAK,WAAU,WACd,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,oEAAoE,UAAA,UAAU,QAAO;AAAA,QACpG,UAAU,YACT,oBAAC,UAAK,WAAU,6DAA6D,oBAAU,SAAA,CAAS;AAAA,MAAA,GAEpG;AAAA,MACA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM,SAAS,IAAI;AAAA,UAC5B,cAAY,OAAO;AAAA,UACnB,WAAU;AAAA,UACX,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IAED,GACF;AAAA,EAEJ;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,iCAAgC,KAAK,OAClD,UAAA;AAAA,IAAA,qBAAC,OAAA,EAAI,WAAU,yHACZ,UAAA;AAAA,MAAA;AAAA,MACD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,CAAC,MAAM;AACf,wBAAY,EAAE,OAAO,KAAK;AAC1B,sBAAU,IAAI;AAAA,UAChB;AAAA,UACA,SAAS,MAAM,UAAU,IAAI;AAAA,UAC7B,aAAa,OAAO;AAAA,UACpB,WAAU;AAAA,QAAA;AAAA,MAAA;AAAA,IACZ,GACF;AAAA,IAEC,UACC,qBAAC,OAAA,EAAI,WAAU,kJACZ,UAAA;AAAA,MAAA,aAAa,oBAAC,KAAA,EAAE,WAAU,oCAAoC,iBAAO,WAAU;AAAA,MAC/E,QAAQ,oBAAC,KAAA,EAAE,WAAU,kCAAkC,iBAAO,MAAK;AAAA,MAEnE,WAAW,IAAI,CAAC,UACf;AAAA,QAAC;AAAA,QAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,MAAM;AACb,qBAAS,MAAM,KAAK;AACpB,wBAAY,EAAE;AACd,sBAAU,KAAK;AAAA,UACjB;AAAA,UACA,WAAU;AAAA,UAEV,UAAA;AAAA,YAAA,oBAAC,QAAA,EAAK,WAAU,0EACb,UAAA,MAAM,QACT;AAAA,YACC,MAAM,YACL,oBAAC,UAAK,WAAU,6DAA6D,gBAAM,SAAA,CAAS;AAAA,UAAA;AAAA,QAAA;AAAA,QAbzF,MAAM;AAAA,MAAA,CAgBd;AAAA,MAEA,CAAC,aAAa,CAAC,QAAQ,WAAW,WAAW,KAC5C,oBAAC,KAAA,EAAE,WAAU,oCAAoC,UAAA,OAAO,cAAA,CAAc;AAAA,MAGvE,gBAAgB,SAAS,KAAA,EAAO,SAAS,KACxC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,MAAM;AACb,yBAAa,SAAS,MAAM;AAC5B,wBAAY,EAAE;AACd,sBAAU,KAAK;AAAA,UACjB;AAAA,UACA,WAAU;AAAA,UAET,UAAA,OAAO,aAAa,OAAO,WAAW,SAAS,KAAA,CAAM,IAAI,SAAS,KAAA;AAAA,QAAK;AAAA,MAAA;AAAA,IAC1E,EAAA,CAEJ;AAAA,EAAA,GAEJ;AAEJ;"}
|