From 60b05e98e09cc3d7f7ab60859913895f0fdfe0d8 Mon Sep 17 00:00:00 2001 From: Titani Labaj <39532947+tlabaj@users.noreply.github.com> Date: Mon, 19 Dec 2022 13:32:33 -0500 Subject: [PATCH] V5 rebase (#8460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(Menu): fixed height issue with drilldown examples (#8033) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.27 - @patternfly/react-code-editor@4.82.27 - @patternfly/react-console@4.92.27 - @patternfly/react-core@4.250.2 - @patternfly/react-docs@5.102.32 - @patternfly/react-inline-edit-extension@4.86.28 - demo-app-ts@4.202.8 - @patternfly/react-log-viewer@4.87.22 - @patternfly/react-table@4.111.5 - @patternfly/react-topology@4.88.27 - @patternfly/react-virtualized-extension@4.88.27 * chore(docs): Release notes 2022.13 (#8168) * chore(docs): Release notes 2022.13 * release note updates * add screnshots and versions * update note * updates from comments Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.102.33 * chore(docs): Updated release notes (#8202) Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.102.34 * chore(Sidebar): converted examples to typescript (#8062) * chore(Banner): update tests to new react testing library standards (#8160) * chore(Banner): update tests to new react testing library standards * add additional test to test screenReaderText * replace toHaveTextContent with toBeInTheDocument matcher * add test to check for pf-u-screen-reader class * specify est timezone for jest to run with (#8151) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.28 - @patternfly/react-code-editor@4.82.28 - @patternfly/react-console@4.92.28 - @patternfly/react-core@4.250.3 - @patternfly/react-docs@5.102.35 - @patternfly/react-inline-edit-extension@4.86.29 - demo-app-ts@4.202.9 - @patternfly/react-log-viewer@4.87.23 - @patternfly/react-table@4.111.6 - @patternfly/react-topology@4.88.28 - @patternfly/react-virtualized-extension@4.88.28 * feature(Select): flag to put create option at top of typeahead (#8165) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.29 - @patternfly/react-code-editor@4.82.29 - @patternfly/react-console@4.92.29 - @patternfly/react-core@4.250.4 - @patternfly/react-docs@5.102.36 - @patternfly/react-inline-edit-extension@4.86.30 - demo-app-ts@4.202.10 - @patternfly/react-log-viewer@4.87.24 - @patternfly/react-table@4.111.7 - @patternfly/react-topology@4.88.29 - @patternfly/react-virtualized-extension@4.88.29 * fix(Dropdown next): Add support for forward ref and updated docs. (#8142) * fix(Dropdown next): Add support for forward ref and updated docs. * hide inner ref prop * hide innerRef Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.30 - @patternfly/react-code-editor@4.82.30 - @patternfly/react-console@4.92.30 - @patternfly/react-core@4.250.5 - @patternfly/react-docs@5.102.37 - @patternfly/react-inline-edit-extension@4.86.31 - demo-app-ts@4.202.11 - @patternfly/react-log-viewer@4.87.25 - @patternfly/react-table@4.111.8 - @patternfly/react-topology@4.88.30 - @patternfly/react-virtualized-extension@4.88.30 * chore(Title): update tests to new RTL standards (#8156) * chore(Title): update tests to new RTL standards * chore(Title): update tests to new RTL standards * chore(Title): update tests to new RTL standards Co-authored-by: Drew Amunategui II Co-authored-by: Drew Amunategui II * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.31 - @patternfly/react-code-editor@4.82.31 - @patternfly/react-console@4.92.31 - @patternfly/react-core@4.250.6 - @patternfly/react-docs@5.102.38 - @patternfly/react-inline-edit-extension@4.86.32 - demo-app-ts@4.202.12 - @patternfly/react-log-viewer@4.87.26 - @patternfly/react-table@4.111.9 - @patternfly/react-topology@4.88.31 - @patternfly/react-virtualized-extension@4.88.31 * docs(Empty state): Added EmptyStatePrimary to documentation (#8161) * docs(Empty state): Added EmptyStatePrimary to documentation * fix typo Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.32 - @patternfly/react-code-editor@4.82.32 - @patternfly/react-console@4.92.32 - @patternfly/react-core@4.250.7 - @patternfly/react-docs@5.102.39 - @patternfly/react-inline-edit-extension@4.86.33 - demo-app-ts@4.202.13 - @patternfly/react-log-viewer@4.87.27 - @patternfly/react-table@4.111.10 - @patternfly/react-topology@4.88.32 - @patternfly/react-virtualized-extension@4.88.32 * fix(Slider): correct tab order when input is above thumb (#8190) * chore(deps): update dependency @patternfly/documentation-framework to v1.2.43 (#8129) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.33 - @patternfly/react-code-editor@4.82.33 - @patternfly/react-console@4.92.33 - @patternfly/react-core@4.250.8 - @patternfly/react-docs@5.102.40 - @patternfly/react-inline-edit-extension@4.86.34 - demo-app-ts@4.202.14 - @patternfly/react-log-viewer@4.87.28 - @patternfly/react-table@4.111.11 - @patternfly/react-topology@4.88.33 - @patternfly/react-virtualized-extension@4.88.33 * feat(label+labelGroup): update aria-labels to include label text (#8192) * feat(label+labelGroup): update aria-labels to include editable label text * PR feedback from Eric * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.34 - @patternfly/react-code-editor@4.82.34 - @patternfly/react-console@4.92.34 - @patternfly/react-core@4.251.0 - @patternfly/react-docs@5.102.41 - @patternfly/react-inline-edit-extension@4.86.35 - demo-app-ts@4.202.15 - @patternfly/react-log-viewer@4.87.29 - @patternfly/react-table@4.111.12 - @patternfly/react-topology@4.88.34 - @patternfly/react-virtualized-extension@4.88.34 * chore(deps): update dependency @patternfly/documentation-framework to v1.2.44 (#8225) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(SkipToContent): converted examples to typescript (#8138) * chore(SkipToContent): converted examples to typescript * fix(SkipToContent): added trailing newline for linter * chore(TextInput): converted examples to typescript (#8137) * chore(TextInput): converted examples to typescript * fix(TextInput): removed problematic file * fix(TextInput): added file back with correct name * fix(TextInput): fixed requested changes * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.35 - @patternfly/react-code-editor@4.82.35 - @patternfly/react-console@4.92.35 - @patternfly/react-core@4.251.1 - @patternfly/react-docs@5.102.42 - @patternfly/react-inline-edit-extension@4.86.36 - demo-app-ts@4.202.16 - @patternfly/react-log-viewer@4.87.30 - @patternfly/react-table@4.111.13 - @patternfly/react-topology@4.88.35 - @patternfly/react-virtualized-extension@4.88.35 * fix(JumpLinks): clean up demo in a drawer (#8182) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.36 - @patternfly/react-code-editor@4.82.36 - @patternfly/react-console@4.92.36 - @patternfly/react-core@4.251.2 - @patternfly/react-docs@5.102.43 - @patternfly/react-inline-edit-extension@4.86.37 - demo-app-ts@4.202.17 - @patternfly/react-log-viewer@4.87.31 - @patternfly/react-table@4.111.14 - @patternfly/react-topology@4.88.36 - @patternfly/react-virtualized-extension@4.88.36 * TextArea test revamp (#8150) * Text area test revamp * Edit ref test * remove unnecessary tests * add tests for default behavior * add default validity test * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.37 - @patternfly/react-code-editor@4.82.37 - @patternfly/react-console@4.92.37 - @patternfly/react-core@4.251.3 - @patternfly/react-docs@5.102.44 - @patternfly/react-inline-edit-extension@4.86.38 - demo-app-ts@4.202.18 - @patternfly/react-log-viewer@4.87.32 - @patternfly/react-table@4.111.15 - @patternfly/react-topology@4.88.37 - @patternfly/react-virtualized-extension@4.88.37 * chore(deps): update dependency @patternfly/patternfly to v4.218.0 (#8234) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.38 - @patternfly/react-charts@6.94.8 - @patternfly/react-code-editor@4.82.38 - @patternfly/react-console@4.92.38 - @patternfly/react-core@4.251.4 - @patternfly/react-docs@5.102.45 - @patternfly/react-icons@4.92.7 - @patternfly/react-inline-edit-extension@4.86.39 - demo-app-ts@4.202.19 - @patternfly/react-log-viewer@4.87.33 - @patternfly/react-styles@4.91.7 - @patternfly/react-table@4.111.16 - @patternfly/react-tokens@4.93.7 - @patternfly/react-topology@4.88.38 - @patternfly/react-virtualized-extension@4.88.38 * chore(deps): update dependency @patternfly/patternfly to v4.219.0 (#8239) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * feat(DataList): pass button props to toggle (#8222) * feat(DataList): pass button props to toggle * fix duplicate id * missed an id * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.39 - @patternfly/react-charts@6.94.9 - @patternfly/react-code-editor@4.82.39 - @patternfly/react-console@4.92.39 - @patternfly/react-core@4.252.0 - @patternfly/react-docs@5.102.46 - @patternfly/react-icons@4.92.8 - @patternfly/react-inline-edit-extension@4.86.40 - demo-app-ts@4.202.20 - @patternfly/react-log-viewer@4.87.34 - @patternfly/react-styles@4.91.8 - @patternfly/react-table@4.111.17 - @patternfly/react-tokens@4.93.8 - @patternfly/react-topology@4.88.39 - @patternfly/react-virtualized-extension@4.88.39 * chore(SimpleList):convert to typescript (#8176) * chore(SimpleList):convert to typescript * updated types to match onSelect handler * updated types to match onSelect handler and various name changes Co-authored-by: Jan Wright * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.40 - @patternfly/react-code-editor@4.82.40 - @patternfly/react-console@4.92.40 - @patternfly/react-core@4.252.1 - @patternfly/react-docs@5.102.47 - @patternfly/react-inline-edit-extension@4.86.41 - demo-app-ts@4.202.21 - @patternfly/react-log-viewer@4.87.35 - @patternfly/react-table@4.111.18 - @patternfly/react-topology@4.88.40 - @patternfly/react-virtualized-extension@4.88.40 * fix(Dropdown): enabled right aligned dropdown with isFlipEnabled (#8224) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.41 - @patternfly/react-code-editor@4.82.41 - @patternfly/react-console@4.92.41 - @patternfly/react-core@4.252.2 - @patternfly/react-docs@5.102.48 - @patternfly/react-inline-edit-extension@4.86.42 - demo-app-ts@4.202.22 - @patternfly/react-log-viewer@4.87.36 - @patternfly/react-table@4.111.19 - @patternfly/react-topology@4.88.41 - @patternfly/react-virtualized-extension@4.88.41 * feat(Wizard,ClipboardCopy): add OUIA props to WizardNav, WizardNavItem, ClipboardCopy (#8193) * feat(Wizard,ClipboardCopy): add OUIA props to WizardNav, WizardNavItem, ClipboardCopy * add missing props * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.42 - @patternfly/react-code-editor@4.82.42 - @patternfly/react-console@4.92.42 - @patternfly/react-core@4.253.0 - @patternfly/react-docs@5.102.49 - @patternfly/react-inline-edit-extension@4.86.43 - demo-app-ts@4.202.23 - @patternfly/react-log-viewer@4.87.37 - @patternfly/react-table@4.111.20 - @patternfly/react-topology@4.88.42 - @patternfly/react-virtualized-extension@4.88.42 * chore(Slider): revert taborder update (#8273) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.43 - @patternfly/react-code-editor@4.82.43 - @patternfly/react-console@4.92.43 - @patternfly/react-core@4.253.1 - @patternfly/react-docs@5.102.50 - @patternfly/react-inline-edit-extension@4.86.44 - demo-app-ts@4.202.24 - @patternfly/react-log-viewer@4.87.38 - @patternfly/react-table@4.111.21 - @patternfly/react-topology@4.88.43 - @patternfly/react-virtualized-extension@4.88.43 * feat(Topology): Add option to fit layout to screen upon layout completion (#8210) * fix(CodeEditor): use codeEditorControls and clean up overall (#7931) * fix(CodeEditor): use codeEditorControls and clean up overall * fix lint errors * use better variable names * clean up per PR comments * add back useCallback * clean up * clean up * fix lint errors * add console warnings when using deprecated props * fix lint errors * update warning messages * fix lint again * feat(menu): add optional danger state for menu items (#8131) * feat(menu): add optional danger state for menu items * docs(menu): add demo for danger state * chore: move example to match html * chore(deps): update dependency @patternfly/documentation-framework to v1.2.46 (#8241) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.44 - @patternfly/react-code-editor@4.82.44 - @patternfly/react-console@4.92.44 - @patternfly/react-core@4.254.0 - @patternfly/react-docs@5.102.51 - @patternfly/react-inline-edit-extension@4.86.45 - demo-app-ts@4.203.0 - @patternfly/react-integration@4.206.0 - @patternfly/react-log-viewer@4.87.39 - @patternfly/react-table@4.111.22 - @patternfly/react-topology@4.89.0 - @patternfly/react-virtualized-extension@4.88.44 * fix(DualListSelector): Add/remove button didn't work if search is used (#8269) * feat(topology): Allow tooltip usage on pipeline task node badges (#8208) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.45 - @patternfly/react-code-editor@4.82.45 - @patternfly/react-console@4.92.45 - @patternfly/react-core@4.254.1 - @patternfly/react-docs@5.102.52 - @patternfly/react-inline-edit-extension@4.86.46 - demo-app-ts@4.204.0 - @patternfly/react-integration@4.207.0 - @patternfly/react-log-viewer@4.87.40 - @patternfly/react-table@4.111.23 - @patternfly/react-topology@4.90.0 - @patternfly/react-virtualized-extension@4.88.45 * feat: add ouia support to dropdown next (#8135) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.46 - @patternfly/react-code-editor@4.82.46 - @patternfly/react-console@4.92.46 - @patternfly/react-core@4.255.0 - @patternfly/react-docs@5.102.53 - @patternfly/react-inline-edit-extension@4.86.47 - demo-app-ts@4.204.1 - @patternfly/react-log-viewer@4.87.41 - @patternfly/react-table@4.111.24 - @patternfly/react-topology@4.90.1 - @patternfly/react-virtualized-extension@4.88.46 * chore(button): added inline progress variant to progress demos (#8172) * fix(Alert): prevent error being thrown when using invalid variant (#8229) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.47 - @patternfly/react-code-editor@4.82.47 - @patternfly/react-console@4.92.47 - @patternfly/react-core@4.255.1 - @patternfly/react-docs@5.102.54 - @patternfly/react-inline-edit-extension@4.86.48 - demo-app-ts@4.204.2 - @patternfly/react-log-viewer@4.87.42 - @patternfly/react-table@4.111.25 - @patternfly/react-topology@4.90.2 - @patternfly/react-virtualized-extension@4.88.47 * next(Wizard): Allow for WizardStep to better control state from props entry-point, include index (#8218) * next(Wizard): Allow for WizardStep to better control state from props entrypoint, include index * address feedback * fix a couple existing wizard demos, update naming of combined steps in 'next' wizard context * disable Back/Cancel for async Next step in Kitchen sink example * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.48 - @patternfly/react-code-editor@4.82.48 - @patternfly/react-console@4.92.48 - @patternfly/react-core@4.255.2 - @patternfly/react-docs@5.102.55 - @patternfly/react-inline-edit-extension@4.86.49 - demo-app-ts@4.204.3 - @patternfly/react-log-viewer@4.87.43 - @patternfly/react-table@4.111.26 - @patternfly/react-topology@4.90.3 - @patternfly/react-virtualized-extension@4.88.48 * chore(beta-components): promote candidates 2022.14 (#8246) * chore(beta-components): promote candidates 2022.14 * remove more beta flags * feat(MultipleFileUpload): add aria live region to internal Progress (#8242) * feat(MultipleFileUpload): add aria live region to internal Progress * add floor/cap load percentage * update description * update and add tests * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.49 - @patternfly/react-code-editor@4.82.49 - @patternfly/react-console@4.92.49 - @patternfly/react-core@4.256.0 - @patternfly/react-docs@5.102.56 - @patternfly/react-inline-edit-extension@4.86.50 - demo-app-ts@4.204.4 - @patternfly/react-log-viewer@4.87.44 - @patternfly/react-table@4.111.27 - @patternfly/react-topology@4.90.4 - @patternfly/react-virtualized-extension@4.88.49 * feat(Banner): add support for status icons (#8195) * feat(Banner): add support for status icons * Made icon support an example instead of new props * Added flex layout to status example * Updated snapshot after rebase * Updated logic for rendering sr text * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.50 - @patternfly/react-code-editor@4.82.50 - @patternfly/react-console@4.92.50 - @patternfly/react-core@4.257.0 - @patternfly/react-docs@5.102.57 - @patternfly/react-inline-edit-extension@4.86.51 - demo-app-ts@4.204.5 - @patternfly/react-log-viewer@4.87.45 - @patternfly/react-table@4.111.28 - @patternfly/react-topology@4.90.5 - @patternfly/react-virtualized-extension@4.88.50 * Create workflow for extensions issues (#8281) * Create workflow for extensions issues Whenever a patternfly-react issue is tagged with the 'extensions' label, it will automatically get added to the 'PatternFly Extensions' project board * change label name * fix(Timestamp): updated logic for rendering datetime attribute (#8205) * fix(Timestamp): updated logic for rendering datetime attribute * Updated spread props to prevent duplicate datetime attribute * Made updates per PR feedback * Added new utils file to helpers index * Removed timezone from dates in tests * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.51 - @patternfly/react-code-editor@4.82.51 - @patternfly/react-console@4.92.51 - @patternfly/react-core@4.257.1 - @patternfly/react-docs@5.102.58 - @patternfly/react-inline-edit-extension@4.86.52 - demo-app-ts@4.204.6 - @patternfly/react-log-viewer@4.87.46 - @patternfly/react-table@4.111.29 - @patternfly/react-topology@4.90.6 - @patternfly/react-virtualized-extension@4.88.51 * chore(deps): update dependency @patternfly/documentation-framework to v1.2.48 (#8282) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.102.59 * feat(Popover): update default flip behavior and width (#8191) * feat(Popover): update default flip behavior and width * fix flip positions for diagonals * revert default for autoWidth for now * remove old comment * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.52 - @patternfly/react-code-editor@4.82.52 - @patternfly/react-console@4.92.52 - @patternfly/react-core@4.258.0 - @patternfly/react-docs@5.102.60 - @patternfly/react-inline-edit-extension@4.86.53 - demo-app-ts@4.204.7 - @patternfly/react-log-viewer@4.87.47 - @patternfly/react-table@4.111.30 - @patternfly/react-topology@4.90.7 - @patternfly/react-virtualized-extension@4.88.52 * chore(deps): update dependency @patternfly/patternfly to v4.219.1 (#8288) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.53 - @patternfly/react-charts@6.94.10 - @patternfly/react-code-editor@4.82.53 - @patternfly/react-console@4.92.53 - @patternfly/react-core@4.258.1 - @patternfly/react-docs@5.102.61 - @patternfly/react-icons@4.92.9 - @patternfly/react-inline-edit-extension@4.86.54 - demo-app-ts@4.204.8 - @patternfly/react-log-viewer@4.87.48 - @patternfly/react-styles@4.91.9 - @patternfly/react-table@4.111.31 - @patternfly/react-tokens@4.93.9 - @patternfly/react-topology@4.90.8 - @patternfly/react-virtualized-extension@4.88.53 * fix(Pagination): prevented regenerating random id on each render (#8175) * fix(Pagination): prevented regenerating random id on each render * fix duplicate ids in existing demos * fix(Pagination): update column management table demo pagination * add unit test * Add pipeline groups (#8278) * Add pipeline groups * Breakout topology package options for readability * chore(dropdown-like components): updated isFlipEnabled to true by def… (#8215) * chore(dropdown-like components): updated isFlipEnabled to true by default * Updated snapshots * Updated failing integration test * Updated conditional for adding static class * Updated static logic based on Core updates * Updated ContextSelector * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.54 - @patternfly/react-code-editor@4.82.54 - @patternfly/react-console@4.92.54 - @patternfly/react-core@4.258.2 - @patternfly/react-docs@5.102.62 - @patternfly/react-inline-edit-extension@4.86.55 - demo-app-ts@4.204.9 - @patternfly/react-integration@4.207.1 - @patternfly/react-log-viewer@4.87.49 - @patternfly/react-table@4.111.32 - @patternfly/react-topology@4.90.9 - @patternfly/react-virtualized-extension@4.88.54 * chore: bump @patternfly/patternfly to 4.219.2 (#8296) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.55 - @patternfly/react-charts@6.94.11 - @patternfly/react-code-editor@4.82.55 - @patternfly/react-console@4.92.55 - @patternfly/react-core@4.258.3 - @patternfly/react-docs@5.102.63 - @patternfly/react-icons@4.92.10 - @patternfly/react-inline-edit-extension@4.86.56 - demo-app-ts@4.204.10 - @patternfly/react-log-viewer@4.87.50 - @patternfly/react-styles@4.91.10 - @patternfly/react-table@4.111.33 - @patternfly/react-tokens@4.93.10 - @patternfly/react-topology@4.90.10 - @patternfly/react-virtualized-extension@4.88.55 * Fix group labels, revert breaking change (#8299) * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.102.64 - demo-app-ts@4.204.11 - @patternfly/react-integration@4.207.2 - @patternfly/react-topology@4.90.11 * Update extensions.yml * Update add-new-issues-to-project.yml * chore(docs): Added release notes 2022.14 (#8301) * chore(docs): Added rleases notes 2022.14 * updated topology version * fixes from reviews Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.56 - @patternfly/react-code-editor@4.82.56 - @patternfly/react-console@4.92.56 - @patternfly/react-core@4.258.4 - @patternfly/react-docs@5.102.65 - @patternfly/react-inline-edit-extension@4.86.57 - demo-app-ts@4.204.12 - @patternfly/react-log-viewer@4.87.51 - @patternfly/react-table@4.111.34 - @patternfly/react-topology@4.90.12 - @patternfly/react-virtualized-extension@4.88.56 * chore(deps): update dependency @patternfly/documentation-framework to v1.2.61 (#8290) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.102.66 * Set status decorators to be opaque. (#8335) * chore(tests): created shareable button mock (#8244) * chore(Backdrop): update component unit tests to meet new standards with RTL (#8232) Co-authored-by: Drew Amunategui II * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.57 - @patternfly/react-code-editor@4.82.57 - @patternfly/react-console@4.92.57 - @patternfly/react-core@4.258.5 - @patternfly/react-docs@5.102.67 - @patternfly/react-inline-edit-extension@4.86.58 - demo-app-ts@4.204.13 - @patternfly/react-log-viewer@4.87.52 - @patternfly/react-table@4.111.35 - @patternfly/react-topology@4.90.13 - @patternfly/react-virtualized-extension@4.88.57 * Bug Fix #8311 (#8312) Bug - Label - hrefs in compact example have wrong anchor tag #8311 * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.58 - @patternfly/react-code-editor@4.82.58 - @patternfly/react-console@4.92.58 - @patternfly/react-core@4.258.6 - @patternfly/react-docs@5.102.68 - @patternfly/react-inline-edit-extension@4.86.59 - demo-app-ts@4.204.14 - @patternfly/react-log-viewer@4.87.53 - @patternfly/react-table@4.111.36 - @patternfly/react-topology@4.90.14 - @patternfly/react-virtualized-extension@4.88.58 * fix(TimePicker): fixed bugs when updating time/minTime/maxTime props (#8267) * fix(TimePicker): fixed bugs when updating time/minTime/maxTime props * Added logic to update minTime and maxTime states * Updated unit tests * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.59 - @patternfly/react-code-editor@4.82.59 - @patternfly/react-console@4.92.59 - @patternfly/react-core@4.258.7 - @patternfly/react-docs@5.102.69 - @patternfly/react-inline-edit-extension@4.86.60 - demo-app-ts@4.204.15 - @patternfly/react-log-viewer@4.87.54 - @patternfly/react-table@4.111.37 - @patternfly/react-topology@4.90.15 - @patternfly/react-virtualized-extension@4.88.59 * chore(TextArea): converted examples to typescript (#8186) * fix(TextArea): redo * fix(TextArea): made requested changes * fix(TextArea): typed functions and changed labels * fix(bulk-select): fixed toggle spacing (#8326) * fix(bulk-select): fixed toggle spacing * chore(bulkselect): pr feedback * chore(ToggleGroup): converted examples to typescript (#8266) * chore(ToggleGroup): converted examples to typescript * fix(ToggleGroup): refactored states and typed function arguments * fix(ToggleGroup): removed unnecessary text * fix(ToggleGroup): fixed requested changes * fix(ToggleGroup): fixed requested changes * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.60 - @patternfly/react-code-editor@4.82.60 - @patternfly/react-console@4.92.60 - @patternfly/react-core@4.258.8 - @patternfly/react-docs@5.102.70 - @patternfly/react-inline-edit-extension@4.86.61 - demo-app-ts@4.204.16 - @patternfly/react-log-viewer@4.87.55 - @patternfly/react-table@4.111.38 - @patternfly/react-topology@4.90.16 - @patternfly/react-virtualized-extension@4.88.60 * feat(Popper, misc): allow components to customize popper z-index (#8310) * feat(Popper, misc): allow components to customize popper z-index * update some prop descriptions * update desc * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.61 - @patternfly/react-code-editor@4.82.61 - @patternfly/react-console@4.92.61 - @patternfly/react-core@4.259.0 - @patternfly/react-docs@5.102.71 - @patternfly/react-inline-edit-extension@4.86.62 - demo-app-ts@4.204.17 - @patternfly/react-log-viewer@4.87.56 - @patternfly/react-table@4.111.39 - @patternfly/react-topology@4.90.17 - @patternfly/react-virtualized-extension@4.88.61 * feat(Progress): added helper text (#8307) * feat(Progress): added helper text * enabled custom components to be passed as children of ProgressHelperText * spread props in ProgressHelperText * improved prop description * removed default isLiveRegion * marked helper text prop as beta * marked example as beta * added custom component example * refactored to make ProgressHelperText a basic wrapper component * added locally defined capitalize function * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.62 - @patternfly/react-code-editor@4.82.62 - @patternfly/react-console@4.92.62 - @patternfly/react-core@4.260.0 - @patternfly/react-docs@5.102.72 - @patternfly/react-inline-edit-extension@4.86.63 - demo-app-ts@4.204.18 - @patternfly/react-log-viewer@4.87.57 - @patternfly/react-table@4.111.40 - @patternfly/react-topology@4.90.18 - @patternfly/react-virtualized-extension@4.88.62 * Update README with create-react-app and YAML help (#8188) I ran into some trouble using the code editor in my project. The main problems were that I had to do extra work that the docs didn't cover because I bootstrapped my project with `create-react-app` and I needed YAML highlighting support which required an extra plugin. This doc update should make it easier for anyone who's in the same boat :) * chore(Text): update tests to new react testing library standards (#8280) * chore(Text): update tests to new react testing library standards * removed data-pf-content attribute and tests * added tests to check for no class names * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.63 - @patternfly/react-code-editor@4.82.63 - @patternfly/react-console@4.92.63 - @patternfly/react-core@4.260.1 - @patternfly/react-docs@5.102.73 - @patternfly/react-inline-edit-extension@4.86.64 - demo-app-ts@4.204.19 - @patternfly/react-log-viewer@4.87.58 - @patternfly/react-table@4.111.41 - @patternfly/react-topology@4.90.19 - @patternfly/react-virtualized-extension@4.88.63 * feat(MultipleFileUpload): added support for helper text (#8344) * feat(MultipleFileUpload): added support for helper text * adjusted verbiage * added example description * adjusted prop name * adjusted forced error checkbox label * refactored to make helper text component fully consumer managed * Updated example comment Co-authored-by: Jenny <32821331+jenny-s51@users.noreply.github.com> Co-authored-by: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> Co-authored-by: Jenny <32821331+jenny-s51@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.64 - @patternfly/react-code-editor@4.82.64 - @patternfly/react-console@4.92.64 - @patternfly/react-core@4.261.0 - @patternfly/react-docs@5.102.74 - @patternfly/react-inline-edit-extension@4.86.65 - demo-app-ts@4.204.20 - @patternfly/react-log-viewer@4.87.59 - @patternfly/react-table@4.111.42 - @patternfly/react-topology@4.90.20 - @patternfly/react-virtualized-extension@4.88.64 * feat(MenuInput): use SearchInput instead of TextInput (#8329) * feat(MenuInput): use SearchInput instead of TextInput * fix cypress test * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.65 - @patternfly/react-code-editor@4.82.65 - @patternfly/react-console@4.92.65 - @patternfly/react-core@4.262.0 - @patternfly/react-docs@5.102.75 - @patternfly/react-inline-edit-extension@4.86.66 - demo-app-ts@4.205.0 - @patternfly/react-integration@4.208.0 - @patternfly/react-log-viewer@4.87.60 - @patternfly/react-table@4.111.43 - @patternfly/react-topology@4.90.21 - @patternfly/react-virtualized-extension@4.88.65 * fix(NumberInput): allow user to back out number to type input (#8304) * fix(NumberInput): allow user to back out number to type input * fix test * fix plus logic for undefined * pr feedback * add example desc * update example desc * update examples for empty input * add integration test, update integration test name * feat(spinner): added isInline, updated link button (#8328) * feat(spinner): added isInline, updated link button * chore(button): update snaps * chore(spinner/button): PR feedback * fix(Popper): add display contents to wrapping divs (#8317) * fix(Popper): add display contents to wrapping divs * update snap * restore old popper update for content changes * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.92.66 - @patternfly/react-code-editor@4.82.66 - @patternfly/react-console@4.92.66 - @patternfly/react-core@4.263.0 - @patternfly/react-docs@5.102.76 - @patternfly/react-inline-edit-extension@4.86.67 - demo-app-ts@4.205.1 - @patternfly/react-integration@4.208.1 - @patternfly/react-log-viewer@4.87.61 - @patternfly/react-table@4.111.44 - @patternfly/react-topology@4.90.22 - @patternfly/react-virtualized-extension@4.88.66 * chore(tabs): reworked tabs demos based on design/core updates (#8286) * chore(tabs): reworked demos for consistency with core updates * revert dashwrapper changes * chore(tabs): add bottom border to secondary variants * remove downloads.html * PR feedback * fix title sizes * fixed status card title size * fix remaining cards * remove comment * remove comment * feat(Tabs): add TabAction, update core ver (#8348) * feat(Tabs): add TabAction, update core ver * desc updates, prop update * adjust actions default order, add missing flag * update description, add classname to span * chore(deps): update dependency @patternfly/patternfly to v4.221.2 (#8358) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.0 - @patternfly/react-charts@6.94.12 - @patternfly/react-code-editor@4.82.67 - @patternfly/react-console@4.93.0 - @patternfly/react-core@4.264.0 - @patternfly/react-docs@5.103.0 - @patternfly/react-icons@4.93.0 - @patternfly/react-inline-edit-extension@4.86.68 - demo-app-ts@4.205.2 - @patternfly/react-log-viewer@4.87.62 - @patternfly/react-styles@4.92.0 - @patternfly/react-table@4.111.45 - @patternfly/react-tokens@4.94.0 - @patternfly/react-topology@4.90.23 - @patternfly/react-virtualized-extension@4.88.67 * chore:(docs): rel notes 2022 (#8376) * chore:(docs): rel notes 2022 * added screenshots * fix typos * Fix typo so i can merge Co-authored-by: Titani Co-authored-by: Nicole Thoen * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.103.1 * chore: fix release notes typos (#8379) * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.103.2 * fix(build): stopped shipping mock files (#8396) * fix: react-core subpaths for next/deprecated modules (#8341) * chore(Tooltip): converted examples to typescript (#8052) * chore(Tooltip): converted examples to typescript * chore(Tooltip): fixed selection variable typing issue * chore(Tooltip): shortened updatedTrigger code * chore(Tooltip): changed span to Button in basic example * remove unnecessary tabindex Co-authored-by: nicolethoen * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.1 - @patternfly/react-code-editor@4.82.68 - @patternfly/react-console@4.93.1 - @patternfly/react-core@4.264.1 - @patternfly/react-docs@5.103.3 - @patternfly/react-inline-edit-extension@4.86.69 - demo-app-ts@4.205.3 - @patternfly/react-log-viewer@4.87.63 - @patternfly/react-table@4.111.46 - @patternfly/react-topology@4.90.24 - @patternfly/react-virtualized-extension@4.88.68 * chore(ComposableTable): Update custom row wrapper example (#8365) * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.103.4 - @patternfly/react-inline-edit-extension@4.86.70 - @patternfly/react-table@4.111.47 * fix(Dropdown next): Added itemId to DropdownItem props (#8356) Co-authored-by: Titani * feat: add pf-screen-reader for screen reader text to Badge (#8361) * feat: add pf-screen-reader for screen reader text to Badge #8354 * test: update snapshots according to new classname for badge reader * fix: badge screen reader prop, delete static class * update screen reader classname Signed-off-by: erkanercan * fix: move screen reader span below children, update unread examples Signed-off-by: erkanercan * fix: correct example typo Signed-off-by: erkanercan Signed-off-by: erkanercan * fix(Menu): updated breadcrumb drilldown example (#8385) * Create "deprecated" subpaths in react-table (#8381) * change base to main * revert index.ts change * Update patternfly-docs.source.js * fix(TimePicker): removed redundant onBlur (#8366) * chore(deps): update dependency @patternfly/patternfly to v4.221.3 (#8382) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * feature(Wizard/next): Allow for async functions when navigating between steps, and add isCollapsible prop control to WizardStep (#8332) * chore(deps): update dependency @patternfly/documentation-framework to v1.2.68 (#8367) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.2 - @patternfly/react-charts@6.94.13 - @patternfly/react-code-editor@4.82.69 - @patternfly/react-console@4.93.2 - @patternfly/react-core@4.265.0 - @patternfly/react-docs@5.103.5 - @patternfly/react-icons@4.93.1 - @patternfly/react-inline-edit-extension@4.86.71 - demo-app-ts@4.205.4 - @patternfly/react-log-viewer@4.87.64 - @patternfly/react-styles@4.92.1 - @patternfly/react-table@4.111.48 - @patternfly/react-tokens@4.94.1 - @patternfly/react-topology@4.90.25 - @patternfly/react-virtualized-extension@4.88.69 * chore(Tabs): converted examples to TypeScript (#8337) * chore(Tabs): converted examples to TypeScript * fix(Tabs): fixed file name * fix(Tabs): typed function arguments * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.3 - @patternfly/react-code-editor@4.82.70 - @patternfly/react-console@4.93.3 - @patternfly/react-core@4.265.1 - @patternfly/react-docs@5.103.6 - @patternfly/react-inline-edit-extension@4.86.72 - demo-app-ts@4.205.5 - @patternfly/react-log-viewer@4.87.65 - @patternfly/react-table@4.111.49 - @patternfly/react-topology@4.90.26 - @patternfly/react-virtualized-extension@4.88.70 * chore(deps): update dependency @patternfly/documentation-framework to v1.2.69 (#8411) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.103.7 * fix(AdvancedSearchMenu): allow spaces in search form field values (#8372) When the user uses a space in a form field value this will get wrapped in quotes within the Search input. Closes #8369 * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.4 - @patternfly/react-code-editor@4.82.71 - @patternfly/react-console@4.93.4 - @patternfly/react-core@4.265.2 - @patternfly/react-docs@5.103.8 - @patternfly/react-inline-edit-extension@4.86.73 - demo-app-ts@4.205.6 - @patternfly/react-log-viewer@4.87.66 - @patternfly/react-table@4.111.50 - @patternfly/react-topology@4.90.27 - @patternfly/react-virtualized-extension@4.88.71 * feat(ClipboardCopy, Truncate): add removeFindDomNode (#8371) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.5 - @patternfly/react-code-editor@4.82.72 - @patternfly/react-console@4.93.5 - @patternfly/react-core@4.266.0 - @patternfly/react-docs@5.103.9 - @patternfly/react-inline-edit-extension@4.86.74 - demo-app-ts@4.205.7 - @patternfly/react-log-viewer@4.87.67 - @patternfly/react-table@4.111.51 - @patternfly/react-topology@4.90.28 - @patternfly/react-virtualized-extension@4.88.72 * chore(Panel): update component unit tests to meet new RTL standards (#8346) * chore(Panel): update component unit tests to meet new standards with RTL #7594 * few small changes to Test Titles for consistency Co-authored-by: Drew Amunategui II * chore(Sidebar): update tests to new react testing library standards (#8342) * chore(Sidebar): update tests to new react testing library standards * Refactored test to check for class names that exist by default * Changed query to include parentElement * Added test general existence of class name test * Refactored the test for checking different width types * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.6 - @patternfly/react-code-editor@4.82.73 - @patternfly/react-console@4.93.6 - @patternfly/react-core@4.266.1 - @patternfly/react-docs@5.103.10 - @patternfly/react-inline-edit-extension@4.86.75 - demo-app-ts@4.205.8 - @patternfly/react-log-viewer@4.87.68 - @patternfly/react-table@4.111.52 - @patternfly/react-topology@4.90.29 - @patternfly/react-virtualized-extension@4.88.73 * chore(pagination): fixed filter not applying in sticky example (#8133) * chore(pagination): fixed filter not applying in sticy example * feat: add page and pagesection to example * Removed Page components Co-authored-by: Eric Olkowski * fix(Pagination): Added support for insets (#8412) * fix(Pagination): Added support for insets * remove 3xl inset * update widget id in example * add usePageInsets prop Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.7 - @patternfly/react-code-editor@4.82.74 - @patternfly/react-console@4.93.7 - @patternfly/react-core@4.266.2 - @patternfly/react-docs@5.103.11 - @patternfly/react-inline-edit-extension@4.86.76 - demo-app-ts@4.205.9 - @patternfly/react-log-viewer@4.87.69 - @patternfly/react-table@4.111.53 - @patternfly/react-topology@4.90.30 - @patternfly/react-virtualized-extension@4.88.74 * Core bump 4 222 3 (#8420) * chore(deps): update dependency @patternfly/patternfly to v4.222.3 * remove wait Co-authored-by: Titani * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.8 - @patternfly/react-charts@6.94.14 - @patternfly/react-code-editor@4.82.75 - @patternfly/react-console@4.93.8 - @patternfly/react-core@4.266.3 - @patternfly/react-docs@5.103.12 - @patternfly/react-icons@4.93.2 - @patternfly/react-inline-edit-extension@4.86.77 - demo-app-ts@4.205.10 - @patternfly/react-integration@4.208.2 - @patternfly/react-log-viewer@4.87.70 - @patternfly/react-styles@4.92.2 - @patternfly/react-table@4.111.54 - @patternfly/react-tokens@4.94.2 - @patternfly/react-topology@4.90.31 - @patternfly/react-virtualized-extension@4.88.75 * feat(Menu): add drilldown filter demo, add flag to support demo & fix some keyboard interaction (#8405) * feat(Menu): add drilldown filter demo, add flag to support demo & fix some keyboard interaction * alternate method * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.9 - @patternfly/react-code-editor@4.82.76 - @patternfly/react-console@4.93.9 - @patternfly/react-core@4.267.0 - @patternfly/react-docs@5.103.13 - @patternfly/react-inline-edit-extension@4.86.78 - demo-app-ts@4.205.11 - @patternfly/react-log-viewer@4.87.71 - @patternfly/react-table@4.111.55 - @patternfly/react-topology@4.90.32 - @patternfly/react-virtualized-extension@4.88.76 * feat(Table): add sticky modifiers to Td (#8391) * feat(Table): allow sticky Td * update description * update disabled type, update desc * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.103.14 - @patternfly/react-inline-edit-extension@4.86.79 - @patternfly/react-table@4.112.0 * chore(deps): update dependency @patternfly/patternfly to v4.222.4 (#8421) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * fix(VncConsole): prevent running initialization code more than once (#8373) (#8374) The functions that were on the dependency list of the useEffect hook got redefined each time the component got updated, resulting in the component's initialization code, from within the useEffect hook, to be running more than once. That was unwanted behavior and the useCallback wrappers should prevent it. * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.10 - @patternfly/react-charts@6.94.15 - @patternfly/react-code-editor@4.82.77 - @patternfly/react-console@4.93.10 - @patternfly/react-core@4.267.1 - @patternfly/react-docs@5.103.15 - @patternfly/react-icons@4.93.3 - @patternfly/react-inline-edit-extension@4.86.80 - demo-app-ts@4.205.12 - @patternfly/react-log-viewer@4.87.72 - @patternfly/react-styles@4.92.3 - @patternfly/react-table@4.112.1 - @patternfly/react-tokens@4.94.3 - @patternfly/react-topology@4.90.33 - @patternfly/react-virtualized-extension@4.88.77 * chore(deps): update dependency @patternfly/documentation-framework to v1.2.70 (#8427) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> * chore(release): releasing packages [ci skip] - @patternfly/react-docs@5.103.16 * fix(Menu): removed li wrapper from breadcrumb example (#8433) * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.11 - @patternfly/react-code-editor@4.82.78 - @patternfly/react-console@4.93.11 - @patternfly/react-core@4.267.2 - @patternfly/react-docs@5.103.17 - @patternfly/react-inline-edit-extension@4.86.81 - demo-app-ts@4.205.13 - @patternfly/react-log-viewer@4.87.73 - @patternfly/react-table@4.112.2 - @patternfly/react-topology@4.90.34 - @patternfly/react-virtualized-extension@4.88.78 * Fix Nav Flyout Accessibility (#8279) * fix(NavItem): disallow flyout and link props to both be defined on NavItem * docs(Navigation): remove links from NavItems with flyouts * fix(NavItem): remove aria-expanded prop * fix(NavItem): use a button for Component if there is a flyout * fix(NavItem): allow flyout to be opened on pressing Enter * fix(MenuItem): disallow flyoutMenu and link props to both be defined * docs(Navigation): remove links from MenuItems with flyouts * fix(SelectOption): make props conditional to align with MenuItemProps * fix(DropdownItem): make props conditional to align with MenuItemProps * fix(NavItem): revert conditional prop changes * fix(NavItem): fix opening nested MenuItem-based flyouts with keyboard * fix(NavItem): add a console.err message if to and flyout are used together * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.12 - @patternfly/react-code-editor@4.82.79 - @patternfly/react-console@4.93.12 - @patternfly/react-core@4.267.3 - @patternfly/react-docs@5.103.18 - @patternfly/react-inline-edit-extension@4.86.82 - demo-app-ts@4.205.14 - @patternfly/react-integration@4.208.3 - @patternfly/react-log-viewer@4.87.74 - @patternfly/react-table@4.112.3 - @patternfly/react-topology@4.90.35 - @patternfly/react-virtualized-extension@4.88.79 * chore(CalendarMonth): provided explicit guidance for labeling an inline calendar month (#8375) * chore(CalendarMonth): provided explicit guidance for labeling an inline calendar month * update per PR comments * move inline accommodations into an inlineProps prop * fix typo and address PR comments * fix test failures * fix tests and snapshots * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.13 - @patternfly/react-code-editor@4.82.80 - @patternfly/react-console@4.93.13 - @patternfly/react-core@4.267.4 - @patternfly/react-docs@5.103.19 - @patternfly/react-inline-edit-extension@4.86.83 - demo-app-ts@4.205.15 - @patternfly/react-log-viewer@4.87.75 - @patternfly/react-table@4.112.4 - @patternfly/react-topology@4.90.36 - @patternfly/react-virtualized-extension@4.88.80 * chore(Wizard): Convert examples to typescript (#8287) * chore(Wizard): Convert examples to typescript * Fix import statements * Requested changes for cleanup * Integrate FinishedStep and SampleForm into examples directly * Remove unused onExpand function * Fix useEffect not defined * Import CogsIcon * a11y fixes for FinishedStep and SampleForm conversions * a11y fixes * Bug Fixes * Fixed incorrect Radio button state setting * Revert Progressive Steps example change * Fix Validate on Button Press for Wizard * Fix import in example * Remove unnecessary step state * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.14 - @patternfly/react-code-editor@4.82.81 - @patternfly/react-console@4.93.14 - @patternfly/react-core@4.267.5 - @patternfly/react-docs@5.103.20 - @patternfly/react-inline-edit-extension@4.86.84 - demo-app-ts@4.205.16 - @patternfly/react-log-viewer@4.87.76 - @patternfly/react-table@4.112.5 - @patternfly/react-topology@4.90.37 - @patternfly/react-virtualized-extension@4.88.81 * fix: Remove package exports and replace subpaths script (#8438) * fix: Remove package exports and replace subpaths script * adding more subpaths in the event 'next' or 'deprecated' have relative paths * chore(release): releasing packages [ci skip] - @patternfly/react-catalog-view-extension@4.93.15 - @patternfly/react-code-editor@4.82.82 - @patternfly/react-console@4.93.15 - @patternfly/react-core@4.267.6 - @patternfly/react-docs@5.103.21 - @patternfly/react-inline-edit-extension@4.86.85 - demo-app-ts@4.205.17 - @patternfly/react-log-viewer@4.87.77 - @patternfly/react-table@4.112.6 - @patternfly/react-topology@4.90.38 - @patternfly/react-virtualized-extension@4.88.82 * fix tests * fix merge errrors Signed-off-by: erkanercan Co-authored-by: Eric Olkowski <70952936+thatblindgeye@users.noreply.github.com> Co-authored-by: patternfly-build Co-authored-by: Titani Co-authored-by: Andy Vo <58367784+andyyvo@users.noreply.github.com> Co-authored-by: Samuel Atefah <68087918+samuelatefah@users.noreply.github.com> Co-authored-by: Dallas Co-authored-by: drewamunat2 <78369347+drewamunat2@users.noreply.github.com> Co-authored-by: Drew Amunategui II Co-authored-by: Drew Amunategui II Co-authored-by: Tomas Psota <72520867+tompsota@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jenny <32821331+jenny-s51@users.noreply.github.com> Co-authored-by: kev-kim <71181430+kev-kim@users.noreply.github.com> Co-authored-by: Nicole Thoen Co-authored-by: Dominik Petřík <77832970+Dominik-Petrik@users.noreply.github.com> Co-authored-by: kmcfaul <45077788+kmcfaul@users.noreply.github.com> Co-authored-by: janwright73 <40367673+janwright73@users.noreply.github.com> Co-authored-by: Jan Wright Co-authored-by: Austin Sullivan Co-authored-by: Jeff Phillips Co-authored-by: Gustavo Santos <53129852+gefgu@users.noreply.github.com> Co-authored-by: Christoph Jerolimov Co-authored-by: Jeff Puzzo <96431149+jeffpuzzo@users.noreply.github.com> Co-authored-by: kialam Co-authored-by: ishaanparlikar <43013132+ishaanparlikar@users.noreply.github.com> Co-authored-by: Michael Coker <35148959+mcoker@users.noreply.github.com> Co-authored-by: Adam Drew Co-authored-by: Erkan Ercan Co-authored-by: Katerina Koukiou Co-authored-by: Eric Olkowski Co-authored-by: Brian Rui <57109640+RuiBrian@users.noreply.github.com> Co-authored-by: Xiangyu Shen --- package.json | 3 +- .../react-catalog-view-extension/CHANGELOG.md | 211 +++ .../react-catalog-view-extension/package.json | 8 +- packages/react-charts/CHANGELOG.md | 32 + packages/react-charts/package.json | 6 +- packages/react-code-editor/CHANGELOG.md | 208 +++ packages/react-code-editor/README.md | 59 + packages/react-code-editor/package.json | 8 +- packages/react-console/CHANGELOG.md | 214 +++ packages/react-console/package.json | 6 +- .../src/components/VncConsole/VncConsole.tsx | 82 +- packages/react-core/.gitignore | 5 + packages/react-core/CHANGELOG.md | 269 +++ packages/react-core/package.json | 15 +- packages/react-core/scripts/copySubpaths.js | 12 + .../__tests__/AlertActionCloseButton.test.tsx | 31 +- .../Alert/__tests__/AlertActionLink.test.tsx | 11 +- .../AlertToggleExpandButton.test.tsx | 13 +- .../AlertActionCloseButton.test.tsx.snap | 9 + .../AlertActionLink.test.tsx.snap | 11 + .../AlertToggleExpandButton.test.tsx.snap | 9 + .../ApplicationLauncher.tsx | 8 + .../BackToTop/__tests__/BackToTop.test.tsx | 15 +- .../__snapshots__/BackToTop.test.tsx.snap | 12 +- .../Backdrop/__tests__/Backdrop.test.tsx | 38 +- .../__snapshots__/Backdrop.test.tsx.snap | 2 +- .../react-core/src/components/Badge/Badge.tsx | 4 + .../components/Badge/__tests__/Badge.test.tsx | 10 + .../components/Badge/examples/BadgeUnread.tsx | 13 +- .../src/components/Button/Button.tsx | 1 + .../components/Button/__mocks__/Button.tsx | 17 + .../src/components/Button/__mocks__/index.ts | 1 + .../__snapshots__/Button.test.tsx.snap | 2 +- .../CalendarMonth/CalendarMonth.tsx | 27 +- .../__tests__/CalendarMonth.test.tsx | 9 + .../CalendarMonth/examples/CalendarMonth.md | 2 +- .../examples/CalendarMonthDateRange.tsx | 21 +- .../examples/CalendarMonthSelectableDate.tsx | 18 +- .../ContextSelector/ContextSelector.tsx | 7 +- .../src/components/Dropdown/Dropdown.tsx | 14 +- .../Dropdown/DropdownWithContext.tsx | 2 + .../HelperText/__mocks__/HelperText.tsx | 9 + .../HelperText/__mocks__/HelperTextItem.tsx | 9 + .../components/HelperText/__mocks__/index.ts | 2 + .../Label/examples/LabelCompact.tsx | 4 +- .../react-core/src/components/Menu/Menu.tsx | 24 +- .../src/components/Menu/MenuItem.tsx | 5 +- .../src/components/Menu/examples/Menu.md | 9 +- .../Menu/examples/MenuFilterDrilldown.tsx | 123 ++ ...t.tsx => MenuFilteringWithSearchInput.tsx} | 7 +- .../examples/MenuWithDrilldownBreadcrumbs.tsx | 84 +- .../MultipleFileUploadStatusItem.tsx | 11 +- .../MultipleFileUploadStatusItem.test.tsx | 35 + .../examples/MultipleFileUpload.md | 6 + .../examples/MultipleFileUploadBasic.tsx | 37 +- .../react-core/src/components/Nav/NavItem.tsx | 32 +- .../src/components/Nav/examples/NavFlyout.tsx | 15 +- .../components/NumberInput/NumberInput.tsx | 3 +- .../__tests__/NumberInput.test.tsx | 8 +- .../NumberInput/examples/NumberInput.md | 2 + .../examples/NumberInputCustomStep.tsx | 8 +- .../NumberInputCustomStepAndThreshold.tsx | 9 +- .../examples/NumberInputDefault.tsx | 10 +- .../examples/NumberInputDisabled.tsx | 10 +- .../NumberInput/examples/NumberInputUnit.tsx | 20 +- .../examples/NumberInputUnitThreshold.tsx | 22 +- .../examples/NumberInputVaryingSizes.tsx | 22 +- .../examples/NumberInputWithStatus.tsx | 11 +- .../components/OptionsMenu/OptionsMenu.tsx | 8 + .../src/components/Pagination/Pagination.tsx | 16 + .../Pagination/__tests__/Pagination.test.tsx | 28 + .../__snapshots__/Pagination.test.tsx.snap | 1230 +++++++++++++ .../Pagination/examples/Pagination.md | 5 + .../Pagination/examples/PaginationInset.tsx | 36 + .../Pagination/examples/PaginationSticky.tsx | 98 +- .../components/Panel/__tests__/Panel.test.tsx | 154 +- .../Panel/__tests__/PanelFooter.test.tsx | 42 + .../Panel/__tests__/PanelHeader.test.tsx | 42 + .../Panel/__tests__/PanelMain.test.tsx | 48 + .../Panel/__tests__/PanelMainBody.test.tsx | 42 + .../__snapshots__/Panel.test.tsx.snap | 84 +- .../__snapshots__/PanelFooter.test.tsx.snap | 11 + .../__snapshots__/PanelHeader.test.tsx.snap | 11 + .../__snapshots__/PanelMain.test.tsx.snap | 11 + .../__snapshots__/PanelMainBody.test.tsx.snap | 11 + .../src/components/Progress/Progress.tsx | 6 + .../components/Progress/ProgressContainer.tsx | 9 +- .../Progress/ProgressHelperText.tsx | 20 + .../Progress/__tests__/Progress.test.tsx | 14 +- .../__tests__/ProgressHelperText.test.tsx | 35 + .../ProgressHelperText.test.tsx.snap | 11 + .../components/Progress/examples/Progress.md | 4 + .../Progress/examples/ProgressHelperText.tsx | 42 + .../SearchInput/AdvancedSearchMenu.tsx | 11 +- .../components/SearchInput/SearchInput.tsx | 33 +- .../SearchInput/examples/SearchInput.md | 4 + .../src/components/Select/Select.tsx | 7 +- .../src/components/Sidebar/SidebarPanel.tsx | 10 + .../Sidebar/__tests__/Sidebar.test.tsx | 72 + .../Sidebar/__tests__/SidebarContent.test.tsx | 38 + .../Sidebar/__tests__/SidebarPanel.test.tsx | 75 + .../__snapshots__/Sidebar.test.tsx.snap | 15 + .../SidebarContent.test.tsx.snap | 11 + .../__snapshots__/SidebarPanel.test.tsx.snap | 11 + .../src/components/Spinner/Spinner.tsx | 5 +- .../components/Spinner/examples/Spinner.md | 4 + .../Spinner/examples/SpinnerInline.tsx | 29 + .../src/components/Tabs/OverflowTab.tsx | 4 + .../react-core/src/components/Tabs/Tab.tsx | 33 +- .../src/components/Tabs/TabAction.tsx | 57 + .../react-core/src/components/Tabs/Tabs.tsx | 2 +- .../components/Tabs/__tests__/Tab.test.tsx | 10 + .../__tests__/__snapshots__/Tab.test.tsx.snap | 45 + .../src/components/Tabs/examples/Tabs.md | 1558 +---------------- .../components/Tabs/examples/TabsBoxLight.tsx | 63 + .../Tabs/examples/TabsChildrenMounting.tsx | 33 + .../examples/TabsContentWithBodyPadding.tsx | 58 + .../components/Tabs/examples/TabsDefault.tsx | 62 + .../Tabs/examples/TabsDefaultOverflow.tsx | 74 + .../components/Tabs/examples/TabsFilled.tsx | 51 + .../Tabs/examples/TabsFilledWithIcons.tsx | 85 + .../src/components/Tabs/examples/TabsHelp.tsx | 61 + .../Tabs/examples/TabsHelpAndClose.tsx | 84 + .../Tabs/examples/TabsIconAndText.tsx | 108 ++ .../components/Tabs/examples/TabsInset.tsx | 65 + .../src/components/Tabs/examples/TabsNav.tsx | 40 + .../Tabs/examples/TabsNavSecondary.tsx | 76 + .../Tabs/examples/TabsPageInsets.tsx | 60 + .../Tabs/examples/TabsSeparateContent.tsx | 75 + .../components/Tabs/examples/TabsSubtabs.tsx | 115 ++ .../examples/TabsToggledSeparateContent.tsx | 67 + .../Tabs/examples/TabsTooltipReactRef.tsx | 72 + .../Tabs/examples/TabsUncontrolled.tsx | 33 + .../TabsUnmountingInvisibleChildren.tsx | 33 + .../components/Tabs/examples/TabsVertical.tsx | 72 + .../Tabs/examples/TabsVerticalExpandable.tsx | 51 + .../TabsVerticalExpandableUncontrolled.tsx | 48 + .../react-core/src/components/Tabs/index.ts | 1 + .../src/components/Text/TextList.tsx | 2 +- .../src/components/Text/TextListItem.tsx | 2 +- .../__snapshots__/TextList.test.tsx.snap | 1 - .../__snapshots__/TextListItem.test.tsx.snap | 1 - .../components/Text/__tests__/Text.test.tsx | 207 ++- .../Text/__tests__/TextContent.text.tsx | 103 ++ .../Text/__tests__/TextList.test.tsx | 52 + .../Text/__tests__/TextListItem.test.tsx | 52 + .../__snapshots__/Text.test.tsx.snap | 337 +--- .../__snapshots__/TextContent.text.tsx.snap | 15 + .../__snapshots__/TextList.test.tsx.snap | 11 + .../__snapshots__/TextListItem.test.tsx.snap | 11 + .../components/TextArea/examples/TextArea.md | 272 +-- .../examples/TextAreaAutoResizing.tsx | 14 + .../TextArea/examples/TextAreaBasic.tsx | 7 + .../TextArea/examples/TextAreaDisabled.tsx | 6 + .../TextAreaHorizontallyResizable.tsx | 14 + .../TextArea/examples/TextAreaIconSprite.tsx | 41 + .../TextArea/examples/TextAreaInvalid.tsx | 15 + .../TextArea/examples/TextAreaReadOnly.tsx | 25 + .../examples/TextAreaUncontrolled.tsx | 6 + .../TextArea/examples/TextAreaValidated.tsx | 52 + .../examples/TextAreaVerticallyResizable.tsx | 14 + .../src/components/TimePicker/TimePicker.tsx | 39 +- .../TimePicker/__tests__/TimePicker.test.tsx | 13 +- .../ToggleGroup/examples/ToggleGroup.md | 196 +-- .../examples/ToggleGroupCompact.tsx | 30 + .../examples/ToggleGroupDefaultMultiple.tsx | 43 + .../examples/ToggleGroupDefaultSingle.tsx | 32 + .../ToggleGroup/examples/ToggleGroupIcon.tsx | 42 + .../examples/ToggleGroupTextIcon.tsx | 42 + .../components/Tooltip/examples/Tooltip.md | 290 +-- .../Tooltip/examples/TooltipBasic.tsx | 16 + .../Tooltip/examples/TooltipIcon.tsx | 24 + .../Tooltip/examples/TooltipOptions.tsx | 197 +++ .../Tooltip/examples/TooltipReactRef.tsx | 22 + .../Tooltip/examples/TooltipSelectorRef.tsx | 19 + .../Wizard/examples/FinishedStep.js | 70 - .../components/Wizard/examples/SampleForm.js | 59 - .../src/components/Wizard/examples/Wizard.md | 707 +------- .../examples/WizardAnchorsForNavItems.tsx | 42 + .../Wizard/examples/WizardBasic.tsx | 14 + .../examples/WizardBasicWithDisabledSteps.tsx | 14 + .../WizardEnabledOnFormValidation.tsx | 139 ++ .../Wizard/examples/WizardExpandableSteps.tsx | 34 + .../Wizard/examples/WizardFinished.tsx | 90 + .../Wizard/examples/WizardGetCurrentStep.tsx | 33 + .../Wizard/examples/WizardInModal.tsx | 32 + .../WizardIncrementallyEnabledSteps.tsx | 61 + .../examples/WizardValidateOnButtonPress.tsx | 204 +++ .../Wizard/examples/WizardWithDrawer.tsx | 126 ++ packages/react-core/src/demos/Card/Card.md | 5 +- .../ComposableApplicationLauncher.tsx | 9 +- .../examples/ComposableContextSelector.tsx | 6 +- packages/react-core/src/demos/Nav.md | 4 +- .../react-core/src/demos/PrimaryDetail.md | 10 +- packages/react-core/src/demos/Tabs.md | 10 - .../src/demos/examples/DashboardWrapper.js | 1 + .../src/demos/examples/Tabs/GrayTabs.tsx | 152 -- .../src/demos/examples/Tabs/ModalTabs.tsx | 6 +- .../src/demos/examples/Tabs/NestedTabs.tsx | 14 +- .../examples/Tabs/NestedUnindentedTabs.tsx | 65 +- .../src/demos/examples/Tabs/TabsAndTable.tsx | 61 +- .../Tabs/TabsAndTablesAutoWidthTabs.tsx | 442 ----- .../src/next/components/Dropdown/Dropdown.tsx | 4 + .../next/components/Dropdown/DropdownItem.tsx | 5 +- .../src/next/components/Select/Select.tsx | 4 + .../src/next/components/Wizard/Wizard.tsx | 2 +- .../next/components/Wizard/WizardContext.tsx | 4 +- .../next/components/Wizard/WizardFooter.tsx | 4 +- .../components/Wizard/WizardNavInternal.tsx | 2 +- .../next/components/Wizard/WizardNavItem.tsx | 2 +- .../src/next/components/Wizard/WizardStep.tsx | 2 + .../Wizard/__tests__/Wizard.test.tsx | 34 +- .../Wizard/__tests__/WizardStep.test.tsx | 3 +- .../next/components/Wizard/examples/Wizard.md | 2 +- .../Wizard/examples/WizardKitchenSink.tsx | 29 +- .../src/next/components/Wizard/types.tsx | 13 +- packages/react-core/tsconfig.json | 9 +- packages/react-docs/CHANGELOG.md | 267 +++ packages/react-docs/RELEASE-NOTES.md | 55 + packages/react-docs/package.json | 30 +- .../components/login-page/react/basic.png | Bin 197681 -> 197808 bytes .../login-page/react/showhide-password.png | Bin 197967 -> 197969 bytes .../table/react-demos/column-management.png | Bin 64375 -> 61691 bytes .../components/table/react-demos/compact.png | Bin 66553 -> 66746 bytes .../table/react-demos/expandcollapse-all.png | Bin 42034 -> 42035 bytes .../react-demos/sortable---responsive.png | Bin 81777 -> 82487 bytes .../static-bottom-pagination-on-mobile.png | Bin 67477 -> 65817 bytes .../table/react-demos/sticky-header.png | Bin 65818 -> 65482 bytes .../tabs/react-demos/modal-tabs.png | Bin 38471 -> 43556 bytes .../tabs/react-demos/nested-tabs.png | Bin 50379 -> 49577 bytes .../react-demos/nested-unindented-tabs.png | Bin 49774 -> 42223 bytes .../tabs/react-demos/tables-and-tabs.png | Bin 45966 -> 56817 bytes .../patternfly-docs/patternfly-docs.source.js | 7 +- packages/react-icons/CHANGELOG.md | 35 + packages/react-icons/package.json | 4 +- .../react-inline-edit-extension/CHANGELOG.md | 224 +++ .../react-inline-edit-extension/package.json | 10 +- packages/react-integration/CHANGELOG.md | 38 + .../cypress/integration/menu.spec.ts | 4 +- .../cypress/integration/numberInput.spec.ts | 9 +- .../demo-app-ts/CHANGELOG.md | 214 +++ .../demo-app-ts/package.json | 4 +- .../components/demos/MenuDemo/MenuDemo.tsx | 7 +- .../demos/MenuDemo/MenuDrilldownDemo.tsx | 5 +- .../src/components/demos/NavDemo/NavDemo.tsx | 8 +- .../demos/NumberInputDemo/NumberInputDemo.tsx | 15 +- packages/react-integration/package.json | 2 +- packages/react-log-viewer/CHANGELOG.md | 208 +++ packages/react-log-viewer/package.json | 8 +- packages/react-styles/CHANGELOG.md | 35 + packages/react-styles/package.json | 4 +- packages/react-table/.gitignore | 2 + packages/react-table/CHANGELOG.md | 236 +++ packages/react-table/package.json | 22 +- packages/react-table/scripts/copySubpaths.js | 12 + .../src/components/Table/base/types.tsx | 4 + .../src/components/TableComposable/Td.tsx | 22 + .../src/components/TableComposable/Th.tsx | 5 + .../examples/ComposableTable.md | 4 +- .../examples/ComposableTableMisc.tsx | 2 +- .../src/deprecated/components/index.ts | 1 + packages/react-table/src/deprecated/index.ts | 1 + packages/react-table/src/docs/demos/Table.md | 5 +- packages/react-table/tsconfig.json | 6 +- packages/react-tokens/CHANGELOG.md | 35 + packages/react-tokens/package.json | 4 +- packages/react-topology/CHANGELOG.md | 208 +++ packages/react-topology/package.json | 8 +- .../src/components/nodes/DefaultNode.tsx | 2 +- .../react-virtualized-extension/CHANGELOG.md | 208 +++ .../react-virtualized-extension/package.json | 8 +- packages/tsconfig.base.json | 3 +- yarn.lock | 93 +- 273 files changed, 9534 insertions(+), 4865 deletions(-) create mode 100644 packages/react-core/.gitignore create mode 100644 packages/react-core/scripts/copySubpaths.js create mode 100644 packages/react-core/src/components/Button/__mocks__/Button.tsx create mode 100644 packages/react-core/src/components/Button/__mocks__/index.ts create mode 100644 packages/react-core/src/components/HelperText/__mocks__/HelperText.tsx create mode 100644 packages/react-core/src/components/HelperText/__mocks__/HelperTextItem.tsx create mode 100644 packages/react-core/src/components/HelperText/__mocks__/index.ts create mode 100644 packages/react-core/src/components/Menu/examples/MenuFilterDrilldown.tsx rename packages/react-core/src/components/Menu/examples/{MenuFilteringWithTextInput.tsx => MenuFilteringWithSearchInput.tsx} (85%) create mode 100644 packages/react-core/src/components/Pagination/examples/PaginationInset.tsx create mode 100644 packages/react-core/src/components/Panel/__tests__/PanelFooter.test.tsx create mode 100644 packages/react-core/src/components/Panel/__tests__/PanelHeader.test.tsx create mode 100644 packages/react-core/src/components/Panel/__tests__/PanelMain.test.tsx create mode 100644 packages/react-core/src/components/Panel/__tests__/PanelMainBody.test.tsx create mode 100644 packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelFooter.test.tsx.snap create mode 100644 packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelHeader.test.tsx.snap create mode 100644 packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMain.test.tsx.snap create mode 100644 packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMainBody.test.tsx.snap create mode 100644 packages/react-core/src/components/Progress/ProgressHelperText.tsx create mode 100644 packages/react-core/src/components/Progress/__tests__/ProgressHelperText.test.tsx create mode 100644 packages/react-core/src/components/Progress/__tests__/__snapshots__/ProgressHelperText.test.tsx.snap create mode 100644 packages/react-core/src/components/Progress/examples/ProgressHelperText.tsx create mode 100644 packages/react-core/src/components/Sidebar/__tests__/Sidebar.test.tsx create mode 100644 packages/react-core/src/components/Sidebar/__tests__/SidebarContent.test.tsx create mode 100644 packages/react-core/src/components/Sidebar/__tests__/SidebarPanel.test.tsx create mode 100644 packages/react-core/src/components/Sidebar/__tests__/__snapshots__/Sidebar.test.tsx.snap create mode 100644 packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarContent.test.tsx.snap create mode 100644 packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarPanel.test.tsx.snap create mode 100644 packages/react-core/src/components/Spinner/examples/SpinnerInline.tsx create mode 100644 packages/react-core/src/components/Tabs/TabAction.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsBoxLight.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsChildrenMounting.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsContentWithBodyPadding.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsDefault.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsDefaultOverflow.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsFilled.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsFilledWithIcons.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsHelp.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsHelpAndClose.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsIconAndText.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsInset.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsNav.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsNavSecondary.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsPageInsets.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsSeparateContent.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsSubtabs.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsToggledSeparateContent.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsTooltipReactRef.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsUncontrolled.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsUnmountingInvisibleChildren.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsVertical.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsVerticalExpandable.tsx create mode 100644 packages/react-core/src/components/Tabs/examples/TabsVerticalExpandableUncontrolled.tsx create mode 100644 packages/react-core/src/components/Text/__tests__/TextContent.text.tsx create mode 100644 packages/react-core/src/components/Text/__tests__/TextList.test.tsx create mode 100644 packages/react-core/src/components/Text/__tests__/TextListItem.test.tsx create mode 100644 packages/react-core/src/components/Text/__tests__/__snapshots__/TextContent.text.tsx.snap create mode 100644 packages/react-core/src/components/Text/__tests__/__snapshots__/TextList.test.tsx.snap create mode 100644 packages/react-core/src/components/Text/__tests__/__snapshots__/TextListItem.test.tsx.snap create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaAutoResizing.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaBasic.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaDisabled.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaHorizontallyResizable.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaIconSprite.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaInvalid.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaReadOnly.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaUncontrolled.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaValidated.tsx create mode 100644 packages/react-core/src/components/TextArea/examples/TextAreaVerticallyResizable.tsx create mode 100644 packages/react-core/src/components/ToggleGroup/examples/ToggleGroupCompact.tsx create mode 100644 packages/react-core/src/components/ToggleGroup/examples/ToggleGroupDefaultMultiple.tsx create mode 100644 packages/react-core/src/components/ToggleGroup/examples/ToggleGroupDefaultSingle.tsx create mode 100644 packages/react-core/src/components/ToggleGroup/examples/ToggleGroupIcon.tsx create mode 100644 packages/react-core/src/components/ToggleGroup/examples/ToggleGroupTextIcon.tsx create mode 100644 packages/react-core/src/components/Tooltip/examples/TooltipBasic.tsx create mode 100644 packages/react-core/src/components/Tooltip/examples/TooltipIcon.tsx create mode 100644 packages/react-core/src/components/Tooltip/examples/TooltipOptions.tsx create mode 100644 packages/react-core/src/components/Tooltip/examples/TooltipReactRef.tsx create mode 100644 packages/react-core/src/components/Tooltip/examples/TooltipSelectorRef.tsx delete mode 100644 packages/react-core/src/components/Wizard/examples/FinishedStep.js delete mode 100644 packages/react-core/src/components/Wizard/examples/SampleForm.js create mode 100644 packages/react-core/src/components/Wizard/examples/WizardAnchorsForNavItems.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardBasic.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardBasicWithDisabledSteps.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardEnabledOnFormValidation.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardExpandableSteps.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardFinished.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardGetCurrentStep.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardInModal.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardIncrementallyEnabledSteps.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardValidateOnButtonPress.tsx create mode 100644 packages/react-core/src/components/Wizard/examples/WizardWithDrawer.tsx delete mode 100644 packages/react-core/src/demos/examples/Tabs/GrayTabs.tsx delete mode 100644 packages/react-core/src/demos/examples/Tabs/TabsAndTablesAutoWidthTabs.tsx create mode 100644 packages/react-table/.gitignore create mode 100644 packages/react-table/scripts/copySubpaths.js create mode 100644 packages/react-table/src/deprecated/components/index.ts create mode 100644 packages/react-table/src/deprecated/index.ts diff --git a/package.json b/package.json index 1ddbb6d63ae..bd2f42601d8 100644 --- a/package.json +++ b/package.json @@ -67,12 +67,13 @@ "typescript": "^4.0.0" }, "scripts": { - "build": "yarn build:generate && yarn build:esm && yarn build:cjs", + "build": "yarn build:generate && yarn build:esm && yarn build:subpaths && yarn build:cjs", "build:cjs": "tsc --build --verbose packages/tsconfig.cjs.json", "build:esm": "tsc --build --verbose packages/tsconfig.json", "build:integration": "lerna run build:demo-app --stream", "build:docs": "yarn workspace @patternfly/react-docs build:docs", "build:generate": "lerna run generate --parallel --stream", + "build:subpaths": "lerna run subpaths --parallel --stream", "build:umd": "lerna run build:umd --parallel --stream", "clean": "yarn clean:build && lerna run clean --parallel", "clean:build": "rimraf .cache .eslintcache coverage", diff --git a/packages/react-catalog-view-extension/CHANGELOG.md b/packages/react-catalog-view-extension/CHANGELOG.md index 16c88669d75..af7db5c53ab 100644 --- a/packages/react-catalog-view-extension/CHANGELOG.md +++ b/packages/react-catalog-view-extension/CHANGELOG.md @@ -3,6 +3,217 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.93.15](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.14...@patternfly/react-catalog-view-extension@4.93.15) (2022-12-12) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.14](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.13...@patternfly/react-catalog-view-extension@4.93.14) (2022-12-09) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.13](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.12...@patternfly/react-catalog-view-extension@4.93.13) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.12](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.11...@patternfly/react-catalog-view-extension@4.93.12) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.93.11 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.93.10 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.9](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.8...@patternfly/react-catalog-view-extension@4.93.9) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.8](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.7...@patternfly/react-catalog-view-extension@4.93.8) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.7](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.6...@patternfly/react-catalog-view-extension@4.93.7) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.6](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.5...@patternfly/react-catalog-view-extension@4.93.6) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.5](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.4...@patternfly/react-catalog-view-extension@4.93.5) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.93.4 (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.93.3](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.93.2...@patternfly/react-catalog-view-extension@4.93.3) (2022-12-05) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.93.2 (2022-12-01) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.93.1 (2022-11-30) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +# [4.93.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.66...@patternfly/react-catalog-view-extension@4.93.0) (2022-11-16) + + +### Features + +* **Tabs:** add TabAction, update core ver ([#8348](https://github.com/patternfly/patternfly-react/issues/8348)) ([8c584b4](https://github.com/patternfly/patternfly-react/commit/8c584b48f8e545cf226f785b873ee11eda505724)) + + + + + +## [4.92.66](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.65...@patternfly/react-catalog-view-extension@4.92.66) (2022-11-15) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.65](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.64...@patternfly/react-catalog-view-extension@4.92.65) (2022-11-15) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.64](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.63...@patternfly/react-catalog-view-extension@4.92.64) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.63](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.62...@patternfly/react-catalog-view-extension@4.92.63) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.62](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.61...@patternfly/react-catalog-view-extension@4.92.62) (2022-11-08) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.61](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.60...@patternfly/react-catalog-view-extension@4.92.61) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.60](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.59...@patternfly/react-catalog-view-extension@4.92.60) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.59](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.58...@patternfly/react-catalog-view-extension@4.92.59) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## [4.92.58](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-catalog-view-extension@4.92.57...@patternfly/react-catalog-view-extension@4.92.58) (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + +## 4.92.57 (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-catalog-view-extension + + + + + ## 4.92.56 (2022-11-01) **Note:** Version bump only for package @patternfly/react-catalog-view-extension diff --git a/packages/react-catalog-view-extension/package.json b/packages/react-catalog-view-extension/package.json index 7ff0dcf5d8e..b4142acdc08 100644 --- a/packages/react-catalog-view-extension/package.json +++ b/packages/react-catalog-view-extension/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-catalog-view-extension", - "version": "4.92.56", + "version": "4.93.15", "description": "This library provides catalog view extensions for PatternFly 4 React.", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -35,9 +35,9 @@ "clean": "rimraf dist" }, "dependencies": { - "@patternfly/patternfly": "4.219.2", - "@patternfly/react-core": "^4.258.4", - "@patternfly/react-styles": "^4.91.10" + "@patternfly/patternfly": "4.222.4", + "@patternfly/react-core": "^4.267.6", + "@patternfly/react-styles": "^4.92.3" }, "devDependencies": { "rimraf": "^2.6.2", diff --git a/packages/react-charts/CHANGELOG.md b/packages/react-charts/CHANGELOG.md index 584406ded7a..798a196939e 100644 --- a/packages/react-charts/CHANGELOG.md +++ b/packages/react-charts/CHANGELOG.md @@ -3,6 +3,38 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## 6.94.15 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + +## 6.94.14 (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + +## 6.94.13 (2022-12-01) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + +## 6.94.12 (2022-11-16) + +**Note:** Version bump only for package @patternfly/react-charts + + + + + ## 6.94.11 (2022-10-27) **Note:** Version bump only for package @patternfly/react-charts diff --git a/packages/react-charts/package.json b/packages/react-charts/package.json index 3774b5b7b6e..f16da9ebb39 100644 --- a/packages/react-charts/package.json +++ b/packages/react-charts/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-charts", - "version": "6.94.11", + "version": "6.94.15", "description": "This library provides a set of React chart components for use with the PatternFly reference implementation.", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -29,8 +29,8 @@ }, "homepage": "https://github.com/patternfly/patternfly-react#readme", "dependencies": { - "@patternfly/react-styles": "^4.91.10", - "@patternfly/react-tokens": "^4.93.10", + "@patternfly/react-styles": "^4.92.3", + "@patternfly/react-tokens": "^4.94.3", "hoist-non-react-statics": "^3.3.0", "lodash": "^4.17.19", "tslib": "^2.0.0", diff --git a/packages/react-code-editor/CHANGELOG.md b/packages/react-code-editor/CHANGELOG.md index be86cf43e69..9b5988aa4e7 100644 --- a/packages/react-code-editor/CHANGELOG.md +++ b/packages/react-code-editor/CHANGELOG.md @@ -3,6 +3,214 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.82.82](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.81...@patternfly/react-code-editor@4.82.82) (2022-12-12) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.81](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.80...@patternfly/react-code-editor@4.82.81) (2022-12-09) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.80](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.79...@patternfly/react-code-editor@4.82.80) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.79](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.78...@patternfly/react-code-editor@4.82.79) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.78 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.77 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.76](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.75...@patternfly/react-code-editor@4.82.76) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.75](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.74...@patternfly/react-code-editor@4.82.75) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.74](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.73...@patternfly/react-code-editor@4.82.74) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.73](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.72...@patternfly/react-code-editor@4.82.73) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.72](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.71...@patternfly/react-code-editor@4.82.72) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.71 (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.70](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.69...@patternfly/react-code-editor@4.82.70) (2022-12-05) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.69 (2022-12-01) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.68 (2022-11-30) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.67](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.66...@patternfly/react-code-editor@4.82.67) (2022-11-16) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.66](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.65...@patternfly/react-code-editor@4.82.66) (2022-11-15) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.65](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.64...@patternfly/react-code-editor@4.82.65) (2022-11-15) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.64](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.63...@patternfly/react-code-editor@4.82.64) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.63](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.62...@patternfly/react-code-editor@4.82.63) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.62](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.61...@patternfly/react-code-editor@4.82.62) (2022-11-08) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.61](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.60...@patternfly/react-code-editor@4.82.61) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.60](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.59...@patternfly/react-code-editor@4.82.60) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.59](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.58...@patternfly/react-code-editor@4.82.59) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## [4.82.58](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-code-editor@4.82.57...@patternfly/react-code-editor@4.82.58) (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + +## 4.82.57 (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-code-editor + + + + + ## 4.82.56 (2022-11-01) **Note:** Version bump only for package @patternfly/react-code-editor diff --git a/packages/react-code-editor/README.md b/packages/react-code-editor/README.md index 58f1a3b39a7..8910e0c0eb6 100644 --- a/packages/react-code-editor/README.md +++ b/packages/react-code-editor/README.md @@ -53,3 +53,62 @@ Install peer deps ``` To properly install the library `monaco-editor-webpack-plugin` be sure to follow the [plugin instructions](https://github.com/microsoft/monaco-editor/tree/main/webpack-plugin) + +#### With create-react-app Projects +If you created your project with `create-react-app` you'll have some extra work to do, or you wont have syntax highlighting. Using the webpack plugin requires updating your webpack config, which `create-react-app` abstracts away. You can `npm eject` your project, but you may not want to do that. To keep your app set up in the `create-react-app` style but to get access to your webpack config you can use `react-app-rewired`. + +First, install `react-app-rewired` as a development dependency: +```sh +$ npm install -D react-app-rewired +``` + +Next, replace all of the `react-script` references in your `package.json` `scripts` section with `react-app-required`: +```json + "scripts": { + "start": "react-app-rewired start", + "build": "react-app-rewired build", + "test": "react-app-rewired test", + "eject": "react-app-rewired eject" + } +``` + +Next, create a `config-overries.js` file at the root of your project and add the following: + +```javascript +const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); + +module.exports = function override(config, env) { + config.plugins.push(new MonacoWebpackPlugin({ + languages: ['json', 'yaml', 'shell'] + })); + return config; +} +``` + +Note: You should change the `languages` array based on your needs. + +You can now start your app with `npm start` and syntax highlighting should work. + +#### Enable YAML Syntax Highlighting +The Monaco editor doesn't ship with full YAML support. You can configure your code editor with `Languages.yaml` but there will be no highlighting, even i you have the webpack plugin working correctly. To enable YAML support you need to do the following: + +First, install `monaco-yaml`: +```shell +$ npm install --save monaco-yaml +``` + +Next, at the entrypoint of your app enable it: +```javascript +import { setDiagnosticsOptions } from 'monaco-yaml'; + +setDiagnosticsOptions({ + enableSchemaRequest: true, + hover: true, + completion: true, + validate: true, + format: true, + schemas: [], +}); +``` + +The `monaco-yaml` plugin has a lot of options so check out their docs to see what else you may want to add. diff --git a/packages/react-code-editor/package.json b/packages/react-code-editor/package.json index d33482b9fa3..aee33f6a98d 100644 --- a/packages/react-code-editor/package.json +++ b/packages/react-code-editor/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-code-editor", - "version": "4.82.56", + "version": "4.82.82", "description": "This package provides a PatternFly wrapper for the Monaco code editor\n", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -30,9 +30,9 @@ "clean": "rimraf dist" }, "dependencies": { - "@patternfly/react-core": "^4.258.4", - "@patternfly/react-icons": "^4.92.10", - "@patternfly/react-styles": "^4.91.10", + "@patternfly/react-core": "^4.267.6", + "@patternfly/react-icons": "^4.93.3", + "@patternfly/react-styles": "^4.92.3", "react-dropzone": "14.2.3", "tslib": "^2.0.0" }, diff --git a/packages/react-console/CHANGELOG.md b/packages/react-console/CHANGELOG.md index 2599c42388b..f47121eee20 100644 --- a/packages/react-console/CHANGELOG.md +++ b/packages/react-console/CHANGELOG.md @@ -3,6 +3,220 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.93.15](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.14...@patternfly/react-console@4.93.15) (2022-12-12) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.14](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.13...@patternfly/react-console@4.93.14) (2022-12-09) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.13](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.12...@patternfly/react-console@4.93.13) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.12](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.11...@patternfly/react-console@4.93.12) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## 4.93.11 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## 4.93.10 (2022-12-08) + + +### Bug Fixes + +* **VncConsole:** prevent running initialization code more than once ([#8373](https://github.com/patternfly/patternfly-react/issues/8373)) ([#8374](https://github.com/patternfly/patternfly-react/issues/8374)) ([285c5ff](https://github.com/patternfly/patternfly-react/commit/285c5ff54f165c43752f36107db2db7473cc338a)) + + + + + +## [4.93.9](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.8...@patternfly/react-console@4.93.9) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.8](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.7...@patternfly/react-console@4.93.8) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.7](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.6...@patternfly/react-console@4.93.7) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.6](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.5...@patternfly/react-console@4.93.6) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.5](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.4...@patternfly/react-console@4.93.5) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## 4.93.4 (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.93.3](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.93.2...@patternfly/react-console@4.93.3) (2022-12-05) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## 4.93.2 (2022-12-01) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## 4.93.1 (2022-11-30) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +# [4.93.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.66...@patternfly/react-console@4.93.0) (2022-11-16) + + +### Features + +* **Tabs:** add TabAction, update core ver ([#8348](https://github.com/patternfly/patternfly-react/issues/8348)) ([8c584b4](https://github.com/patternfly/patternfly-react/commit/8c584b48f8e545cf226f785b873ee11eda505724)) + + + + + +## [4.92.66](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.65...@patternfly/react-console@4.92.66) (2022-11-15) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.65](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.64...@patternfly/react-console@4.92.65) (2022-11-15) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.64](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.63...@patternfly/react-console@4.92.64) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.63](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.62...@patternfly/react-console@4.92.63) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.62](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.61...@patternfly/react-console@4.92.62) (2022-11-08) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.61](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.60...@patternfly/react-console@4.92.61) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.60](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.59...@patternfly/react-console@4.92.60) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.59](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.58...@patternfly/react-console@4.92.59) (2022-11-07) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## [4.92.58](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-console@4.92.57...@patternfly/react-console@4.92.58) (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-console + + + + + +## 4.92.57 (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-console + + + + + ## 4.92.56 (2022-11-01) **Note:** Version bump only for package @patternfly/react-console diff --git a/packages/react-console/package.json b/packages/react-console/package.json index 9a1cf67391d..99eb7675bfa 100644 --- a/packages/react-console/package.json +++ b/packages/react-console/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-console", - "version": "4.92.56", + "version": "4.93.15", "description": "This package provides VncConsole, SerialConsole and DesktopViewer React components to be used alongside patternfly-react to access virtual machine or server consoles.", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -33,8 +33,8 @@ }, "dependencies": { "@novnc/novnc": "^1.2.0", - "@patternfly/patternfly": "4.219.2", - "@patternfly/react-core": "^4.258.4", + "@patternfly/patternfly": "4.222.4", + "@patternfly/react-core": "^4.267.6", "@spice-project/spice-html5": "^0.2.1", "@types/file-saver": "^2.0.1", "file-saver": "^1.3.8", diff --git a/packages/react-console/src/components/VncConsole/VncConsole.tsx b/packages/react-console/src/components/VncConsole/VncConsole.tsx index c8ac73999e2..89355de0686 100644 --- a/packages/react-console/src/components/VncConsole/VncConsole.tsx +++ b/packages/react-console/src/components/VncConsole/VncConsole.tsx @@ -92,28 +92,53 @@ export const VncConsole: React.FunctionComponent = ({ textCtrlAltDel }) => { const rfb = React.useRef(); - let novncStaticComponent: React.ReactNode; - let novncElem: HTMLDivElement; + const novncElem = React.useRef(null); const [status, setStatus] = React.useState(CONNECTING); - const addEventListeners = () => { + const onConnected = () => { + setStatus(CONNECTED); + }; + + const _onDisconnected = React.useCallback( + (e: any) => { + setStatus(DISCONNECTED); + onDisconnected(e); + }, + [onDisconnected] + ); + + const _onSecurityFailure = React.useCallback( + (e: any) => { + setStatus(DISCONNECTED); + onSecurityFailure(e); + }, + [onSecurityFailure] + ); + + const onCtrlAltDel = () => { + if (rfb.current) { + rfb?.current?.sendCtrlAltDel(); + } + }; + + const addEventListeners = React.useCallback(() => { if (rfb.current) { rfb.current?.addEventListener('connect', onConnected); rfb.current?.addEventListener('disconnect', _onDisconnected); rfb.current?.addEventListener('securityfailure', _onSecurityFailure); } - }; + }, [rfb, _onDisconnected, _onSecurityFailure]); - const removeEventListeners = () => { + const removeEventListeners = React.useCallback(() => { if (rfb.current) { rfb.current.removeEventListener('connect', onConnected); rfb.current.removeEventListener('disconnect', _onDisconnected); rfb.current.removeEventListener('securityfailure', _onSecurityFailure); } - }; + }, [rfb, _onDisconnected, _onSecurityFailure]); - const connect = () => { + const connect = React.useCallback(() => { const protocol = encrypt ? 'wss' : 'ws'; const url = `${protocol}://${host}:${port}/${path}`; @@ -122,12 +147,25 @@ export const VncConsole: React.FunctionComponent = ({ shared, credentials }; - rfb.current = new RFB(novncElem, url, options); + rfb.current = new RFB(novncElem.current, url, options); addEventListeners(); rfb.current.viewOnly = viewOnly; rfb.current.scaleViewport = scaleViewport; rfb.current.resizeSession = resizeSession; - }; + }, [ + addEventListeners, + host, + path, + port, + resizeSession, + scaleViewport, + viewOnly, + encrypt, + rfb, + repeaterID, + shared, + credentials + ]); React.useEffect(() => { initLogging(vncLogging); @@ -152,26 +190,6 @@ export const VncConsole: React.FunctionComponent = ({ rfb.current.disconnect(); }; - const onConnected = () => { - setStatus(CONNECTED); - }; - - const _onDisconnected = (e: any) => { - setStatus(DISCONNECTED); - onDisconnected(e); - }; - - const _onSecurityFailure = (e: any) => { - setStatus(DISCONNECTED); - onSecurityFailure(e); - }; - - const onCtrlAltDel = () => { - if (rfb.current) { - rfb?.current?.sendCtrlAltDel(); - } - }; - let rightContent; let emptyState; switch (status) { @@ -207,10 +225,6 @@ export const VncConsole: React.FunctionComponent = ({ ); } - if (!novncStaticComponent) { - novncStaticComponent =
(novncElem = e)} />; - } - return ( <> {rightContent} @@ -219,7 +233,7 @@ export const VncConsole: React.FunctionComponent = ({
{emptyState} - {novncStaticComponent} +
diff --git a/packages/react-core/.gitignore b/packages/react-core/.gitignore new file mode 100644 index 00000000000..77cfc55e590 --- /dev/null +++ b/packages/react-core/.gitignore @@ -0,0 +1,5 @@ +/next +/deprecated +/components +/layouts +/helpers \ No newline at end of file diff --git a/packages/react-core/CHANGELOG.md b/packages/react-core/CHANGELOG.md index 4dcd6a8d067..e39310420d3 100644 --- a/packages/react-core/CHANGELOG.md +++ b/packages/react-core/CHANGELOG.md @@ -3,6 +3,275 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [4.267.6](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.267.5...@patternfly/react-core@4.267.6) (2022-12-12) + + +### Bug Fixes + +* Remove package exports and replace subpaths script ([#8438](https://github.com/patternfly/patternfly-react/issues/8438)) ([75bea27](https://github.com/patternfly/patternfly-react/commit/75bea2790cffcfe2ffc9ca46d82748e3e85674fc)) + + + + + +## [4.267.5](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.267.4...@patternfly/react-core@4.267.5) (2022-12-09) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +## [4.267.4](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.267.3...@patternfly/react-core@4.267.4) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +## [4.267.3](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.267.2...@patternfly/react-core@4.267.3) (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +## 4.267.2 (2022-12-08) + + +### Bug Fixes + +* **Menu:** removed li wrapper from breadcrumb example ([#8433](https://github.com/patternfly/patternfly-react/issues/8433)) ([1f41a71](https://github.com/patternfly/patternfly-react/commit/1f41a712fb8124a931277eb6611923746cd24496)) + + + + + +## 4.267.1 (2022-12-08) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +# [4.267.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.266.3...@patternfly/react-core@4.267.0) (2022-12-07) + + +### Features + +* **Menu:** add drilldown filter demo, add flag to support demo & fix some keyboard interaction ([#8405](https://github.com/patternfly/patternfly-react/issues/8405)) ([6fd28da](https://github.com/patternfly/patternfly-react/commit/6fd28da87bbc1f06553df388c626de8d94e0fa05)) + + + + + +## [4.266.3](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.266.2...@patternfly/react-core@4.266.3) (2022-12-07) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +## [4.266.2](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.266.1...@patternfly/react-core@4.266.2) (2022-12-06) + + +### Bug Fixes + +* **Pagination:** Added support for insets ([#8412](https://github.com/patternfly/patternfly-react/issues/8412)) ([1053d53](https://github.com/patternfly/patternfly-react/commit/1053d530605c4f629eefdc7501b121a1906394a2)) + + + + + +## [4.266.1](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.266.0...@patternfly/react-core@4.266.1) (2022-12-06) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +# [4.266.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.265.2...@patternfly/react-core@4.266.0) (2022-12-06) + + +### Features + +* **ClipboardCopy, Truncate:** add removeFindDomNode ([#8371](https://github.com/patternfly/patternfly-react/issues/8371)) ([1cb5801](https://github.com/patternfly/patternfly-react/commit/1cb580101a2a4dcb1d29a8ba46ba96f9a9912de3)) + + + + + +## 4.265.2 (2022-12-06) + + +### Bug Fixes + +* **AdvancedSearchMenu:** allow spaces in search form field values ([#8372](https://github.com/patternfly/patternfly-react/issues/8372)) ([e026b8c](https://github.com/patternfly/patternfly-react/commit/e026b8c04fe25e94c5d7c4b697d774bab562eed8)), closes [#8369](https://github.com/patternfly/patternfly-react/issues/8369) + + + + + +## [4.265.1](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.265.0...@patternfly/react-core@4.265.1) (2022-12-05) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +# 4.265.0 (2022-12-01) + + +### Bug Fixes + +* **Dropdown next:** Added itemId to DropdownItem props ([#8356](https://github.com/patternfly/patternfly-react/issues/8356)) ([17f3c4b](https://github.com/patternfly/patternfly-react/commit/17f3c4b4f2c8cb4fc3914729a83dbe8cc5258744)) +* **Menu:** updated breadcrumb drilldown example ([#8385](https://github.com/patternfly/patternfly-react/issues/8385)) ([ca6e8d4](https://github.com/patternfly/patternfly-react/commit/ca6e8d4eaeec06e85dd11f639dab3f0c94882025)) +* **TimePicker:** removed redundant onBlur ([#8366](https://github.com/patternfly/patternfly-react/issues/8366)) ([4a5a202](https://github.com/patternfly/patternfly-react/commit/4a5a202f26b36e9b9d4555b3c9c49fdc9c07b3fa)) + + +### Features + +* add pf-screen-reader for screen reader text to Badge ([#8361](https://github.com/patternfly/patternfly-react/issues/8361)) ([91f6b4d](https://github.com/patternfly/patternfly-react/commit/91f6b4d034a179361f2ec24cac169c14aa8c5195)), closes [#8354](https://github.com/patternfly/patternfly-react/issues/8354) + + + + + +## 4.264.1 (2022-11-30) + + +### Bug Fixes + +* react-core subpaths for next/deprecated modules ([#8341](https://github.com/patternfly/patternfly-react/issues/8341)) ([ed002d2](https://github.com/patternfly/patternfly-react/commit/ed002d204d12f9e138a7373ce0e7318153fbe502)) + + + + + +# [4.264.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.263.0...@patternfly/react-core@4.264.0) (2022-11-16) + + +### Features + +* **Tabs:** add TabAction, update core ver ([#8348](https://github.com/patternfly/patternfly-react/issues/8348)) ([8c584b4](https://github.com/patternfly/patternfly-react/commit/8c584b48f8e545cf226f785b873ee11eda505724)) + + + + + +# [4.263.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.262.0...@patternfly/react-core@4.263.0) (2022-11-15) + + +### Bug Fixes + +* **NumberInput:** allow user to back out number to type input ([#8304](https://github.com/patternfly/patternfly-react/issues/8304)) ([7dda7a9](https://github.com/patternfly/patternfly-react/commit/7dda7a9419f020df3f9ea2468ee35d2c28f16382)) +* **Popper:** add display contents to wrapping divs ([#8317](https://github.com/patternfly/patternfly-react/issues/8317)) ([1851a2c](https://github.com/patternfly/patternfly-react/commit/1851a2cd33a7a032e63c156a9e6c52653862bd9b)) + + +### Features + +* **spinner:** added isInline, updated link button ([#8328](https://github.com/patternfly/patternfly-react/issues/8328)) ([29f76e1](https://github.com/patternfly/patternfly-react/commit/29f76e1b1f99df446a8d1c5719a0d3fa6790ac9a)) + + + + + +# [4.262.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.261.0...@patternfly/react-core@4.262.0) (2022-11-15) + + +### Features + +* **MenuInput:** use SearchInput instead of TextInput ([#8329](https://github.com/patternfly/patternfly-react/issues/8329)) ([e00b995](https://github.com/patternfly/patternfly-react/commit/e00b995b927c76d4128d5584ff0ed0d97f672c9a)) + + + + + +# [4.261.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.260.1...@patternfly/react-core@4.261.0) (2022-11-09) + + +### Features + +* **MultipleFileUpload:** added support for helper text ([#8344](https://github.com/patternfly/patternfly-react/issues/8344)) ([f8faf8b](https://github.com/patternfly/patternfly-react/commit/f8faf8bf62b8ece44f5283922711730921fcd537)) + + + + + +## [4.260.1](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.260.0...@patternfly/react-core@4.260.1) (2022-11-09) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +# [4.260.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.259.0...@patternfly/react-core@4.260.0) (2022-11-08) + + +### Features + +* **Progress:** added helper text ([#8307](https://github.com/patternfly/patternfly-react/issues/8307)) ([7ad9398](https://github.com/patternfly/patternfly-react/commit/7ad9398588c8d7f0da5ec5c6a6bdeb58d2308d39)) + + + + + +# [4.259.0](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.258.8...@patternfly/react-core@4.259.0) (2022-11-07) + + +### Features + +* **Popper, misc:** allow components to customize popper z-index ([#8310](https://github.com/patternfly/patternfly-react/issues/8310)) ([17dff4c](https://github.com/patternfly/patternfly-react/commit/17dff4c3bde667f426994a1e9073c9c58b9c598a)) + + + + + +## [4.258.8](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.258.7...@patternfly/react-core@4.258.8) (2022-11-07) + + +### Bug Fixes + +* **bulk-select:** fixed toggle spacing ([#8326](https://github.com/patternfly/patternfly-react/issues/8326)) ([fe40f19](https://github.com/patternfly/patternfly-react/commit/fe40f19058a383cfc12e3f7a07d07af8dc579d04)) + + + + + +## [4.258.7](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.258.6...@patternfly/react-core@4.258.7) (2022-11-07) + + +### Bug Fixes + +* **TimePicker:** fixed bugs when updating time/minTime/maxTime props ([#8267](https://github.com/patternfly/patternfly-react/issues/8267)) ([f1408df](https://github.com/patternfly/patternfly-react/commit/f1408df627115592f95576f01c072e52a6c7d9e8)) + + + + + +## [4.258.6](https://github.com/patternfly/patternfly-react/compare/@patternfly/react-core@4.258.5...@patternfly/react-core@4.258.6) (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-core + + + + + +## 4.258.5 (2022-11-04) + +**Note:** Version bump only for package @patternfly/react-core + + + + + ## 4.258.4 (2022-11-01) **Note:** Version bump only for package @patternfly/react-core diff --git a/packages/react-core/package.json b/packages/react-core/package.json index 0574aea9438..883ff68d302 100644 --- a/packages/react-core/package.json +++ b/packages/react-core/package.json @@ -1,6 +1,6 @@ { "name": "@patternfly/react-core", - "version": "4.258.4", + "version": "4.267.6", "description": "This library provides a set of common React components for use with the PatternFly reference implementation.", "main": "dist/js/index.js", "module": "dist/esm/index.js", @@ -41,21 +41,22 @@ "scripts": { "build:umd": "rollup -c --environment IS_PRODUCTION", "clean": "rimraf dist", - "generate": "node scripts/copyStyles.js" + "generate": "node scripts/copyStyles.js", + "subpaths": "node scripts/copySubpaths.js" }, "dependencies": { - "@patternfly/react-icons": "^4.92.10", - "@patternfly/react-styles": "^4.91.10", - "@patternfly/react-tokens": "^4.93.10", + "@patternfly/react-icons": "^4.93.3", + "@patternfly/react-styles": "^4.92.3", + "@patternfly/react-tokens": "^4.94.3", "focus-trap": "6.9.2", "react-dropzone": "^14.2.3", "tippy.js": "5.1.2", "tslib": "^2.0.0" }, "devDependencies": { - "@patternfly/patternfly": "4.219.2", + "@patternfly/patternfly": "4.222.4", "@rollup/plugin-commonjs": "^21.0.0", - "@rollup/plugin-node-resolve": "^13.0.0", + "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^3.0.0", "css": "^2.2.3", "fs-extra": "^6.0.1", diff --git a/packages/react-core/scripts/copySubpaths.js b/packages/react-core/scripts/copySubpaths.js new file mode 100644 index 00000000000..cffb00dd7ce --- /dev/null +++ b/packages/react-core/scripts/copySubpaths.js @@ -0,0 +1,12 @@ +/** + * Copy subpath modules into the package root directory for ease of access. + */ +const { copySync } = require('fs-extra'); +const { resolve, dirname } = require('path'); + +['next', 'deprecated', 'components', 'layouts', 'helpers'].forEach(subPathName => { + const source = dirname(require.resolve(`@patternfly/react-core/dist/esm/${subPathName}`)); + const destination = resolve(__dirname, `../${subPathName}`); + + copySync(source, destination); +}); diff --git a/packages/react-core/src/components/Alert/__tests__/AlertActionCloseButton.test.tsx b/packages/react-core/src/components/Alert/__tests__/AlertActionCloseButton.test.tsx index be395f8e64a..0116fe2ac09 100644 --- a/packages/react-core/src/components/Alert/__tests__/AlertActionCloseButton.test.tsx +++ b/packages/react-core/src/components/Alert/__tests__/AlertActionCloseButton.test.tsx @@ -5,18 +5,7 @@ import userEvent from '@testing-library/user-event'; import { AlertActionCloseButton } from '../AlertActionCloseButton'; import { AlertContext } from '../AlertContext'; -jest.mock('../../Button', () => ({ - Button: ({ children, variant, isInline, onClick, ...props }) => ( - <> - -

{`variant: ${variant}`}

-

Test label

- - ), - ButtonVariant: { plain: 'plain' } -})); +jest.mock('../../Button'); test('Renders without children', () => { render( @@ -98,7 +87,7 @@ test('Renders with an aria label composed with the title and variantLabel provid test('Renders with an aria label composed with the title provided via a context and variantLabel provided via prop', () => { render( - + ); @@ -106,14 +95,14 @@ test('Renders with an aria label composed with the title provided via a context }); test('Renders with the aria label provided via prop when one is provided', () => { - render( - - - - ); - - expect(screen.getByRole('button')).toHaveAccessibleName('Aria label prop'); - }); + render( + + + + ); + + expect(screen.getByRole('button')).toHaveAccessibleName('Aria label prop'); +}); test('Matches the snapshot', () => { const { asFragment } = render( diff --git a/packages/react-core/src/components/Alert/__tests__/AlertActionLink.test.tsx b/packages/react-core/src/components/Alert/__tests__/AlertActionLink.test.tsx index 9fccb898171..49f06bd1cce 100644 --- a/packages/react-core/src/components/Alert/__tests__/AlertActionLink.test.tsx +++ b/packages/react-core/src/components/Alert/__tests__/AlertActionLink.test.tsx @@ -2,16 +2,7 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import { AlertActionLink } from '../AlertActionLink'; -jest.mock('../../Button', () => ({ - Button: ({ children, variant, isInline, ...props }) => ( - <> - -

{`variant: ${variant}`}

-

{`isInline: ${isInline}`}

- - ), - ButtonVariant: { link: 'link' } -})); +jest.mock('../../Button'); test('Renders without children', () => { render( diff --git a/packages/react-core/src/components/Alert/__tests__/AlertToggleExpandButton.test.tsx b/packages/react-core/src/components/Alert/__tests__/AlertToggleExpandButton.test.tsx index 8ae6e321253..0d7d3d3c6a3 100644 --- a/packages/react-core/src/components/Alert/__tests__/AlertToggleExpandButton.test.tsx +++ b/packages/react-core/src/components/Alert/__tests__/AlertToggleExpandButton.test.tsx @@ -5,18 +5,7 @@ import userEvent from '@testing-library/user-event'; import { AlertToggleExpandButton } from '../AlertToggleExpandButton'; import { AlertContext } from '../AlertContext'; -jest.mock('../../Button', () => ({ - Button: ({ children, variant, isInline, onClick, ...props }) => ( - <> - -

{`variant: ${variant}`}

-

Test label

- - ), - ButtonVariant: { plain: 'plain' } -})); +jest.mock('../../Button'); jest.mock('@patternfly/react-icons/dist/esm/icons/angle-right-icon', () => () => 'Icon mock'); diff --git a/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionCloseButton.test.tsx.snap b/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionCloseButton.test.tsx.snap index 82f1e3a7d65..c88f18237d9 100644 --- a/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionCloseButton.test.tsx.snap +++ b/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionCloseButton.test.tsx.snap @@ -27,5 +27,14 @@ exports[`Matches the snapshot 1`] = ` > Test label

+

+ isInline: undefined +

+

+ iconPosition: undefined +

+
`; diff --git a/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionLink.test.tsx.snap b/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionLink.test.tsx.snap index fd53fe19fee..0def8dd9fd6 100644 --- a/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionLink.test.tsx.snap +++ b/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertActionLink.test.tsx.snap @@ -10,8 +10,19 @@ exports[`Matches the snapshot 1`] = `

variant: link

+

+ Test label +

isInline: true

+

+ iconPosition: undefined +

+
`; diff --git a/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertToggleExpandButton.test.tsx.snap b/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertToggleExpandButton.test.tsx.snap index c1a42f67acc..f447c81e299 100644 --- a/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertToggleExpandButton.test.tsx.snap +++ b/packages/react-core/src/components/Alert/__tests__/__snapshots__/AlertToggleExpandButton.test.tsx.snap @@ -20,5 +20,14 @@ exports[`Matches snapshot 1`] = ` > Test label

+

+ isInline: undefined +

+

+ iconPosition: undefined +

+
`; diff --git a/packages/react-core/src/components/ApplicationLauncher/ApplicationLauncher.tsx b/packages/react-core/src/components/ApplicationLauncher/ApplicationLauncher.tsx index 54bbc7525f0..53fbd0a250f 100644 --- a/packages/react-core/src/components/ApplicationLauncher/ApplicationLauncher.tsx +++ b/packages/react-core/src/components/ApplicationLauncher/ApplicationLauncher.tsx @@ -58,6 +58,10 @@ export interface ApplicationLauncherProps extends React.HTMLProps { @@ -120,6 +124,8 @@ export class ApplicationLauncher extends React.Component ({ - Button: ({ variant, iconPosition, children, icon }) => ( - <> - -

{variant}

-

{iconPosition}

-
{icon}
- - ) -})); +jest.mock('../../Button'); test('Renders BackToTop', () => { render( @@ -138,13 +129,13 @@ test('Passes correct text content to button child component', () => { test('Passes correct variant to button child component', () => { render(); - expect(screen.getByText('primary')).toBeVisible(); + expect(screen.getByText('variant: primary')).toBeVisible(); }); test('Passes correct iconPosition to button child component', () => { render(); - expect(screen.getByText('right')).toBeVisible(); + expect(screen.getByText('iconPosition: right')).toBeVisible(); }); test('Passes correct icon to button child component', () => { diff --git a/packages/react-core/src/components/BackToTop/__tests__/__snapshots__/BackToTop.test.tsx.snap b/packages/react-core/src/components/BackToTop/__tests__/__snapshots__/BackToTop.test.tsx.snap index 85d5e50d7e5..84cec57ed52 100644 --- a/packages/react-core/src/components/BackToTop/__tests__/__snapshots__/BackToTop.test.tsx.snap +++ b/packages/react-core/src/components/BackToTop/__tests__/__snapshots__/BackToTop.test.tsx.snap @@ -9,10 +9,18 @@ exports[`Matches the snapshot 1`] = ` Back to top

- primary + variant: primary +

+

+ Test label +

+

+ isInline: undefined

- right + iconPosition: right

{ +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('backdrop').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with the pf-c-backdrop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-backdrop'); +}); + +test('Renders with only the class pf-c-backdrop by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-backdrop', { exact: true }); +}); + +test('Renders with custom class name when className prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('test-class'); +}); + +test('Renders with the inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('this is a simple backdrop'); +}); + +test('Matches the snapshot', () => { const { asFragment } = render(Backdrop); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Backdrop/__tests__/__snapshots__/Backdrop.test.tsx.snap b/packages/react-core/src/components/Backdrop/__tests__/__snapshots__/Backdrop.test.tsx.snap index c341a6f53f4..c714bc285ec 100644 --- a/packages/react-core/src/components/Backdrop/__tests__/__snapshots__/Backdrop.test.tsx.snap +++ b/packages/react-core/src/components/Backdrop/__tests__/__snapshots__/Backdrop.test.tsx.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Backdrop Test 1`] = ` +exports[`Matches the snapshot 1`] = `
{ + /** Text announced by screen readers to indicate the current content/status of the badge. */ + screenReaderText?: string; /** Adds styling to the badge to indicate it has been read */ isRead?: boolean; /** content rendered inside the Badge */ @@ -15,6 +17,7 @@ export const Badge: React.FunctionComponent = ({ isRead = false, className = '', children = '', + screenReaderText, ...props }: BadgeProps) => ( = ({ className={css(styles.badge, (isRead ? styles.modifiers.read : styles.modifiers.unread) as any, className)} > {children} + {screenReaderText && {screenReaderText}} ); Badge.displayName = 'Badge'; diff --git a/packages/react-core/src/components/Badge/__tests__/Badge.test.tsx b/packages/react-core/src/components/Badge/__tests__/Badge.test.tsx index f2f679c014d..5ffefc19975 100644 --- a/packages/react-core/src/components/Badge/__tests__/Badge.test.tsx +++ b/packages/react-core/src/components/Badge/__tests__/Badge.test.tsx @@ -31,6 +31,16 @@ test('Renders with class name pf-m-read when isRead prop is true', () => { expect(screen.getByText('Test')).toHaveClass('pf-m-read'); }); +test('Does not render pf-screen-reader class by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toContainHTML(''); +}); + +test('Renders screenReaderText passed via prop', () => { + render(Test); + expect(screen.getByText('Custom screen reader text')).toBeInTheDocument(); +}); + test('Renders with custom class name when className prop is provided', () => { render(Test); expect(screen.getByText('Test')).toHaveClass('custom-class'); diff --git a/packages/react-core/src/components/Badge/examples/BadgeUnread.tsx b/packages/react-core/src/components/Badge/examples/BadgeUnread.tsx index 19c2e4bb3cf..b5bd85255a9 100644 --- a/packages/react-core/src/components/Badge/examples/BadgeUnread.tsx +++ b/packages/react-core/src/components/Badge/examples/BadgeUnread.tsx @@ -3,6 +3,17 @@ import { Badge } from '@patternfly/react-core'; export const BadgeUnread: React.FunctionComponent = () => ( - 7 24 240 999+ + + 7 + + + 24 + + + 240 + + + 999+ + ); diff --git a/packages/react-core/src/components/Button/Button.tsx b/packages/react-core/src/components/Button/Button.tsx index 7cfdb8fe470..9a1e5099797 100644 --- a/packages/react-core/src/components/Button/Button.tsx +++ b/packages/react-core/src/components/Button/Button.tsx @@ -175,6 +175,7 @@ const ButtonBase: React.FunctionComponent = ({ ( + <> + +

{`variant: ${variant}`}

+

Test label

+

{`isInline: ${isInline}`}

+

{`iconPosition: ${iconPosition}`}

+
{icon}
+ +); + +export const ButtonVariant = { plain: 'plain', link: 'link' }; diff --git a/packages/react-core/src/components/Button/__mocks__/index.ts b/packages/react-core/src/components/Button/__mocks__/index.ts new file mode 100644 index 00000000000..8b166a86e4d --- /dev/null +++ b/packages/react-core/src/components/Button/__mocks__/index.ts @@ -0,0 +1 @@ +export * from './Button'; diff --git a/packages/react-core/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap b/packages/react-core/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap index 79ce3c4478f..596c17e9380 100644 --- a/packages/react-core/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap +++ b/packages/react-core/src/components/Button/__tests__/__snapshots__/Button.test.tsx.snap @@ -240,7 +240,7 @@ exports[`Button isLoading inline link 1`] = ` diff --git a/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx b/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx index de0e55165c9..996a2f88d12 100644 --- a/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx +++ b/packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx @@ -20,6 +20,15 @@ export enum Weekday { Saturday } +export interface CalendarMonthInlineProps { + /** Component wrapping the calendar month when used inline. Recommended to be 'article'. */ + component?: keyof JSX.IntrinsicElements; + /** Title of the calendar rendered above the inline calendar month. Recommended to be a 'title' component. */ + title?: React.ReactNode; + /** Id of the accessible label of the calendar month. Recommended to map to the title. */ + ariaLabelledby?: string; +} + /** Additional properties that extend from and can be passed to the main component. These * properties allow customizing the calendar formatting and aria-labels. */ @@ -49,6 +58,8 @@ export interface CalendarFormat { weekStart?: 0 | 1 | 2 | 3 | 4 | 5 | 6 | Weekday; /** Accessible label for the year input. */ yearInputAriaLabel?: string; + /** Props used to ensure accessibility when displaying the calendar month inline. */ + inlineProps?: CalendarMonthInlineProps; } export interface CalendarProps extends CalendarFormat, Omit, 'onChange'> { @@ -133,6 +144,7 @@ export const CalendarMonth = ({ yearInputAriaLabel = 'Select year', cellAriaLabel, isDateFocused = false, + inlineProps, ...props }: CalendarProps) => { const longMonths = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map(monthNum => new Date(1990, monthNum)).map(monthFormat); @@ -232,7 +244,8 @@ export const CalendarMonth = ({ const isHoveredDateValid = isValidated(hoveredDate); const monthFormatted = monthFormat(focusedDate); const yearFormatted = yearFormat(focusedDate); - return ( + + const calendarToRender = (
@@ -386,4 +399,16 @@ export const CalendarMonth = ({
); + + if (inlineProps !== undefined) { + const Component = (inlineProps.component ? inlineProps.component : 'article') as any; + return ( + + {inlineProps.title} + {calendarToRender} + + ); + } + return calendarToRender; }; +CalendarMonth.displayName = 'CalendarMonth'; diff --git a/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx b/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx index a5d5214408e..4b70968618e 100644 --- a/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx +++ b/packages/react-core/src/components/CalendarMonth/__tests__/CalendarMonth.test.tsx @@ -55,3 +55,12 @@ test('Next year dates have correct year in aria label', () => { const nextYearDate = screen.getByRole('button', { name: '1 January 2025' }); expect(nextYearDate).toBeVisible(); }); + +test('InlineProps render correct wrapper component and attributes', () => { + render(Title
, ariaLabelledby: "hi"}} />); + + const article = screen.getByRole('article'); + expect(article).toHaveAttribute('aria-labelledby', 'hi'); + const title = screen.getByText('Title'); + expect(title).toBeVisible(); +}); diff --git a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md index 993a87a1501..0c3b27f6938 100644 --- a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md +++ b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonth.md @@ -2,7 +2,7 @@ id: Calendar month section: components cssPrefix: pf-c-calendar-month -propComponents: ['CalendarMonth', 'CalendarFormat'] +propComponents: ['CalendarMonth', 'CalendarFormat', 'CalendarMonthInlineProps'] --- ## Examples diff --git a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthDateRange.tsx b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthDateRange.tsx index 1afd9cdbbc9..1bdfd79ea46 100644 --- a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthDateRange.tsx +++ b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthDateRange.tsx @@ -1,10 +1,27 @@ import React from 'react'; -import { CalendarMonth } from '@patternfly/react-core'; +import { CalendarMonth, Title, CalendarMonthInlineProps } from '@patternfly/react-core'; export const CalendarMonthDateRange: React.FunctionComponent = () => { const startDate = new Date(2020, 10, 11); const endDate = new Date(2020, 10, 24); const disablePreStartDates = (date: Date) => date >= startDate; - return ; + const inlineProps: CalendarMonthInlineProps = { + component: 'article', + title: ( + + Calendar month displaying a range + + ), + ariaLabelledby: 'display-range' + }; + + return ( + + ); }; diff --git a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthSelectableDate.tsx b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthSelectableDate.tsx index d61f03d889c..f9fe55fd318 100644 --- a/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthSelectableDate.tsx +++ b/packages/react-core/src/components/CalendarMonth/examples/CalendarMonthSelectableDate.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { CalendarMonth } from '@patternfly/react-core'; +import { CalendarMonth, Title, CalendarMonthInlineProps } from '@patternfly/react-core'; export const CalendarMonthSelectableDate: React.FunctionComponent = () => { const [date, setDate] = React.useState(new Date(2020, 10, 24)); @@ -9,10 +9,20 @@ export const CalendarMonthSelectableDate: React.FunctionComponent = () => { console.log(`updated month: ${newDate.getMonth()}, updated year: ${newDate.getFullYear()}`); }; + const inlineProps: CalendarMonthInlineProps = { + component: 'article', + title: ( + + Select your favorite date + + ), + ariaLabelledby: 'favorite-date' + }; + return ( - + <> +
Selected date: {date.toString()}
- -
+ ); }; diff --git a/packages/react-core/src/components/ContextSelector/ContextSelector.tsx b/packages/react-core/src/components/ContextSelector/ContextSelector.tsx index 834b9097399..b0c2227e17e 100644 --- a/packages/react-core/src/components/ContextSelector/ContextSelector.tsx +++ b/packages/react-core/src/components/ContextSelector/ContextSelector.tsx @@ -61,6 +61,8 @@ export interface ContextSelectorProps extends OUIAProps { isFlipEnabled?: boolean; /** Id of the context selector */ id?: string; + /** z-index of the context selector when menuAppendTo is not inline. */ + zIndex?: number; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ @@ -88,7 +90,8 @@ export class ContextSelector extends React.Component ); } diff --git a/packages/react-core/src/components/Dropdown/Dropdown.tsx b/packages/react-core/src/components/Dropdown/Dropdown.tsx index 8014f93cb49..c7a162b3768 100644 --- a/packages/react-core/src/components/Dropdown/Dropdown.tsx +++ b/packages/react-core/src/components/Dropdown/Dropdown.tsx @@ -56,6 +56,10 @@ export interface DropdownProps extends React.HTMLProps, OUIAProp * appended inline, e.g. `menuAppendTo="parent"` */ isFlipEnabled?: boolean; + /** @beta Opt-in for updated popper that does not use findDOMNode. */ + removeFindDomNode?: boolean; + /** z-index of the dropdown when menuAppendTo is not inline. */ + zIndex?: number; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ @@ -72,6 +76,8 @@ export const Dropdown: React.FunctionComponent = ({ contextProps, menuAppendTo = 'inline', isFlipEnabled = true, + removeFindDomNode = false, + zIndex = 9999, ...props }: DropdownProps) => ( = ({ ...contextProps }} > - + ); Dropdown.displayName = 'Dropdown'; diff --git a/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx b/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx index 29c8600d1bc..aaebd987c4b 100644 --- a/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx +++ b/packages/react-core/src/components/Dropdown/DropdownWithContext.tsx @@ -77,6 +77,7 @@ export class DropdownWithContext extends React.Component ); diff --git a/packages/react-core/src/components/HelperText/__mocks__/HelperText.tsx b/packages/react-core/src/components/HelperText/__mocks__/HelperText.tsx new file mode 100644 index 00000000000..070adc10f9c --- /dev/null +++ b/packages/react-core/src/components/HelperText/__mocks__/HelperText.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import { HelperTextProps } from '../'; + +export const HelperText = ({ children, isLiveRegion }: HelperTextProps) => ( + <> +
{children}
+

{`isLiveRegion: ${isLiveRegion}`}

+ +); diff --git a/packages/react-core/src/components/HelperText/__mocks__/HelperTextItem.tsx b/packages/react-core/src/components/HelperText/__mocks__/HelperTextItem.tsx new file mode 100644 index 00000000000..c431a78864c --- /dev/null +++ b/packages/react-core/src/components/HelperText/__mocks__/HelperTextItem.tsx @@ -0,0 +1,9 @@ +import React from 'react'; +import { HelperTextItemProps } from '../'; + +export const HelperTextItem = ({ children, variant }: HelperTextItemProps) => ( + <> +
{children}
+

{`variant: ${variant}`}

+ +); diff --git a/packages/react-core/src/components/HelperText/__mocks__/index.ts b/packages/react-core/src/components/HelperText/__mocks__/index.ts new file mode 100644 index 00000000000..c35042a2c6b --- /dev/null +++ b/packages/react-core/src/components/HelperText/__mocks__/index.ts @@ -0,0 +1,2 @@ +export * from './HelperText'; +export * from './HelperTextItem'; diff --git a/packages/react-core/src/components/Label/examples/LabelCompact.tsx b/packages/react-core/src/components/Label/examples/LabelCompact.tsx index 2f77a0644a7..a0567cae904 100644 --- a/packages/react-core/src/components/Label/examples/LabelCompact.tsx +++ b/packages/react-core/src/components/Label/examples/LabelCompact.tsx @@ -14,10 +14,10 @@ export const LabelCompact: React.FunctionComponent = () => ( {' '} -
diff --git a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx index 2b7b0a947c6..7f59631f14c 100644 --- a/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/__tests__/MultipleFileUploadStatusItem.test.tsx @@ -99,3 +99,38 @@ describe('MultipleFileUploadStatusItem', () => { expect(asFragment()).toMatchSnapshot(); }); }); + +test('does not render helper text by default', () => { + const testFile = new File(['foo'], 'testFile.txt'); + render( + + ); + + const helperText = screen.queryByText('Test helper text'); + + expect(helperText).not.toBeInTheDocument(); +}); + +test('renders helper text', () => { + const testFile = new File(['foo'], 'testFile.txt'); + render( + + ); + + const helperText = screen.getByText('Test helper text'); + + expect(helperText).toBeVisible(); +}); diff --git a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md index c6c9474aa45..2f1c7116706 100644 --- a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md +++ b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUpload.md @@ -42,5 +42,11 @@ File upload - multiple is designed in a composable manner to make customization ### Basic +The below example demonstrates a typical application of file upload - multiple, with a few tweaks from that typical application to enhance the convenience of the example. + +The "Show as horizontal" checkbox can be used to easily toggle the `isHorizontal` prop, showing our available styling variations. + +The "Demonstrate error reporting by forcing uploads to fail" checkbox shows how our `progressHelperText` prop can be used to provide status messages to users, such as when a file fails to upload. While this checkbox is checked it will cause any file uploaded to automatically fail the file reading process, and helper text will be dynamically rendered which informs the user of that error. + ```ts file="./MultipleFileUploadBasic.tsx" ``` diff --git a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx index aea0ad6e291..689e067a6fa 100644 --- a/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx +++ b/packages/react-core/src/components/MultipleFileUpload/examples/MultipleFileUploadBasic.tsx @@ -4,7 +4,9 @@ import { MultipleFileUploadMain, MultipleFileUploadStatus, MultipleFileUploadStatusItem, - Checkbox + Checkbox, + HelperText, + HelperTextItem } from '@patternfly/react-core'; import UploadIcon from '@patternfly/react-icons/dist/esm/icons/upload-icon'; @@ -17,6 +19,7 @@ interface readFile { export const MultipleFileUploadBasic: React.FunctionComponent = () => { const [isHorizontal, setIsHorizontal] = React.useState(false); + const [fileUploadShouldFail, setFileUploadShouldFail] = React.useState(false); const [currentFiles, setCurrentFiles] = React.useState([]); const [readFileData, setReadFileData] = React.useState([]); const [showStatus, setShowStatus] = React.useState(false); @@ -53,6 +56,17 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { setReadFileData(newReadFiles); }; + /** Forces uploaded files to become corrupted if "Demonstrate error reporting by forcing uploads to fail" is selected in the example, + * only used in this example for demonstration purposes */ + const updateCurrentFiles = (files: File[]) => { + if (fileUploadShouldFail) { + const corruptedFiles = files.map(file => ({ ...file, lastModified: ('foo' as unknown) as number })); + setCurrentFiles(prevFiles => [...prevFiles, ...corruptedFiles]); + } else { + setCurrentFiles(prevFiles => [...prevFiles, ...files]); + } + }; + // callback that will be called by the react dropzone with the newly dropped file objects const handleFileDrop = (droppedFiles: File[]) => { // identify what, if any, files are re-uploads of already uploaded files @@ -63,7 +77,7 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { * won't realize that the status items for the re-uploaded files needs to be re-rendered */ Promise.resolve() .then(() => removeFiles(reUploads.map(file => file.name))) - .then(() => setCurrentFiles(prevFiles => [...prevFiles, ...droppedFiles])); + .then(() => updateCurrentFiles(droppedFiles)); }; // callback called by the status item when a file is successfully read with the built-in file reader @@ -79,6 +93,18 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { ]); }; + // add helper text to a status item showing any error encountered during the file reading process + const createHelperText = (file: File) => { + const fileResult = readFileData.find(readFile => readFile.fileName === file.name); + if (fileResult?.loadError) { + return ( + + {fileResult.loadError.toString()} + + ); + } + }; + const successfullyReadFileCount = readFileData.filter(fileData => fileData.loadResult === 'success').length; return ( @@ -113,6 +139,7 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { onClearClick={() => removeFiles([file.name])} onReadSuccess={handleReadSuccess} onReadFail={handleReadFail} + progressHelperText={createHelperText(file)} /> ))} @@ -124,6 +151,12 @@ export const MultipleFileUploadBasic: React.FunctionComponent = () => { isChecked={isHorizontal} onChange={() => setIsHorizontal(!isHorizontal)} /> + setFileUploadShouldFail(!fileUploadShouldFail)} + /> ); }; diff --git a/packages/react-core/src/components/Nav/NavItem.tsx b/packages/react-core/src/components/Nav/NavItem.tsx index 36eae7851dd..55f50cc07d5 100644 --- a/packages/react-core/src/components/Nav/NavItem.tsx +++ b/packages/react-core/src/components/Nav/NavItem.tsx @@ -14,7 +14,7 @@ export interface NavItemProps extends Omit, ' styleChildren?: boolean; /** Additional classes added to the nav item */ className?: string; - /** Target navigation link */ + /** Target navigation link. Should not be used if the flyout prop is defined. */ to?: string; /** Flag indicating whether the item is active */ isActive?: boolean; @@ -28,10 +28,12 @@ export interface NavItemProps extends Omit, ' onClick?: NavSelectClickHandler; /** Component used to render NavItems if React.isValidElement(children) is false */ component?: React.ReactNode; - /** Flyout of a nav item. This should be a Menu component. */ + /** Flyout of a nav item. This should be a Menu component. Should not be used if the to prop is defined. */ flyout?: React.ReactElement; /** Callback when flyout is opened or closed */ onShowFlyout?: () => void; + /** z-index of the flyout nav item */ + zIndex?: number; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ @@ -53,6 +55,7 @@ export const NavItem: React.FunctionComponent = ({ onShowFlyout, ouiaId, ouiaSafe, + zIndex = 9999, ...props }: NavItemProps) => { const { flyoutRef, setFlyoutRef } = React.useContext(NavContext); @@ -62,8 +65,14 @@ export const NavItem: React.FunctionComponent = ({ const ref = React.useRef(); const flyoutVisible = ref === flyoutRef; const popperRef = React.useRef(); - const Component = component as any; const hasFlyout = flyout !== undefined; + const Component = hasFlyout ? 'button' : (component as any); + + // A NavItem should not be both a link and a flyout + if (to && hasFlyout) { + // eslint-disable-next-line no-console + console.error('NavItem cannot have both "to" and "flyout" props.'); + } const showFlyout = (show: boolean, override?: boolean) => { if ((!flyoutVisible || override) && show) { @@ -100,11 +109,7 @@ export const NavItem: React.FunctionComponent = ({ const key = event.key; const target = event.target as HTMLElement; - if (!(popperRef?.current?.contains(target) || (hasFlyout && ref?.current?.contains(target)))) { - return; - } - - if (key === ' ' || key === 'ArrowRight') { + if ((key === ' ' || key === 'Enter' || key === 'ArrowRight') && hasFlyout && ref?.current?.contains(target)) { event.stopPropagation(); event.preventDefault(); if (!flyoutVisible) { @@ -113,7 +118,9 @@ export const NavItem: React.FunctionComponent = ({ } } - if (key === 'Escape' || key === 'ArrowLeft') { + // We only want the NavItem to handle closing a flyout menu if only the first level flyout is open. + // Otherwise, MenuItem should handle closing its flyouts + if ((key === 'Escape' || key === 'ArrowLeft') && popperRef?.current?.querySelectorAll('.pf-c-menu').length === 1) { if (flyoutVisible) { event.stopPropagation(); event.preventDefault(); @@ -159,6 +166,8 @@ export const NavItem: React.FunctionComponent = ({ 'aria-expanded': flyoutVisible }; + const tabIndex = isNavOpen ? null : -1; + const renderDefaultLink = (context: any): React.ReactNode => { const preventLinkDefault = preventDefault || !to; return ( @@ -172,7 +181,7 @@ export const NavItem: React.FunctionComponent = ({ className )} aria-current={isActive ? 'page' : null} - tabIndex={isNavOpen ? null : '-1'} + tabIndex={tabIndex} {...(hasFlyout && { ...ariaFlyoutProps })} {...props} > @@ -189,7 +198,7 @@ export const NavItem: React.FunctionComponent = ({ ...(styleChildren && { className: css(styles.navLink, isActive && styles.modifiers.current, child.props && child.props.className) }), - tabIndex: child.props.tabIndex || isNavOpen ? null : -1, + tabIndex: child.props.tabIndex || tabIndex, children: hasFlyout ? ( {child.props.children} @@ -221,6 +230,7 @@ export const NavItem: React.FunctionComponent = ({ placement="right-start" isVisible={flyoutVisible} onDocumentKeyDown={handleFlyout} + zIndex={zIndex} /> ); diff --git a/packages/react-core/src/components/Nav/examples/NavFlyout.tsx b/packages/react-core/src/components/Nav/examples/NavFlyout.tsx index 2ef83df4de6..a6a2e45e022 100644 --- a/packages/react-core/src/components/Nav/examples/NavFlyout.tsx +++ b/packages/react-core/src/components/Nav/examples/NavFlyout.tsx @@ -19,12 +19,7 @@ export const NavFlyout: React.FunctionComponent = () => { - + Next menu {Array.apply(0, Array(numFlyouts - depth)).map((_item, index: number) => ( @@ -38,12 +33,7 @@ export const NavFlyout: React.FunctionComponent = () => { Menu {depth} item {index} ))} - + Next menu @@ -81,7 +71,6 @@ export const NavFlyout: React.FunctionComponent = () => { preventDefault flyout={curFlyout} id="nav-flyout-default-link-3" - to="#nav-flyout-default-link-3" itemId="nav-flyout-default-link-3" isActive={activeItem === 'nav-flyout-default-link-3'} > diff --git a/packages/react-core/src/components/NumberInput/NumberInput.tsx b/packages/react-core/src/components/NumberInput/NumberInput.tsx index 80e04f4ad71..d4d3ed43954 100644 --- a/packages/react-core/src/components/NumberInput/NumberInput.tsx +++ b/packages/react-core/src/components/NumberInput/NumberInput.tsx @@ -10,7 +10,7 @@ import { TextInput } from '../TextInput'; export interface NumberInputProps extends React.HTMLProps { /** Value of the number input */ - value?: number | null; + value?: number | ''; /** Additional classes added to the number input */ className?: string; /** Sets the width of the number input to a number of characters */ @@ -89,7 +89,6 @@ export const NumberInput: React.FunctionComponent = ({ plusBtnProps, ...props }: NumberInputProps) => { - value = value || 0; const numberInputUnit =
{unit}
; const keyDownHandler = inputProps && inputProps.onKeyDown ? inputProps.onKeyDown : defaultKeyDownHandler({ inputName, onMinus, onPlus }); diff --git a/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx b/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx index 3f079d3fa59..c2bc167c1f4 100644 --- a/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx +++ b/packages/react-core/src/components/NumberInput/__tests__/NumberInput.test.tsx @@ -195,22 +195,22 @@ describe('numberInput', () => { expect(input).toHaveDisplayValue('47.01'); }); - test('renders 0 if no value passed', () => { + test('renders 0 (default value) if no value passed', () => { render(); const input = screen.getByRole('spinbutton'); expect(input).toHaveDisplayValue('0'); }); - test('renders 0 if undefined value passed', () => { + test('renders 0 (default value) if undefined value passed', () => { render(); const input = screen.getByRole('spinbutton'); expect(input).toHaveDisplayValue('0'); }); - test('renders 0 if null value passed', () => { + test('renders nothing if null value passed', () => { render(); const input = screen.getByRole('spinbutton'); - expect(input).toHaveDisplayValue('0'); + expect(input).toHaveDisplayValue(''); }); test('does not throw an error if onChange is passed via inputProps as well as the onChange prop', () => { diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInput.md b/packages/react-core/src/components/NumberInput/examples/NumberInput.md index ef7f961cdd0..9e90f62a691 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInput.md +++ b/packages/react-core/src/components/NumberInput/examples/NumberInput.md @@ -19,6 +19,8 @@ propComponents: ['NumberInput'] ### With unit and thresholds +To enable a user entered value to snap to the nearest threshold if the entered input is out of bounds, define the blur event handler. + ```ts file="./NumberInputUnitThreshold.tsx" ``` diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStep.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStep.tsx index d46391fa724..c63f02b754b 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStep.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStep.tsx @@ -2,16 +2,16 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputCustomStep: React.FunctionComponent = () => { - const [value, setValue] = React.useState(90); + const [value, setValue] = React.useState(90); const step = 3; const stepper = (stepValue: number) => { - setValue(value + stepValue); + setValue((value || 0) + stepValue); }; const onChange = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - setValue(Number(target.value)); + const value = (event.target as HTMLInputElement).value; + setValue(value === '' ? value : +value); }; return ( diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStepAndThreshold.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStepAndThreshold.tsx index a77f875dc3a..f410c255616 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStepAndThreshold.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputCustomStepAndThreshold.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputCustomStepAndThreshold: React.FunctionComponent = () => { - const [value, setValue] = React.useState(90); + const [value, setValue] = React.useState(90); const minValue = 90; const maxValue = 100; const step = 3; @@ -19,13 +19,12 @@ export const NumberInputCustomStepAndThreshold: React.FunctionComponent = () => }; const stepper = (stepValue: number) => { - setValue(value + stepValue); + setValue((value || 0) + stepValue); }; const onChange = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - const newValue = normalizeBetween(isNaN(+target.value) ? 0 : Number(target.value), minValue, maxValue); - setValue(newValue); + const value = (event.target as HTMLInputElement).value; + setValue(value === '' ? value : +value); }; const onBlur = (event: React.FormEvent) => { diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputDefault.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputDefault.tsx index a3e973a79f2..4f86471db04 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputDefault.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputDefault.tsx @@ -2,20 +2,20 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputDefault: React.FunctionComponent = () => { - const [value, setValue] = React.useState(90); + const [value, setValue] = React.useState(90); const onMinus = () => { - const newValue = value - 1; + const newValue = (value || 0) - 1; setValue(newValue); }; const onChange = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - setValue(Number(target.value)); + const value = (event.target as HTMLInputElement).value; + setValue(value === '' ? value : +value); }; const onPlus = () => { - const newValue = value + 1; + const newValue = (value || 0) + 1; setValue(newValue); }; diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputDisabled.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputDisabled.tsx index 20b35f919d2..5f182ac00df 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputDisabled.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputDisabled.tsx @@ -2,22 +2,22 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputDisabled: React.FunctionComponent = () => { - const [value, setValue] = React.useState(100); + const [value, setValue] = React.useState(100); const minValue = 0; const maxValue = 100; const onMinus = () => { - const newValue = value - 1; + const newValue = (value || 0) - 1; setValue(newValue); }; const onChange = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - setValue(Number(target.value)); + const value = (event.target as HTMLInputElement).value; + setValue(value === '' ? value : +value); }; const onPlus = () => { - const newValue = value + 1; + const newValue = (value || 0) + 1; setValue(newValue); }; diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputUnit.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputUnit.tsx index 1fcb8a79c0c..5cab6f02cc5 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputUnit.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputUnit.tsx @@ -2,26 +2,26 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputUnit: React.FunctionComponent = () => { - const [value1, setValue1] = React.useState(90); - const [value2, setValue2] = React.useState(Number((1.0).toFixed(2))); + const [value1, setValue1] = React.useState(90); + const [value2, setValue2] = React.useState(Number((1.0).toFixed(2))); - const onMinus1 = () => setValue1(value1 - 1); + const onMinus1 = () => setValue1((value1 || 0) - 1); const onChange1 = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - setValue1(Number(target.value)); + const value = (event.target as HTMLInputElement).value; + setValue1(value === '' ? value : +value); }; - const onPlus1 = () => setValue1(value1 + 1); + const onPlus1 = () => setValue1((value1 || 0) + 1); const onMinus2 = () => { - const newValue = Number((value2 - 0.01).toFixed(2)); + const newValue = Number(((value2 || 0) - 0.01).toFixed(2)); setValue2(newValue); }; const onChange2 = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - setValue2(Number(target.value)); + const value = (event.target as HTMLInputElement).value; + setValue2(value === '' ? value : +value); }; const onPlus2 = () => { - const newValue = Number((value2 + 0.01).toFixed(2)); + const newValue = Number(((value2 || 0) + 0.01).toFixed(2)); setValue2(newValue); }; diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputUnitThreshold.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputUnitThreshold.tsx index 5ef9de026d2..98cf3c66ed9 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputUnitThreshold.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputUnitThreshold.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputUnitThreshold: React.FunctionComponent = () => { - const [value, setValue] = React.useState(0); + const [value, setValue] = React.useState(0); const minValue = 0; const maxValue = 10; @@ -18,18 +18,27 @@ export const NumberInputUnitThreshold: React.FunctionComponent = () => { }; const onMinus = () => { - const newValue = normalizeBetween(value - 1, minValue, maxValue); + const newValue = normalizeBetween((value as number) - 1, minValue, maxValue); setValue(newValue); }; const onChange = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - const newValue = normalizeBetween(isNaN(+target.value) ? 0 : Number(target.value), minValue, maxValue); - setValue(newValue); + const value = (event.target as HTMLInputElement).value; + setValue(value === '' ? value : +value); + }; + + const onBlur = (event: React.FocusEvent) => { + const blurVal = +event.target.value; + + if (blurVal < minValue) { + setValue(minValue); + } else if (blurVal > maxValue) { + setValue(maxValue); + } }; const onPlus = () => { - const newValue = normalizeBetween(value + 1, minValue, maxValue); + const newValue = normalizeBetween((value as number) + 1, minValue, maxValue); setValue(newValue); }; @@ -43,6 +52,7 @@ export const NumberInputUnitThreshold: React.FunctionComponent = () => { max={maxValue} onMinus={onMinus} onChange={onChange} + onBlur={onBlur} onPlus={onPlus} inputName="input" inputAriaLabel="number input" diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputVaryingSizes.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputVaryingSizes.tsx index ddfa0c9209c..d6430cf9dbe 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputVaryingSizes.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputVaryingSizes.tsx @@ -2,25 +2,25 @@ import React from 'react'; import { NumberInput } from '@patternfly/react-core'; export const NumberInputVaryingSizes: React.FunctionComponent = () => { - const [input1Value, setInput1Value] = React.useState(1); - const [input2Value, setInput2Value] = React.useState(1234567890); - const [input3Value, setInput3Value] = React.useState(5); - const [input4Value, setInput4Value] = React.useState(12345); + const [input1Value, setInput1Value] = React.useState(1); + const [input2Value, setInput2Value] = React.useState(1234567890); + const [input3Value, setInput3Value] = React.useState(5); + const [input4Value, setInput4Value] = React.useState(12345); const onChange = ( event: React.FormEvent, - updateFunction: React.Dispatch> + updateFunction: React.Dispatch> ) => { - const target = event.target as HTMLInputElement; - updateFunction(Number(target.value)); + const value = (event.target as HTMLInputElement).value; + updateFunction(value === '' ? value : +value); }; - const onMinus = (value, updateFunction: React.Dispatch>) => { - updateFunction(value - 1); + const onMinus = (value: number | '', updateFunction: React.Dispatch>) => { + updateFunction((value || 0) - 1); }; - const onPlus = (value, updateFunction: React.Dispatch>) => { - updateFunction(value + 1); + const onPlus = (value: number | '', updateFunction: React.Dispatch>) => { + updateFunction((value || 0) + 1); }; return ( diff --git a/packages/react-core/src/components/NumberInput/examples/NumberInputWithStatus.tsx b/packages/react-core/src/components/NumberInput/examples/NumberInputWithStatus.tsx index b5b6570a0f8..ef776062074 100644 --- a/packages/react-core/src/components/NumberInput/examples/NumberInputWithStatus.tsx +++ b/packages/react-core/src/components/NumberInput/examples/NumberInputWithStatus.tsx @@ -9,22 +9,21 @@ export const NumberInputWithStatus: React.FunctionComponent = () => { const [value, setValue] = React.useReducer((state, newVal) => Math.max(min, Math.min(max, Number(newVal))), 5); const onPlus = () => { - const newVal = value + 1; + const newVal = (value || 0) + 1; setValue(newVal); validate(newVal); }; const onMinus = () => { - const newVal = value - 1; + const newVal = (value || 0) - 1; setValue(newVal); validate(newVal); }; const onChange = (event: React.FormEvent) => { - const target = event.target as HTMLInputElement; - const newVal = isNaN(+target.value) ? 5 : Number(target.value); - setValue(newVal); - validate(newVal); + const value = (event.target as HTMLInputElement).value; + setValue(value === '' ? value : +value); + validate(value); }; const validate = newVal => { diff --git a/packages/react-core/src/components/OptionsMenu/OptionsMenu.tsx b/packages/react-core/src/components/OptionsMenu/OptionsMenu.tsx index a26728b5494..9a612606830 100644 --- a/packages/react-core/src/components/OptionsMenu/OptionsMenu.tsx +++ b/packages/react-core/src/components/OptionsMenu/OptionsMenu.tsx @@ -43,6 +43,10 @@ export interface OptionsMenuProps extends React.HTMLProps, OUIAP * menuAppendTo={document.getElementById('target')} */ menuAppendTo?: HTMLElement | (() => HTMLElement) | 'inline' | 'parent'; + /** @beta Opt-in for updated popper that does not use findDOMNode. */ + removeFindDomNode?: boolean; + /** z-index of the options menu when menuAppendTo is not inline. */ + zIndex?: number; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ @@ -61,6 +65,8 @@ export const OptionsMenu: React.FunctionComponent = ({ menuAppendTo = 'inline', ouiaId, ouiaSafe = true, + removeFindDomNode = false, + zIndex = 9999, ...props }: OptionsMenuProps) => ( = ({ isGrouped={isGrouped} toggle={toggle} menuAppendTo={menuAppendTo} + removeFindDomNode={removeFindDomNode} + zIndex={zIndex} {...props} /> diff --git a/packages/react-core/src/components/Pagination/Pagination.tsx b/packages/react-core/src/components/Pagination/Pagination.tsx index 437230b2666..cb030124470 100644 --- a/packages/react-core/src/components/Pagination/Pagination.tsx +++ b/packages/react-core/src/components/Pagination/Pagination.tsx @@ -6,6 +6,7 @@ import { fillTemplate } from '../../helpers'; import { Navigation } from './Navigation'; import { PaginationOptionsMenu } from './PaginationOptionsMenu'; import { useOUIAProps, OUIAProps } from '../../helpers'; +import { formatBreakpointMods } from '../../helpers/util'; import widthChars from '@patternfly/react-tokens/dist/esm/c_pagination__nav_page_select_c_form_control_width_chars'; export enum PaginationVariant { @@ -107,6 +108,17 @@ export interface PaginationProps extends React.HTMLProps, OUIAPr dropDirection?: 'up' | 'down'; /** Page to start at. */ firstPage?: number; + /** @beta Flag indicating that pagination should use page insets. */ + usePageInsets?: boolean; + /** @beta Insets at various breakpoints. */ + inset?: { + default?: 'insetNone' | 'insetSm' | 'insetMd' | 'insetLg' | 'insetXl' | 'inset2xl'; + sm?: 'insetNone' | 'insetSm' | 'insetMd' | 'insetLg' | 'insetXl' | 'inset2xl'; + md?: 'insetNone' | 'insetSm' | 'insetMd' | 'insetLg' | 'insetXl' | 'inset2xl'; + lg?: 'insetNone' | 'insetSm' | 'insetMd' | 'insetLg' | 'insetXl' | 'inset2xl'; + xl?: 'insetNone' | 'insetSm' | 'insetMd' | 'insetLg' | 'insetXl' | 'inset2xl'; + '2xl'?: 'insetNone' | 'insetSm' | 'insetMd' | 'insetLg' | 'insetXl' | 'inset2xl'; + }; /** Flag indicating if pagination is compact. */ isCompact?: boolean; /** Flag indicating if pagination is disabled. */ @@ -215,6 +227,8 @@ export const Pagination: React.FunctionComponent = ({ onLastClick = () => undefined, ouiaId, ouiaSafe = true, + usePageInsets, + inset, ...props }: PaginationProps) => { const paginationRef = React.useRef(null); @@ -270,6 +284,8 @@ export const Pagination: React.FunctionComponent = ({ className={css( styles.pagination, variant === PaginationVariant.bottom && styles.modifiers.bottom, + usePageInsets && styles.modifiers.pageInsets, + formatBreakpointMods(inset, styles), isCompact && styles.modifiers.compact, isStatic && styles.modifiers.static, isSticky && styles.modifiers.sticky, diff --git a/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx b/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx index 1f289a08034..020032ee4ac 100644 --- a/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx +++ b/packages/react-core/src/components/Pagination/__tests__/Pagination.test.tsx @@ -114,6 +114,18 @@ describe('Pagination', () => { rerender(); expect(screen.getByLabelText('test label')).toHaveAttribute('id', id); }); + + test('should not update generated options menu id on rerenders', () => { + const { rerender } = render(); + const id = screen.getByLabelText("test label").getAttribute("id"); + rerender(); + expect(screen.getByLabelText("test label")).toHaveAttribute("id", id); + }); + + test('page insets', () => { + render(); + expect(screen.getByTestId('pagination-insets')).toHaveClass('pf-m-page-insets'); + }); }); describe('API', () => { @@ -322,5 +334,21 @@ describe('Pagination', () => { expect(onPerPage).not.toHaveBeenCalled(); }); }); + + Object.values(['insetNone', 'insetSm', 'insetMd', 'insetLg', 'insetXl', 'inset2xl'] as [ + 'insetNone', + 'insetSm', + 'insetMd', + 'insetLg', + 'insetXl', + 'inset2xl' + ]).forEach(inset => { + test(`verify ${inset} inset breakpoints`, () => { + const { asFragment } = render( + test + ); + expect(asFragment()).toMatchSnapshot(); + }); + }); }); }); diff --git a/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap b/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap index 722609e4fba..1a02560540e 100644 --- a/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap +++ b/packages/react-core/src/components/Pagination/__tests__/__snapshots__/Pagination.test.tsx.snap @@ -1,5 +1,1235 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Pagination API verify inset2xl inset breakpoints 1`] = ` + +
+
+ + 1 - 10 + + of + + 0 + + +
+
+
+ +
+
+ + test +
+
+`; + +exports[`Pagination API verify insetLg inset breakpoints 1`] = ` + +
+
+ + 1 - 10 + + of + + 0 + + +
+
+
+ +
+
+ + test +
+
+`; + +exports[`Pagination API verify insetMd inset breakpoints 1`] = ` + +
+
+ + 1 - 10 + + of + + 0 + + +
+
+
+ +
+
+ + test +
+
+`; + +exports[`Pagination API verify insetNone inset breakpoints 1`] = ` + +
+
+ + 1 - 10 + + of + + 0 + + +
+
+
+ +
+
+ + test +
+
+`; + +exports[`Pagination API verify insetSm inset breakpoints 1`] = ` + +
+
+ + 1 - 10 + + of + + 0 + + +
+
+
+ +
+
+ + test +
+
+`; + +exports[`Pagination API verify insetXl inset breakpoints 1`] = ` + +
+
+ + 1 - 10 + + of + + 0 + + +
+
+
+ +
+
+ + test +
+
+`; + exports[`Pagination component render custom pagination toggle 1`] = `
{ + const [page, setPage] = React.useState(1); + const [perPage, setPerPage] = React.useState(20); + + const onSetPage = (_event: React.MouseEvent | React.KeyboardEvent | MouseEvent, newPage: number) => { + setPage(newPage); + }; + + const onPerPageSelect = ( + _event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + newPerPage: number, + newPage: number + ) => { + setPerPage(newPerPage); + setPage(newPage); + }; + + return ( + + ); +}; diff --git a/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx b/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx index a7936659eca..00f0e894d04 100644 --- a/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx +++ b/packages/react-core/src/components/Pagination/examples/PaginationSticky.tsx @@ -3,8 +3,9 @@ import { Pagination, PaginationVariant, Gallery, GalleryItem, Card, CardBody } f export const PaginationSticky: React.FunctionComponent = () => { const [page, setPage] = React.useState(1); - const [perPage, setPerPage] = React.useState(20); + const [perPage, setPerPage] = React.useState(100); const [isTopSticky, setIsTopSticky] = React.useState(true); + const itemCount = 523; const onToggleSticky = () => { setIsTopSticky(prev => !prev); @@ -23,57 +24,48 @@ export const PaginationSticky: React.FunctionComponent = () => { setPage(newPage); }; - return ( -
- {isTopSticky && ( - - - - - - {Array.apply(0, Array(40)).map((x, i) => ( - - - This is a card - - - ))} - - - )} - {!isTopSticky && ( - - - {Array.apply(0, Array(40)).map((x, i) => ( - - - This is a card - - - ))} - - - - - - )} -
+ const buildCards = () => { + const numberOfCards = (page - 1) * perPage + perPage - 1 >= itemCount ? itemCount - (page - 1) * perPage : perPage; + + return Array.apply(0, Array(numberOfCards)).map((x, i) => ( + + + This is a card + + + )); + }; + + return isTopSticky ? ( + + + + + {buildCards()} + + ) : ( + + {buildCards()} + + + + ); }; diff --git a/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx b/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx index eb15a5a5d38..382652b5a8f 100644 --- a/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx +++ b/packages/react-core/src/components/Panel/__tests__/Panel.test.tsx @@ -1,62 +1,100 @@ -import React from 'react'; -import { render } from '@testing-library/react'; +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; import { Panel } from '../Panel'; import { PanelMain } from '../PanelMain'; import { PanelMainBody } from '../PanelMainBody'; -import { PanelHeader } from '../PanelHeader'; -import { PanelFooter } from '../PanelFooter'; - -describe('Panel', () => { - test('renders content', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); - - test('renders content with raised styling', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); - - test('renders content with bordered styling', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); - - test('renders content with scrollable styling', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); -}); - -describe('PanelMain', () => { - test('renders content', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); - - test('renders content with the set maximum height', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); -}); - -describe('PanelMainBody', () => { - test('renders content', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); -}); - -describe('PanelHeader', () => { - test('renders content', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); -}); - -describe('PanelFooter', () => { - test('renders content', () => { - const { asFragment } = render(Foo); - expect(asFragment()).toMatchSnapshot(); - }); +import userEvent from '@testing-library/user-event'; +import { useEffect } from 'react'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('panel').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with the class pf-c-panel', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel'); +}); + +test('Renders with only the class pf-c-panel by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel', { exact: true }); +}); + +test('Renders with custom class name when className prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('test-class'); +}); + +test('Renders with class name pf-m-raised when variant is raised', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-raised'); +}); + +test('Renders with class name pf-m-bordered when variant is bordered', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-bordered'); +}); + +test('Renders with class name pf-m-scrollable when isScrollable is true', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-scrollable'); +}); + +test('Renders with ref', async () => { + const user = userEvent.setup(); + const panelRef: React.RefObject = React.createRef(); + + const BasicPanel = () => { + const [lastClickWasInPanel, setLastClickWasInPanel] = React.useState(false); + + const handleClick = event => { + if (panelRef.current && panelRef.current.contains(event.target)) { + setLastClickWasInPanel(true); + } else { + setLastClickWasInPanel(false); + } + }; + + useEffect(() => { + document.addEventListener('click', handleClick); + }, []); + + return ( +
+ + + Main content + + +

Last click was in panel: {lastClickWasInPanel ? 'true' : 'false'}

+
+ ); + }; + + render(); + + await user.click(document.body); + expect(screen.getByText('Last click was in panel: false')).toBeVisible; + await user.click(screen.getByText('Main content')); + expect(screen.getByText('Last click was in panel: true')).toBeVisible; +}); + +test('Renders with the inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('this is a simple panel'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Panel/__tests__/PanelFooter.test.tsx b/packages/react-core/src/components/Panel/__tests__/PanelFooter.test.tsx new file mode 100644 index 00000000000..b0c8f96fd7a --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/PanelFooter.test.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { PanelFooter } from '../PanelFooter'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('panelFooter').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with the class pf-c-panel__footer', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__footer'); +}); + +test('Renders with only the class pf-c-panel__footer by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__footer', { exact: true }); +}); + +test('Renders with custom class name when className prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('test-class'); +}); + +test('Renders with the inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('this is a simple panel footer'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Panel/__tests__/PanelHeader.test.tsx b/packages/react-core/src/components/Panel/__tests__/PanelHeader.test.tsx new file mode 100644 index 00000000000..2a395223373 --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/PanelHeader.test.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { PanelHeader } from '../PanelHeader'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('panelHeader').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with the class pf-c-panel__header', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__header'); +}); + +test('Renders with only the class pf-c-panel__header by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__header', { exact: true }); +}); + +test('Renders with custom class name when className prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('test-class'); +}); + +test('Renders with the inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('this is a simple panel header'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Panel/__tests__/PanelMain.test.tsx b/packages/react-core/src/components/Panel/__tests__/PanelMain.test.tsx new file mode 100644 index 00000000000..b2784e61930 --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/PanelMain.test.tsx @@ -0,0 +1,48 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { PanelMain } from '../PanelMain'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('panelMain').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with the class pf-c-panel__main', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__main'); +}); + +test('Renders with only the class pf-c-panel__main by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__main', { exact: true }); +}); + +test('Renders with custom class name when className prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('test-class'); +}); + +test('Renders with custom max height name when maxHeight prop is passed', () => { + render(Test); + const styles = getComputedStyle(screen.getByText('Test')); + expect(styles.getPropertyValue('--pf-c-panel__main--MaxHeight')).toBe('100px'); +}); + +test('Renders with the inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('this is a simple panel main'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Panel/__tests__/PanelMainBody.test.tsx b/packages/react-core/src/components/Panel/__tests__/PanelMainBody.test.tsx new file mode 100644 index 00000000000..2e6760a0763 --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/PanelMainBody.test.tsx @@ -0,0 +1,42 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { PanelMainBody } from '../PanelMainBody'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('panelMainBody').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with the class pf-c-panel__main-body', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__main-body'); +}); + +test('Renders with only the class pf-c-panel__main-body by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-panel__main-body', { exact: true }); +}); + +test('Renders with custom class name when className prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('test-class'); +}); + +test('Renders with the inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('this is a simple panel main body'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Panel/__tests__/__snapshots__/Panel.test.tsx.snap b/packages/react-core/src/components/Panel/__tests__/__snapshots__/Panel.test.tsx.snap index 8e1eae116da..8898a702e5e 100644 --- a/packages/react-core/src/components/Panel/__tests__/__snapshots__/Panel.test.tsx.snap +++ b/packages/react-core/src/components/Panel/__tests__/__snapshots__/Panel.test.tsx.snap @@ -1,92 +1,12 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Panel renders content 1`] = ` +exports[`Matches the snapshot 1`] = `
- Foo + Test
`; -exports[`Panel renders content with bordered styling 1`] = ` - -
- Foo -
-
-`; - -exports[`Panel renders content with raised styling 1`] = ` - -
- Foo -
-
-`; - -exports[`Panel renders content with scrollable styling 1`] = ` - -
- Foo -
-
-`; - -exports[`PanelFooter renders content 1`] = ` - - - -`; - -exports[`PanelHeader renders content 1`] = ` - -
- Foo -
-
-`; - -exports[`PanelMain renders content 1`] = ` - -
- Foo -
-
-`; - -exports[`PanelMain renders content with the set maximum height 1`] = ` - -
- Foo -
-
-`; - -exports[`PanelMainBody renders content 1`] = ` - -
- Foo -
-
-`; diff --git a/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelFooter.test.tsx.snap b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelFooter.test.tsx.snap new file mode 100644 index 00000000000..1d0c965cea9 --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelFooter.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + + + +`; diff --git a/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelHeader.test.tsx.snap b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelHeader.test.tsx.snap new file mode 100644 index 00000000000..ae415425cff --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelHeader.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+ Test +
+
+`; diff --git a/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMain.test.tsx.snap b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMain.test.tsx.snap new file mode 100644 index 00000000000..ece5ab78492 --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMain.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+ Test +
+
+`; diff --git a/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMainBody.test.tsx.snap b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMainBody.test.tsx.snap new file mode 100644 index 00000000000..db02f6c38bd --- /dev/null +++ b/packages/react-core/src/components/Panel/__tests__/__snapshots__/PanelMainBody.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+ Test +
+
+`; diff --git a/packages/react-core/src/components/Progress/Progress.tsx b/packages/react-core/src/components/Progress/Progress.tsx index 6e7e29ca4dd..9d9193d1849 100644 --- a/packages/react-core/src/components/Progress/Progress.tsx +++ b/packages/react-core/src/components/Progress/Progress.tsx @@ -42,6 +42,10 @@ export interface ProgressProps extends Omit, 'si 'aria-label'?: string; /** Associates the ProgressBar with it's label for accessibility purposes. Required when title not used */ 'aria-labelledby'?: string; + /** @beta Content which can be used to convey additional information about the progress component. + * We recommend the helper text component as it was designed for this purpose. + */ + helperText?: React.ReactNode; } export class Progress extends React.Component { @@ -85,6 +89,7 @@ export class Progress extends React.Component { tooltipPosition, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, + helperText, ...props } = this.props; @@ -137,6 +142,7 @@ export class Progress extends React.Component { progressBarAriaProps={progressBarAriaProps} isTitleTruncated={isTitleTruncated} tooltipPosition={tooltipPosition} + helperText={helperText} />
); diff --git a/packages/react-core/src/components/Progress/ProgressContainer.tsx b/packages/react-core/src/components/Progress/ProgressContainer.tsx index 0f819577198..6619af04975 100644 --- a/packages/react-core/src/components/Progress/ProgressContainer.tsx +++ b/packages/react-core/src/components/Progress/ProgressContainer.tsx @@ -6,6 +6,7 @@ import CheckCircleIcon from '@patternfly/react-icons/dist/esm/icons/check-circle import TimesCircleIcon from '@patternfly/react-icons/dist/esm/icons/times-circle-icon'; import ExclamationTriangleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-triangle-icon'; import { AriaProps, ProgressBar } from './ProgressBar'; +import { ProgressHelperText } from './ProgressHelperText'; export enum ProgressMeasureLocation { outside = 'outside', @@ -53,6 +54,10 @@ export interface ProgressContainerProps extends Omit variant = null, measureLocation = ProgressMeasureLocation.top, isTitleTruncated = false, - tooltipPosition + tooltipPosition, + helperText }: ProgressContainerProps) => { const StatusIcon = variantToIcon.hasOwnProperty(variant) && variantToIcon[variant]; const [tooltip, setTooltip] = React.useState(''); @@ -117,6 +123,7 @@ export const ProgressContainer: React.FunctionComponent {measureLocation === ProgressMeasureLocation.inside && `${value}%`} + {helperText && {helperText}} ); }; diff --git a/packages/react-core/src/components/Progress/ProgressHelperText.tsx b/packages/react-core/src/components/Progress/ProgressHelperText.tsx new file mode 100644 index 00000000000..6c2863c2f8c --- /dev/null +++ b/packages/react-core/src/components/Progress/ProgressHelperText.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; +import progressStyle from '@patternfly/react-styles/css/components/Progress/progress'; + +export interface ProgressHelperTextProps extends React.HTMLProps { + /** Content which can be used to convey additional information about the progress component. + * We recommend the helper text component as it was designed for this purpose. + */ + children?: React.ReactNode; +} + +export const ProgressHelperText: React.FunctionComponent = ({ + children, + ...props +}: ProgressHelperTextProps) => ( +
+ {children} +
+); + +ProgressHelperText.displayName = 'ProgressHelperText'; diff --git a/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx b/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx index 74720cd918b..1d666155b1a 100644 --- a/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx +++ b/packages/react-core/src/components/Progress/__tests__/Progress.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { Progress, ProgressSize } from '../Progress'; import { ProgressVariant, ProgressMeasureLocation } from '../ProgressContainer'; @@ -97,3 +97,15 @@ test('progress component generates console warning when no accessible name is pr render(); expect(consoleWarnMock).toHaveBeenCalled(); }); + +test('Does not render helper text by default', () => { + render(); + + expect(screen.queryByText('Test helper text')).not.toBeInTheDocument(); +}) + +test('Renders passed helper text', () => { + render(); + + expect(screen.getByText('Test helper text')).toBeVisible(); +}); diff --git a/packages/react-core/src/components/Progress/__tests__/ProgressHelperText.test.tsx b/packages/react-core/src/components/Progress/__tests__/ProgressHelperText.test.tsx new file mode 100644 index 00000000000..24fad231a30 --- /dev/null +++ b/packages/react-core/src/components/Progress/__tests__/ProgressHelperText.test.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import { ProgressHelperText } from '../ProgressHelperText'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('container').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with class pf-c-progress__helper-text on the div containing the helper text component', () => { + render(Test); + + expect(screen.getByText('Test')).toHaveClass('pf-c-progress__helper-text'); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Progress/__tests__/__snapshots__/ProgressHelperText.test.tsx.snap b/packages/react-core/src/components/Progress/__tests__/__snapshots__/ProgressHelperText.test.tsx.snap new file mode 100644 index 00000000000..f8e8eac47e8 --- /dev/null +++ b/packages/react-core/src/components/Progress/__tests__/__snapshots__/ProgressHelperText.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+ test +
+
+`; diff --git a/packages/react-core/src/components/Progress/examples/Progress.md b/packages/react-core/src/components/Progress/examples/Progress.md index 34ecd6c5bdd..a099e3e8698 100644 --- a/packages/react-core/src/components/Progress/examples/Progress.md +++ b/packages/react-core/src/components/Progress/examples/Progress.md @@ -74,3 +74,7 @@ propComponents: ['Progress'] ### Title outside of progress bar ```ts file="./ProgressTitleOutsideOfProgressBar.tsx" ``` + +### Helper text +```ts file="./ProgressHelperText.tsx" isBeta +``` diff --git a/packages/react-core/src/components/Progress/examples/ProgressHelperText.tsx b/packages/react-core/src/components/Progress/examples/ProgressHelperText.tsx new file mode 100644 index 00000000000..4f3fa425937 --- /dev/null +++ b/packages/react-core/src/components/Progress/examples/ProgressHelperText.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { Progress, ProgressProps, HelperText, HelperTextItem, Radio } from '@patternfly/react-core'; + +export const ProgressHelperText: React.FunctionComponent = () => { + type ProgressVariant = ProgressProps['variant']; + + const [selectedVariant, setSelectedVariant] = React.useState(undefined); + + const progressVariants: ProgressVariant[] = [undefined, 'success', 'warning', 'danger']; + + const capitalize = (input: string) => input[0].toUpperCase() + input.substring(1); + const formatVariantName = (variant: ProgressVariant) => (variant ? capitalize(variant) : 'Default'); + + const variantOptions = progressVariants.map(variant => ( + setSelectedVariant(variant)} + key={formatVariantName(variant)} + name="Progress variant options" + /> + )); + + const helperTextVariant = selectedVariant === 'danger' ? 'error' : selectedVariant; + + const helperText = ( + + + {`${formatVariantName(selectedVariant)} variant is being displayed`} + + + ); + + return ( + <> + {variantOptions} +
+ + + ); +}; diff --git a/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx b/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx index eeb8195f708..82055650c84 100644 --- a/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx +++ b/packages/react-core/src/components/SearchInput/AdvancedSearchMenu.tsx @@ -133,21 +133,24 @@ export const AdvancedSearchMenu: React.FunctionComponent) => { const newMap = getAttrValueMap(); + newMap[attribute] = newValue; let updatedValue = ''; Object.entries(newMap).forEach(([k, v]) => { if (v.trim() !== '') { + /* Wrap the value in quotes if it contains spaces */ + const quoteWrappedValue = v.includes(' ') ? `'${v.replace(/(^'|'$)/g, '')}'` : v; + if (k !== 'haswords') { - updatedValue = `${updatedValue} ${k}${advancedSearchDelimiter}${v}`; + updatedValue = `${updatedValue} ${k}${advancedSearchDelimiter}${quoteWrappedValue}`; } else { - updatedValue = `${updatedValue} ${v}`; + updatedValue = `${updatedValue} ${quoteWrappedValue}`; } } }); - updatedValue = updatedValue.replace(/^\s+/g, ''); if (onChange) { - onChange(updatedValue, event); + onChange(updatedValue.replace(/^\s+/g, ''), event); } }; diff --git a/packages/react-core/src/components/SearchInput/SearchInput.tsx b/packages/react-core/src/components/SearchInput/SearchInput.tsx index 20c99dcb383..82c3701dc33 100644 --- a/packages/react-core/src/components/SearchInput/SearchInput.tsx +++ b/packages/react-core/src/components/SearchInput/SearchInput.tsx @@ -117,6 +117,8 @@ export interface SearchInputProps extends Omit, placeholder?: string; /** Accessible label for the button to navigate to previous result. */ previousNavigationButtonAriaLabel?: string; + /** z-index of the advanced search form when appendTo is not inline. */ + zIndex?: number; /** Label for the button which resets the advanced search form and clears the search input. */ resetButtonLabel?: string; /** The number of search results returned. Either a total number of results, @@ -157,6 +159,7 @@ const SearchInputBase: React.FunctionComponent = ({ submitSearchButtonLabel = 'Search', isDisabled = false, appendTo, + zIndex = 9999, type = 'text', ...props }: SearchInputProps) => { @@ -223,13 +226,36 @@ const SearchInputBase: React.FunctionComponent = ({ setIsSearchMenuOpen(false); }; + const splitStringExceptInQuotes = (str: string) => { + let quoteType: string; + + return str.match(/\\?.|^$/g).reduce( + (p: any, c: string) => { + if (c === "'" || c === '"') { + if (!quoteType) { + quoteType = c; + } + if (c === quoteType) { + p.quote = !p.quote; + } + } else if (!p.quote && c === ' ') { + p.a.push(''); + } else { + p.a[p.a.length - 1] += c.replace(/\\(.)/, '$1'); + } + return p; + }, + { a: [''] } + ).a; + }; + const getAttrValueMap = () => { const attrValue: { [key: string]: string } = {}; - const pairs = searchValue.split(' '); - pairs.map(pair => { + const pairs = splitStringExceptInQuotes(searchValue); + pairs.map((pair: string) => { const splitPair = pair.split(advancedSearchDelimiter); if (splitPair.length === 2) { - attrValue[splitPair[0]] = splitPair[1]; + attrValue[splitPair[0]] = splitPair[1].replace(/(^'|'$)/g, ''); } else if (splitPair.length === 1) { attrValue.haswords = attrValue.hasOwnProperty('haswords') ? `${attrValue.haswords} ${splitPair[0]}` @@ -412,6 +438,7 @@ const SearchInputBase: React.FunctionComponent = ({ isVisible={isSearchMenuOpen} enableFlip={true} appendTo={() => appendTo || searchInputRef.current} + zIndex={zIndex} />
); diff --git a/packages/react-core/src/components/SearchInput/examples/SearchInput.md b/packages/react-core/src/components/SearchInput/examples/SearchInput.md index 8dd819e7c74..665ca92271f 100644 --- a/packages/react-core/src/components/SearchInput/examples/SearchInput.md +++ b/packages/react-core/src/components/SearchInput/examples/SearchInput.md @@ -48,5 +48,9 @@ the following example. The search input component can also be used as a composab or other elements to build a completely custom advanced search form. This feature is demonstrated in the search input's react demos. +The values used in the attribute-value form fields may contain spaces. The values containing spaces +should be wrapped with quotes inside the summary search string in the input field. If the latter is +autogenerated from the individual fields the quotes will be autoplaced. + ```ts file='./SearchInputAdvanced.tsx' ``` diff --git a/packages/react-core/src/components/Select/Select.tsx b/packages/react-core/src/components/Select/Select.tsx index ca2ce1def12..1ce9a272b73 100644 --- a/packages/react-core/src/components/Select/Select.tsx +++ b/packages/react-core/src/components/Select/Select.tsx @@ -183,6 +183,8 @@ export interface SelectProps * appended inline, e.g. `menuAppendTo="parent"` */ isFlipEnabled?: boolean; + /** z-index of the select menu when menuAppendTo is not inline. */ + zIndex?: number; /** Value to overwrite the randomly generated data-ouia-component-id.*/ ouiaId?: number | string; /** Set the value of data-ouia-safe. Only set to true when the component is in a static state, i.e. no animations are occurring. At all other times, this value must be false. */ @@ -263,7 +265,8 @@ export class Select extends React.Component )} diff --git a/packages/react-core/src/components/Sidebar/SidebarPanel.tsx b/packages/react-core/src/components/Sidebar/SidebarPanel.tsx index 240066c17fe..b63feae3502 100644 --- a/packages/react-core/src/components/Sidebar/SidebarPanel.tsx +++ b/packages/react-core/src/components/Sidebar/SidebarPanel.tsx @@ -3,6 +3,16 @@ import { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/Sidebar/sidebar'; import { formatBreakpointMods } from '../../helpers/util'; +export enum SidebarPanelWidthType { + default = 'default', + width25 = 'width_25', + width33 = 'width_33', + width50 = 'width_50', + width66 = 'width_66', + width75 = 'width_75', + width100 = 'width_100' +} + export interface SidebarPanelProps extends Omit, 'width'> { children: React.ReactNode; /** Indicates whether the panel is positioned statically or sticky to the top. Default is sticky on small screens when the orientation is stack, and static on medium and above screens when the orientation is split. */ diff --git a/packages/react-core/src/components/Sidebar/__tests__/Sidebar.test.tsx b/packages/react-core/src/components/Sidebar/__tests__/Sidebar.test.tsx new file mode 100644 index 00000000000..82ac79fd0a1 --- /dev/null +++ b/packages/react-core/src/components/Sidebar/__tests__/Sidebar.test.tsx @@ -0,0 +1,72 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { Sidebar } from '../Sidebar'; + +test('Renders without children', () => { + render( +
+ +
+ ); + expect(screen.getByTestId('sidebar').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with only class name pf-c-sidebar by default', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-c-sidebar', { exact: true }); +}); + +test('Renders with class name pf-c-sidebar', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-c-sidebar'); +}); + +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('custom-class'); +}); + +test('Renders with class name pf-m-no-background when hasNoBackground prop is passed', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-m-no-background'); +}); + +test('Renders with class name pf-m-stack when "stack" is passed to orientation prop', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-m-stack'); +}); + +test('Renders with class name pf-m-split when "split" is passed to orientation prop', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-m-split'); +}); + +test('Renders with class name pf-m-panel-right when isPanelRight prop is passed', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-m-panel-right'); +}); + +test('Renders with class name pf-m-gutter when hasGutter prop is passed', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveClass('pf-m-gutter'); +}); + +test('Renders with class name pf-m-sidebar__main by default for child component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-sidebar__main'); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test').parentElement).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Sidebar/__tests__/SidebarContent.test.tsx b/packages/react-core/src/components/Sidebar/__tests__/SidebarContent.test.tsx new file mode 100644 index 00000000000..8b30c2359ee --- /dev/null +++ b/packages/react-core/src/components/Sidebar/__tests__/SidebarContent.test.tsx @@ -0,0 +1,38 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { SidebarContent } from '../SidebarContent'; + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with only class name pf-c-sidebar__content by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-sidebar__content', { exact: true }); +}); + +test('Renders with class name pf-c-sidebar__content', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-sidebar__content'); +}); + +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); +}); + +test('Renders with class name pf-m-no-background when hasNoBackground prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-no-background'); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Sidebar/__tests__/SidebarPanel.test.tsx b/packages/react-core/src/components/Sidebar/__tests__/SidebarPanel.test.tsx new file mode 100644 index 00000000000..83e100c4dac --- /dev/null +++ b/packages/react-core/src/components/Sidebar/__tests__/SidebarPanel.test.tsx @@ -0,0 +1,75 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { SidebarPanel, SidebarPanelWidthType } from '../SidebarPanel'; + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders with with only class name pf-c-sidebar__panel by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-sidebar__panel', { exact: true }); +}); + +test('Renders with with class name pf-c-sidebar__panel', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-c-sidebar__panel'); +}); + +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); +}); + +test('Renders with class name pf-m-sticky when "sticky" is passed to variant prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-sticky'); +}); + +test('Renders with class name pf-m-static when "static" is passed to variant prop', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-static'); +}); + +test('Renders with class name pf-m-no-background when hasNoBackground prop is passed', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('pf-m-no-background'); +}); + +['width_25', 'width_33', 'width_50', 'width_66', 'width_75', 'width_100'].forEach(widthType => { + test(`Renders with appropriate class names when ${widthType} is passed to each breakpoint of width prop`, () => { + render( + + Test + + ); + + const className = widthType.replace('_', '-'); + expect(screen.getByText('Test')).toHaveClass(`pf-m-${className}`); + expect(screen.getByText('Test')).toHaveClass(`pf-m-${className}-on-sm`); + expect(screen.getByText('Test')).toHaveClass(`pf-m-${className}-on-md`); + expect(screen.getByText('Test')).toHaveClass(`pf-m-${className}-on-lg`); + expect(screen.getByText('Test')).toHaveClass(`pf-m-${className}-on-xl`); + expect(screen.getByText('Test')).toHaveClass(`pf-m-${className}-on-2xl`); + }); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/Sidebar.test.tsx.snap b/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/Sidebar.test.tsx.snap new file mode 100644 index 00000000000..0f37c4cc20a --- /dev/null +++ b/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/Sidebar.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+
+ Test +
+
+
+`; diff --git a/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarContent.test.tsx.snap b/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarContent.test.tsx.snap new file mode 100644 index 00000000000..278f53acace --- /dev/null +++ b/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarContent.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+ Test +
+
+`; diff --git a/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarPanel.test.tsx.snap b/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarPanel.test.tsx.snap new file mode 100644 index 00000000000..81236e06b34 --- /dev/null +++ b/packages/react-core/src/components/Sidebar/__tests__/__snapshots__/SidebarPanel.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
+ Test +
+
+`; diff --git a/packages/react-core/src/components/Spinner/Spinner.tsx b/packages/react-core/src/components/Spinner/Spinner.tsx index 61932f3c393..ba0ae7ae5da 100644 --- a/packages/react-core/src/components/Spinner/Spinner.tsx +++ b/packages/react-core/src/components/Spinner/Spinner.tsx @@ -20,6 +20,8 @@ export interface SpinnerProps extends Omit, 'si isSVG?: boolean; /** Diameter of spinner set as CSS variable */ diameter?: string; + /** @beta Indicates the spinner is inline and the size should inherit the text font size. This will override the size prop. */ + isInline?: boolean; /** Accessible label to describe what is loading */ 'aria-label'?: string; /** Id of element which describes what is being loaded */ @@ -33,6 +35,7 @@ export const Spinner: React.FunctionComponent = ({ 'aria-valuetext': ariaValueText = 'Loading...', isSVG = true, diameter, + isInline = false, 'aria-label': ariaLabel, 'aria-labelledBy': ariaLabelledBy, ...props @@ -41,7 +44,7 @@ export const Spinner: React.FunctionComponent = ({ return ( ( + + + + Heading + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit Sed hendrerit nisi in cursus maximus. + + + Second level + + + + Curabitur accumsan turpis pharetra blandit. Quisque condimentum maximus mi,{' '} + sit amet commodo arcu rutrum id. Proin pretium + urna vel cursus venenatis. Suspendisse potenti. + + + Sometimes you need small text + + + + +); diff --git a/packages/react-core/src/components/Tabs/OverflowTab.tsx b/packages/react-core/src/components/Tabs/OverflowTab.tsx index 0d715ff4feb..0edf1387133 100644 --- a/packages/react-core/src/components/Tabs/OverflowTab.tsx +++ b/packages/react-core/src/components/Tabs/OverflowTab.tsx @@ -19,6 +19,8 @@ export interface OverflowTabProps extends React.HTMLProps { defaultTitleText?: string; /** The aria label applied to the button which toggles the tab overflow menu */ toggleAriaLabel?: string; + /** z-index of the overflow tab */ + zIndex?: number; } export const OverflowTab: React.FunctionComponent = ({ @@ -27,6 +29,7 @@ export const OverflowTab: React.FunctionComponent = ({ showTabCount, defaultTitleText = 'More', toggleAriaLabel, + zIndex = 9999, ...props }: OverflowTabProps) => { const menuRef = React.useRef(); @@ -138,6 +141,7 @@ export const OverflowTab: React.FunctionComponent = ({ isVisible={isExpanded} popperMatchesTriggerWidth={false} appendTo={overflowLIRef.current} + zIndex={zIndex} /> ); diff --git a/packages/react-core/src/components/Tabs/Tab.tsx b/packages/react-core/src/components/Tabs/Tab.tsx index 12acef004ca..5867704a163 100644 --- a/packages/react-core/src/components/Tabs/Tab.tsx +++ b/packages/react-core/src/components/Tabs/Tab.tsx @@ -5,10 +5,12 @@ import { TabButton } from './TabButton'; import { TabsContext } from './TabsContext'; import { css } from '@patternfly/react-styles'; import { Tooltip } from '../Tooltip'; -import { Button } from '../Button'; import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; +import { TabAction } from './TabAction'; -export interface TabProps extends Omit, 'title'>, OUIAProps { +export interface TabProps + extends Omit, 'title' | 'action'>, + OUIAProps { /** content rendered inside the Tab content area. */ children?: React.ReactNode; /** additional classes added to the Tab */ @@ -39,6 +41,8 @@ export interface TabProps extends Omit = ({ tooltip, closeButtonAriaLabel, isCloseDisabled = false, + actions, ...props }: TabProps) => { const preventedEvents = inoperableEvents.reduce( @@ -117,26 +122,22 @@ const TabBase: React.FunctionComponent = ({ className={css( styles.tabsItem, eventKey === localActiveKey && styles.modifiers.current, - handleTabClose && styles.modifiers.action, - handleTabClose && (isDisabled || isAriaDisabled) && styles.modifiers.disabled, + (handleTabClose || actions) && styles.modifiers.action, + (isDisabled || isAriaDisabled) && styles.modifiers.disabled, childClassName )} role="presentation" > {tooltip ? {tabButton} : tabButton} + {actions && actions} {handleTabClose !== undefined && ( - - - + handleTabClose(event, eventKey, tabContentRef)} + isDisabled={isCloseDisabled} + > + + )} ); diff --git a/packages/react-core/src/components/Tabs/TabAction.tsx b/packages/react-core/src/components/Tabs/TabAction.tsx new file mode 100644 index 00000000000..04bc4e597ee --- /dev/null +++ b/packages/react-core/src/components/Tabs/TabAction.tsx @@ -0,0 +1,57 @@ +import * as React from 'react'; +import { css } from '@patternfly/react-styles'; +import styles from '@patternfly/react-styles/css/components/Tabs/tabs'; +import { Button } from '../Button'; +import { getOUIAProps, OUIAProps } from '../../helpers'; + +export interface TabActionProps extends Omit, 'ref' | 'type' | 'size'>, OUIAProps { + /** Content rendered in the tab action */ + children?: React.ReactNode; + /** Additional classes added to the tab action span */ + className?: string; + /** Click callback for tab action button */ + onClick?: (event: React.MouseEvent) => void; + /** Flag indicating if the tab action is a help action */ + isHelpAction?: boolean; + /** Flag indicating if the tab action is disabled */ + isDisabled?: boolean; + /** Accessible label for the tab action */ + 'aria-label'?: string; + /** @hide Callback for the section ref */ + innerRef?: React.Ref; +} + +const TabActionBase: React.FunctionComponent = ({ + children, + className, + onClick, + isHelpAction, + isDisabled, + 'aria-label': ariaLabel = 'Tab action', + innerRef, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ouiaId, + ouiaSafe, + ...props +}: TabActionProps) => ( + + + +); + +export const TabAction = React.forwardRef((props: TabActionProps, ref: React.Ref) => ( + +)); + +TabAction.displayName = 'TabAction'; diff --git a/packages/react-core/src/components/Tabs/Tabs.tsx b/packages/react-core/src/components/Tabs/Tabs.tsx index caf128c6b3e..00a175dbc28 100644 --- a/packages/react-core/src/components/Tabs/Tabs.tsx +++ b/packages/react-core/src/components/Tabs/Tabs.tsx @@ -45,7 +45,7 @@ export interface TabsProps extends Omit, eventKey: number | string) => void; - /** @beta Callback to handle tab closing */ + /** @beta Callback to handle tab closing and adds a basic close button to all tabs. This is overridden by the tab actions property. */ onClose?: (event: React.MouseEvent, eventKey: number | string) => void; /** @beta Callback for the add button. Passing this property inserts the add button */ onAdd?: () => void; diff --git a/packages/react-core/src/components/Tabs/__tests__/Tab.test.tsx b/packages/react-core/src/components/Tabs/__tests__/Tab.test.tsx index 2f3d9c79452..677811072be 100644 --- a/packages/react-core/src/components/Tabs/__tests__/Tab.test.tsx +++ b/packages/react-core/src/components/Tabs/__tests__/Tab.test.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { render } from '@testing-library/react'; import { Tab } from '../Tab'; +import { TabAction } from '../TabAction'; import { TabTitleText } from '../TabTitleText'; test('should not render anything', () => { @@ -11,3 +12,12 @@ test('should not render anything', () => { ); expect(asFragment()).toMatchSnapshot(); }); + +test('renders tab action', () => { + const { asFragment } = render( + "Tab item 2"} actions={test}> + Tab 2 section + + ); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Tabs/__tests__/__snapshots__/Tab.test.tsx.snap b/packages/react-core/src/components/Tabs/__tests__/__snapshots__/Tab.test.tsx.snap index 32cd9db47f4..74166f26005 100644 --- a/packages/react-core/src/components/Tabs/__tests__/__snapshots__/Tab.test.tsx.snap +++ b/packages/react-core/src/components/Tabs/__tests__/__snapshots__/Tab.test.tsx.snap @@ -1,5 +1,50 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`renders tab action 1`] = ` + + + +`; + exports[`should not render anything 1`] = `
  • { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - const tooltip = ( - - ); - - return ( -
    - - Users} aria-label="Default content - users"> - Users - - Containers}> - Containers - - Database}> - Database - - Disabled} isDisabled> - Disabled - - ARIA Disabled} isAriaDisabled> - ARIA Disabled - - ARIA Disabled (Tooltip)} - isAriaDisabled - > - ARIA Disabled (Tooltip) - - -
    - -
    -
    - ); - } -} +```ts file="./TabsDefault.tsx" ``` ### With tooltip react ref @@ -109,305 +34,22 @@ When using a React ref to link a Tooltip to a Tab component via the `reference` The tooltip should also have the `id` prop passed in. The value given to this prop should then be passed into the tab's `aria-describedby` prop. This ensures a tooltip used with a React ref will be announced by the JAWS and NVDA screen readers. -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; - -class SimpleTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - const tooltipRef = React.createRef(); - - return ( -
    - - Users} aria-label="Tooltip ref content - users"> - Users - - Containers}> - Containers - - Database}> - Database - - Disabled} isDisabled> - Disabled - - ARIA Disabled} isAriaDisabled> - ARIA Disabled - - ARIA Disabled (Tooltip)} - isAriaDisabled - ref={tooltipRef} - aria-describedby="tooltip-ref1" - > - ARIA Disabled (Tooltip) - - - -
    - -
    -
    - ); - } -} +```ts file="./TabsTooltipReactRef.tsx" ``` ### Uncontrolled -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; - -class UncontrolledSimpleTabs extends React.Component { - render() { - const tooltip = ( - - ); - - return ( - <> - - Users} aria-label="Uncontrolled ref content - users"> - Users - - Containers}> - Containers - - Database}> - Database - - Disabled} isDisabled> - Disabled - - ARIA Disabled} isAriaDisabled> - ARIA Disabled - - ARIA Disabled (Tooltip)} - isAriaDisabled - tooltip={tooltip} - > - ARIA Disabled (Tooltip) - - - - ); - } -} +```ts file="./TabsUncontrolled.tsx" ``` ### Box light variation -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; - -class SimpleTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isTabsLightScheme: true - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleScheme = checked => { - this.setState({ - isTabsLightScheme: checked - }); - }; - } - - render() { - const { activeTabKey, isBox, isTabsLightScheme } = this.state; - const tooltip = ( - - ); - - return ( -
    - - Users} aria-label="Box light variation content - users"> - Users - - Containers}> - Containers - - Database}> - Database - - Disabled} isDisabled> - Disabled - - ARIA Disabled} isAriaDisabled> - ARIA Disabled - - ARIA Disabled (Tooltip)} - isAriaDisabled - tooltip={tooltip} - > - ARIA Disabled (Tooltip) - - -
    - -
    -
    - ); - } -} +```ts file="./TabsBoxLight.tsx" ``` ### Default overflow -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; - -class ScrollButtonsPrimaryTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - return ( -
    - - Users} aria-label="Default overflow content users"> - Users - - Containers}> - Containers - - Database}> - Database - - Server}> - Server - - System}> - System - - Network}> - Network - - Tab item 7}> - Tab 7 section - - Tab item 8}> - Tab 8 section - - Tab item 9}> - Tab 9 section - - Tab item 10}> - Tab 10 section - - Tab item 11}> - Tab 11 section - - -
    - -
    -
    - ); - } -} +```ts file="./TabsDefaultOverflow.tsx" ``` ### Horizontal overflow @@ -417,1226 +59,82 @@ class ScrollButtonsPrimaryTabs extends React.Component { ### Vertical -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; - -class VerticalTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - const tooltip = ( - - ); - - return ( -
    - - Users} aria-label="Vertical example content users"> - Users - - Containers}> - Containers - - Database}> - Database - - Disabled} isDisabled> - Disabled - - ARIA Disabled} isAriaDisabled> - ARIA Disabled - - ARIA Disabled (Tooltip)} - isAriaDisabled - tooltip={tooltip} - > - ARIA Disabled (Tooltip) - - -
    - -
    -
    - ); - } -} +```ts file="./TabsVertical.tsx" ``` ### Vertical expandable -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; -class VerticalExpandableTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isExpanded: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - this.onToggle = isExpanded => { - this.setState({ - isExpanded - }); - }; - } - render() { - const { activeTabKey, isExpanded } = this.state; - return ( - - Users} aria-label="Vertical expandable content users"> - Users - - Containers}> - Containers - - Database}> - Database - - Server}> - Server - - System}> - System - - Network}> - Network - - - ); - } -} +```ts file="./TabsVerticalExpandable.tsx" ``` ### Vertical expandable uncontrolled -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; -class VerticalExpandableUncontrolledTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0 - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - render() { - const { activeTabKey } = this.state; - return ( - - Users} aria-label="Vertical expandable uncontrolled content users"> - Users - - Containers}> - Containers - - Database}> - Database - - Server}> - Server - - System}> - System - - Network}> - Network - - - ); - } -} +```ts file="./TabsVerticalExpandableUncontrolled.tsx" ``` ### Inset -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; - -class InsetTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - return ( -
    - - Users} aria-label="Inset example content users"> - Users - - Containers}> - Containers - - Database}> - Database - - Server}> - Server - - System}> - System - - Network}> - Network - - -
    - -
    -
    - ); - } -} +```ts file="./TabsInset.tsx" ``` ### Page Insets -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; - -class PageInsetsTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - return ( -
    - - Users} aria-label="Page insets example content users"> - Users - - Containers}> - Containers - - Database}> - Database - - Server}> - Server - - System}> - System - - Network}> - Network - - -
    - -
    -
    - ); - } -} +```ts file="./TabsPageInsets.tsx" ``` ### Icons and text -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, TabTitleIcon } from '@patternfly/react-core'; -import UsersIcon from '@patternfly/react-icons/dist/esm/icons/users-icon'; -import BoxIcon from '@patternfly/react-icons/dist/esm/icons/box-icon'; -import DatabaseIcon from '@patternfly/react-icons/dist/esm/icons/database-icon'; -import ServerIcon from '@patternfly/react-icons/dist/esm/icons/server-icon'; -import LaptopIcon from '@patternfly/react-icons/dist/esm/icons/laptop-icon'; -import ProjectDiagramIcon from '@patternfly/react-icons/dist/esm/icons/project-diagram-icon'; - -class IconAndTextTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0 - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - - render() { - return ( - - - - - {' '} - Users{' '} - - } - aria-label="icons and text content" - > - Users - - - - - {' '} - Containers{' '} - - } - > - Containers - - - - - {' '} - Database{' '} - - } - > - Database - - - - - {' '} - Server{' '} - - } - > - Server - - - - - {' '} - System{' '} - - } - > - System - - - - - {' '} - Network{' '} - - } - > - Network - - - ); - } -} +```ts file="./TabsIconAndText.tsx" ``` ### Tabs with sub tabs -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; - -class SecondaryTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey1: 0, - activeTabKey2: 10, - isBox: false - }; - // Toggle currently active tab - this.handleTabClickFirst = (event, tabIndex) => { - this.setState({ - activeTabKey1: tabIndex - }); - }; - // Toggle currently active secondary tab - this.handleTabClickSecond = (event, tabIndex) => { - this.setState({ - activeTabKey2: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey1, activeTabKey2, isBox } = this.state; - return ( -
    - - Users} aria-label="Tabs with subtabs content users"> - - Secondary tab item 1}> - Secondary tab item 1 item section - - Secondary tab item 2}> - Secondary tab item 2 section - - Secondary tab item 3}> - Secondary tab item 3 section - - Secondary tab item 4}> - Secondary tab item 4 section - - Secondary tab item 5}> - Secondary tab item 5 section - - Secondary tab item 6}> - Secondary tab item 6 section - - Secondary tab item 7}> - Secondary tab item 7 section - - Secondary tab item 8}> - Secondary tab item 8 section - - - - Containers}> - Containers - - Database}> - Database - - Server}> - Server - - System}> - System - - Network}> - Network - - Tab item 7}> - Tab 7 section - - Tab item 8}> - Tab 8 section - - Tab item 9}> - Tab 9 section - - Tab item 10}> - Tab 10 section - - Tab item 11}> - Tab 11 section - - -
    - -
    -
    - ); - } -} +```ts file="./TabsSubtabs.tsx" ``` ### Filled -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; - -class FilledTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - return ( -
    - - Users} aria-label="Tabs filled example content users"> - Users - - Containers}> - Containers - - Database}> - Database - - -
    - -
    -
    - ); - } -} +```ts file="TabsFilled.tsx" ``` ### Filled with icons -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, TabTitleIcon, Checkbox } from '@patternfly/react-core'; -import UsersIcon from '@patternfly/react-icons/dist/esm/icons/users-icon'; -import BoxIcon from '@patternfly/react-icons/dist/esm/icons/box-icon'; -import DatabaseIcon from '@patternfly/react-icons/dist/esm/icons/database-icon'; - -class FilledTabsWithIcons extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0, - isBox: false - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - - this.toggleBox = checked => { - this.setState({ - isBox: checked - }); - }; - } - - render() { - const { activeTabKey, isBox } = this.state; - return ( -
    - - - - - {' '} - Users{' '} - - } - aria-label="filled tabs with icons content users" - > - Users - - - - - {' '} - Containers{' '} - - } - > - Containers - - - - - {' '} - Database{' '} - - } - > - Database - - -
    - -
    -
    - ); - } -} +```ts file="./TabsFilledWithIcons.tsx" ``` ### Using the nav element -```js -import React from 'react'; -import { Tabs, Tab, TabsComponent, TabTitleText } from '@patternfly/react-core'; - -class TabsNav extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0 - }; - - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - - render() { - return ( - - Users} href="#users" aria-label="Nav element content users"> - Users - - Containers} href="#containers"> - Containers - - Database} href="#database"> - Database - - Disabled} isDisabled href="#disabled"> - Disabled - - ARIA Disabled} isAriaDisabled href="#aria-disabled"> - ARIA Disabled - - Network} href="#network"> - Network - - - ); - } -} +```ts file="./TabsNav.tsx" ``` ### Sub nav using the nav element -```js -import React from 'react'; -import { Tabs, Tab, TabsComponent, TabTitleText } from '@patternfly/react-core'; - -class SecondaryTabsNav extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey1: 0, - activeTabKey2: 10 - }; - - // Toggle currently active tab - this.handleTabClickFirst = (event, tabIndex) => { - this.setState({ - activeTabKey1: tabIndex - }); - }; - - // Toggle currently active secondary tab - this.handleTabClickSecond = (event, tabIndex) => { - this.setState({ - activeTabKey2: tabIndex - }); - }; - } - - render() { - return ( - - Users} href="#" aria-label="Subtabs with nav content users"> - - Item 1} href="#"> - Item 1 item section - - Item 2} href="#"> - Item 2 section - - Item 3} href="#"> - Item 3 section - - Disabled} isDisabled href="#"> - Disabled - - ARIA Disabled} isAriaDisabled href="#"> - ARIA Disabled - - Item 6} href="#"> - Item 6 section - - - - Containers} href="#"> - Containers - - Database} href="#"> - Database - - Disabled} isDisabled href="#"> - Disabled - - ARIA Disabled} isAriaDisabled href="#"> - ARIA Disabled - - Network} href="#"> - Network - - - ); - } -} +```ts file="./TabsNavSecondary.tsx" ``` ### Separate content -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, TabContent } from '@patternfly/react-core'; - -class SeparateTabContent extends React.Component { - constructor(props) { - super(props); - this.state = { - activeKey: 0 - }; - - this.contentRef1 = React.createRef(); - this.contentRef2 = React.createRef(); - this.contentRef3 = React.createRef(); - - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - - render() { - return ( - - - Tab item 1} - tabContentId="refTab1Section" - tabContentRef={this.contentRef1} - /> - Tab item 2} - tabContentId="refTab2Section" - tabContentRef={this.contentRef2} - /> - Tab item 3} - tabContentId="refTab3Section" - tabContentRef={this.contentRef3} - /> - -
    - - Tab 1 section - - - -
    -
    - ); - } -} +```ts file="./TabsSeparateContent.tsx" ``` ### Tab content with body and padding -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText, TabContent, TabContentBody } from '@patternfly/react-core'; - -const TabContentWithBody = () => { - const [activeTabKey, setActiveTabKey] = React.useState(0); - - // Toggle currently active tab - const handleTabClick = (event, tabIndex) => { - setActiveTabKey(tabIndex); - }; - - const contentRef1 = React.createRef(); - const contentRef2 = React.createRef(); - const contentRef3 = React.createRef(); - - return ( - - - Tab item 1} - tabContentId="tab1SectionBodyPadding" - tabContentRef={contentRef1} - /> - Tab item 2} - tabContentId="tab2SectionBodyPadding" - tabContentRef={contentRef2} - /> - Tab item 3} - tabContentId="tab3SectionBodyPadding" - tabContentRef={contentRef3} - /> - -
    - - Tab 1 section with body and padding - - - -
    -
    - ); -}; +```ts file="./TabsContentWithBodyPadding.tsx" ``` ### Children mounting on click -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText } from '@patternfly/react-core'; - -class MountingSimpleTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0 - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - - render() { - return ( - - Tab item 1} aria-label="Tab 1"> - Tab 1 section - - Tab item 2} aria-label="Tab 2"> - Tab 2 section - - Tab item 3} aria-label="Tab 3"> - Tab 3 section - - - ); - } -} +```ts file="./TabsChildrenMounting.tsx" ``` ### Unmounting invisible children -```js -import React from 'react'; -import { Tabs, Tab, TabTitleText } from '@patternfly/react-core'; - -class UnmountingSimpleTabs extends React.Component { - constructor(props) { - super(props); - this.state = { - activeTabKey: 0 - }; - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - - render() { - return ( - - Tab item 1} aria-label="Invisible children tab 1"> - Tab 1 section - - Tab item 2} aria-label="Invisible children tab 2"> - Tab 2 section - - Tab item 3} aria-label="Invisible children tab 3"> - Tab 3 section - - - ); - } -} +```ts file="./TabsUnmountingInvisibleChildren.tsx" ``` ### Toggled separate content -```js -import React from 'react'; -import { Tabs, Tab, TabContent, Button, Divider } from '@patternfly/react-core'; - -class ToggledSeparateContent extends React.Component { - constructor(props) { - super(props); - this.state = { - activeKey: 0, - isTab2Hidden: false - }; - - this.contentRef1 = React.createRef(); - this.contentRef2 = React.createRef(); - this.contentRef3 = React.createRef(); - - // Toggle currently active tab - this.handleTabClick = (event, tabIndex) => { - this.setState({ - activeTabKey: tabIndex - }); - }; - } - - render() { - const { activeKey, isTab2Hidden } = this.state; - return ( - - - - - - {!isTab2Hidden && ( - - )} - - -
    - - Tab 1 section - - {!isTab2Hidden && ( - - )} - -
    -
    - ); - } -} +```ts file="./TabsToggledSeparateContent.tsx" ``` ### Dynamic @@ -1645,3 +143,13 @@ To enable closeable tabs, pass the `onClose` property to `Tabs`, and to enable t ```ts file="./TabsDynamic.tsx" isBeta ``` + +### Help action + +```ts file="./TabsHelp.tsx" isBeta +``` + +### Help and close actions + +```ts file="./TabsHelpAndClose.tsx" isBeta +``` diff --git a/packages/react-core/src/components/Tabs/examples/TabsBoxLight.tsx b/packages/react-core/src/components/Tabs/examples/TabsBoxLight.tsx new file mode 100644 index 00000000000..58b1d392e35 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsBoxLight.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; + +export const TabsBoxLight: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isTabsLightScheme, setIsTabsLightScheme] = React.useState(true); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleScheme = (checked: boolean) => { + setIsTabsLightScheme(checked); + }; + + const tooltip = ( + + ); + return ( +
    + + Users} aria-label="Box light variation content - users"> + Users + + Containers}> + Containers + + Database}> + Database + + Disabled} isDisabled> + Disabled + + ARIA Disabled} isAriaDisabled> + ARIA Disabled + + ARIA Disabled (Tooltip)} isAriaDisabled tooltip={tooltip}> + ARIA Disabled (Tooltip) + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsChildrenMounting.tsx b/packages/react-core/src/components/Tabs/examples/TabsChildrenMounting.tsx new file mode 100644 index 00000000000..23e189e63ca --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsChildrenMounting.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText } from '@patternfly/react-core'; + +export const TabsChildrenMounting: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + return ( + + Tab item 1} aria-label="Tab 1"> + Tab 1 section + + Tab item 2} aria-label="Tab 2"> + Tab 2 section + + Tab item 3} aria-label="Tab 3"> + Tab 3 section + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsContentWithBodyPadding.tsx b/packages/react-core/src/components/Tabs/examples/TabsContentWithBodyPadding.tsx new file mode 100644 index 00000000000..1271559f18c --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsContentWithBodyPadding.tsx @@ -0,0 +1,58 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, TabContent, TabContentBody } from '@patternfly/react-core'; + +export const TabContentWithBodyPadding: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const contentRef1 = React.createRef(); + const contentRef2 = React.createRef(); + const contentRef3 = React.createRef(); + + return ( + + + Tab item 1} + tabContentId="tab1SectionBodyPadding" + tabContentRef={contentRef1} + /> + Tab item 2} + tabContentId="tab2SectionBodyPadding" + tabContentRef={contentRef2} + /> + Tab item 3} + tabContentId="tab3SectionBodyPadding" + tabContentRef={contentRef3} + /> + +
    + + Tab 1 section with body and padding + + + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsDefault.tsx b/packages/react-core/src/components/Tabs/examples/TabsDefault.tsx new file mode 100644 index 00000000000..dadc08edb48 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsDefault.tsx @@ -0,0 +1,62 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; + +export const TabsDefault: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + const tooltip = ( + + ); + return ( +
    + + Users} aria-label="Default content - users"> + Users + + Containers}> + Containers + + Database}> + Database + + Disabled} isDisabled> + Disabled + + ARIA Disabled} isAriaDisabled> + ARIA Disabled + + ARIA Disabled (Tooltip)} isAriaDisabled> + ARIA Disabled (Tooltip) + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsDefaultOverflow.tsx b/packages/react-core/src/components/Tabs/examples/TabsDefaultOverflow.tsx new file mode 100644 index 00000000000..caa78a3791f --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsDefaultOverflow.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; + +export const TabsDefaultOverflow: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + return ( +
    + + Users} aria-label="Default overflow content users"> + Users + + Containers}> + Containers + + Database}> + Database + + Server}> + Server + + System}> + System + + Network}> + Network + + Tab item 7}> + Tab 7 section + + Tab item 8}> + Tab 8 section + + Tab item 9}> + Tab 9 section + + Tab item 10}> + Tab 10 section + + Tab item 11}> + Tab 11 section + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsFilled.tsx b/packages/react-core/src/components/Tabs/examples/TabsFilled.tsx new file mode 100644 index 00000000000..6802cf36d25 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsFilled.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; + +export const TabsFilled: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + return ( +
    + + Users} aria-label="Tabs filled example content users"> + Users + + Containers}> + Containers + + Database}> + Database + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsFilledWithIcons.tsx b/packages/react-core/src/components/Tabs/examples/TabsFilledWithIcons.tsx new file mode 100644 index 00000000000..613434fa22b --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsFilledWithIcons.tsx @@ -0,0 +1,85 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, TabTitleIcon, Checkbox } from '@patternfly/react-core'; +import UsersIcon from '@patternfly/react-icons/dist/esm/icons/users-icon'; +import BoxIcon from '@patternfly/react-icons/dist/esm/icons/box-icon'; +import DatabaseIcon from '@patternfly/react-icons/dist/esm/icons/database-icon'; + +export const TabsFilledWithIcons: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + return ( +
    + + + + + {' '} + Users{' '} + + } + aria-label="filled tabs with icons content users" + > + Users + + + + + {' '} + Containers{' '} + + } + > + Containers + + + + + {' '} + Database{' '} + + } + > + Database + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsHelp.tsx b/packages/react-core/src/components/Tabs/examples/TabsHelp.tsx new file mode 100644 index 00000000000..32e287546da --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsHelp.tsx @@ -0,0 +1,61 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, TabAction, Popover } from '@patternfly/react-core'; +import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; + +export const TabsHelp: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + + const tabs = ['Users', 'Containers', 'Database', 'Disabled', 'ARIA disabled', 'Help disabled']; + + const helpPopover = (header: string, popoverRef: React.RefObject) => ( + {header}
  • } + bodyContent={ +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis. +
    + } + footerContent="Popover footer" + reference={popoverRef} + /> + ); + + return ( + setActiveTabKey(tabIndex as number)} + aria-label="Tabs in the help action example" + role="region" + > + {tabs.map((tab, index) => { + const ref = React.createRef(); + + return ( + {tab}} + {...(tab === 'Disabled' && { isDisabled: true })} + {...(tab === 'ARIA disabled' && { isAriaDisabled: true })} + actions={ + <> + + + + {helpPopover(`Help popover for ${tab}`, ref)} + + } + > + {tab} + + ); + })} + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsHelpAndClose.tsx b/packages/react-core/src/components/Tabs/examples/TabsHelpAndClose.tsx new file mode 100644 index 00000000000..2c409a5fbae --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsHelpAndClose.tsx @@ -0,0 +1,84 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Popover, TabAction } from '@patternfly/react-core'; +import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; +import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon'; + +export const TabsHelpAndClose: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [tabs, setTabs] = React.useState(['Terminal 1', 'Terminal 2', 'Terminal 3']); + const tabComponentRef = React.useRef(); + const firstMount = React.useRef(true); + + const onClose = (event: any, tabIndex: string | number) => { + const tabIndexNum = tabIndex as number; + let nextTabIndex = activeTabKey; + if (tabIndexNum < activeTabKey) { + // if a preceding tab is closing, keep focus on the new index of the current tab + nextTabIndex = activeTabKey - 1 > 0 ? activeTabKey - 1 : 0; + } else if (activeTabKey === tabs.length - 1) { + // if the closing tab is the last tab, focus the preceding tab + nextTabIndex = tabs.length - 2 > 0 ? tabs.length - 2 : 0; + } + setActiveTabKey(nextTabIndex); + setTabs(tabs.filter((tab, index) => index !== tabIndex)); + }; + + const helpPopover = (header: string, popoverRef: React.RefObject) => ( + {header}
    } + bodyContent={ +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam id feugiat augue, nec fringilla turpis. +
    + } + footerContent="Popover footer" + reference={popoverRef} + /> + ); + + React.useEffect(() => { + if (firstMount.current) { + firstMount.current = false; + return; + } else { + const first = tabComponentRef.current.tabList.current.childNodes[activeTabKey]; + first && first.firstChild.focus(); + } + }, [tabs]); + + return ( + setActiveTabKey(tabIndex as number)} + aria-label="Tabs in the help enabled and closeable example" + role="region" + ref={tabComponentRef} + > + {tabs.map((tab, index) => { + const ref = React.createRef(); + + return ( + {tab}} + actions={ + <> + + + + onClose(e, index)} isDisabled={tabs.length === 1}> + + + {helpPopover(`Help popover for ${tab}`, ref)} + + } + > + {tab} + + ); + })} + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsIconAndText.tsx b/packages/react-core/src/components/Tabs/examples/TabsIconAndText.tsx new file mode 100644 index 00000000000..6c0da805c7f --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsIconAndText.tsx @@ -0,0 +1,108 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, TabTitleIcon } from '@patternfly/react-core'; +import UsersIcon from '@patternfly/react-icons/dist/esm/icons/users-icon'; +import BoxIcon from '@patternfly/react-icons/dist/esm/icons/box-icon'; +import DatabaseIcon from '@patternfly/react-icons/dist/esm/icons/database-icon'; +import ServerIcon from '@patternfly/react-icons/dist/esm/icons/server-icon'; +import LaptopIcon from '@patternfly/react-icons/dist/esm/icons/laptop-icon'; +import ProjectDiagramIcon from '@patternfly/react-icons/dist/esm/icons/project-diagram-icon'; + +export const TabsIconAndText: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + return ( + + + + + {' '} + Users{' '} + + } + aria-label="icons and text content" + > + Users + + + + + {' '} + Containers{' '} + + } + > + Containers + + + + + {' '} + Database{' '} + + } + > + Database + + + + + {' '} + Server{' '} + + } + > + Server + + + + + {' '} + System{' '} + + } + > + System + + + + + {' '} + Network{' '} + + } + > + Network + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsInset.tsx b/packages/react-core/src/components/Tabs/examples/TabsInset.tsx new file mode 100644 index 00000000000..6f9964d6627 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsInset.tsx @@ -0,0 +1,65 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; + +export const TabsInset: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + return ( +
    + + Users} aria-label="Inset example content users"> + Users + + Containers}> + Containers + + Database}> + Database + + Server}> + Server + + System}> + System + + Network}> + Network + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsNav.tsx b/packages/react-core/src/components/Tabs/examples/TabsNav.tsx new file mode 100644 index 00000000000..42494ea94f0 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsNav.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import { Tabs, Tab, TabsComponent, TabTitleText } from '@patternfly/react-core'; + +export const TabsNav: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + return ( + + Users} href="#users" aria-label="Nav element content users"> + Users + + Containers} href="#containers"> + Containers + + Database} href="#database"> + Database + + Disabled} isDisabled href="#disabled"> + Disabled + + ARIA Disabled} isAriaDisabled href="#aria-disabled"> + ARIA Disabled + + Network} href="#network"> + Network + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsNavSecondary.tsx b/packages/react-core/src/components/Tabs/examples/TabsNavSecondary.tsx new file mode 100644 index 00000000000..7102c5aca73 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsNavSecondary.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { Tabs, Tab, TabsComponent, TabTitleText } from '@patternfly/react-core'; + +export const TabsNavSecondary: React.FunctionComponent = () => { + const [activeTabKey1, setActiveTabKey1] = React.useState(0); + const [activeTabKey2, setActiveTabKey2] = React.useState(0); + + // Toggle currently active primary tab + const handleTabClickFirst = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey1(tabIndex); + }; + + // Toggle currently active secondary tab + const handleTabClickSecond = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey2(tabIndex); + }; + + return ( + + Users} href="#" aria-label="Subtabs with nav content users"> + + Item 1} href="#"> + Item 1 item section + + Item 2} href="#"> + Item 2 section + + Item 3} href="#"> + Item 3 section + + Disabled} isDisabled href="#"> + Disabled + + ARIA Disabled} isAriaDisabled href="#"> + ARIA Disabled + + Item 6} href="#"> + Item 6 section + + + + Containers} href="#"> + Containers + + Database} href="#"> + Database + + Disabled} isDisabled href="#"> + Disabled + + ARIA Disabled} isAriaDisabled href="#"> + ARIA Disabled + + Network} href="#"> + Network + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsPageInsets.tsx b/packages/react-core/src/components/Tabs/examples/TabsPageInsets.tsx new file mode 100644 index 00000000000..e0a5429a396 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsPageInsets.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; + +export const TabsPageInsets: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + return ( +
    + + Users} aria-label="Page insets example content users"> + Users + + Containers}> + Containers + + Database}> + Database + + Server}> + Server + + System}> + System + + Network}> + Network + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsSeparateContent.tsx b/packages/react-core/src/components/Tabs/examples/TabsSeparateContent.tsx new file mode 100644 index 00000000000..a07c3455636 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsSeparateContent.tsx @@ -0,0 +1,75 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, TabContent } from '@patternfly/react-core'; + +export const TabsSeparateContent: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const contentRef1 = React.createRef(); + const contentRef2 = React.createRef(); + const contentRef3 = React.createRef(); + + return ( + + + Tab item 1} + tabContentId="refTab1Section" + tabContentRef={contentRef1} + /> + Tab item 2} + tabContentId="refTab2Section" + tabContentRef={contentRef2} + /> + Tab item 3} + tabContentId="refTab3Section" + tabContentRef={contentRef3} + /> + +
    + + Tab 1 section + + + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsSubtabs.tsx b/packages/react-core/src/components/Tabs/examples/TabsSubtabs.tsx new file mode 100644 index 00000000000..2994a622641 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsSubtabs.tsx @@ -0,0 +1,115 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox } from '@patternfly/react-core'; + +export const TabsSubtabs: React.FunctionComponent = () => { + const [activeTabKey1, setActiveTabKey1] = React.useState(0); + const [activeTabKey2, setActiveTabKey2] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + + // Toggle currently active primary tab + const handleTabClickFirst = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey1(tabIndex); + }; + + // Toggle currently active secondary tab + const handleTabClickSecond = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey2(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + return ( +
    + + Users} aria-label="Tabs with subtabs content users"> + + Secondary tab item 1}> + Secondary tab item 1 item section + + Secondary tab item 2}> + Secondary tab item 2 section + + Secondary tab item 3}> + Secondary tab item 3 section + + Secondary tab item 4}> + Secondary tab item 4 section + + Secondary tab item 5}> + Secondary tab item 5 section + + Secondary tab item 6}> + Secondary tab item 6 section + + Secondary tab item 7}> + Secondary tab item 7 section + + Secondary tab item 8}> + Secondary tab item 8 section + + + + Containers}> + Containers + + Database}> + Database + + Server}> + Server + + System}> + System + + Network}> + Network + + Tab item 7}> + Tab 7 section + + Tab item 8}> + Tab 8 section + + Tab item 9}> + Tab 9 section + + Tab item 10}> + Tab 10 section + + Tab item 11}> + Tab 11 section + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsToggledSeparateContent.tsx b/packages/react-core/src/components/Tabs/examples/TabsToggledSeparateContent.tsx new file mode 100644 index 00000000000..80aaf1c72f9 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsToggledSeparateContent.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import { Tabs, Tab, TabContent, Button, Divider } from '@patternfly/react-core'; + +export const TabsToggledSeparateContent: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isTab2Hidden, setisTab2Hidden] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const contentRef1 = React.createRef(); + const contentRef2 = React.createRef(); + const contentRef3 = React.createRef(); + + return ( + + + + + + {!isTab2Hidden && ( + + )} + + +
    + + Tab 1 section + + {!isTab2Hidden && ( + + )} + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsTooltipReactRef.tsx b/packages/react-core/src/components/Tabs/examples/TabsTooltipReactRef.tsx new file mode 100644 index 00000000000..df7665c20ad --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsTooltipReactRef.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; + +export const TabsTooltipReactRef: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + const tooltipRef = React.createRef(); + + return ( +
    + + Users} aria-label="Tooltip ref content - users"> + Users + + Containers}> + Containers + + Database}> + Database + + Disabled} isDisabled> + Disabled + + ARIA Disabled} isAriaDisabled> + ARIA Disabled + + ARIA Disabled (Tooltip)} + isAriaDisabled + ref={tooltipRef} + aria-describedby="tooltip-ref1" + > + ARIA Disabled (Tooltip) + + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsUncontrolled.tsx b/packages/react-core/src/components/Tabs/examples/TabsUncontrolled.tsx new file mode 100644 index 00000000000..51fb4826278 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsUncontrolled.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Tooltip } from '@patternfly/react-core'; + +export const TabsUncontrolled: React.FunctionComponent = () => { + const tooltip = ( + + ); + + return ( + <> + + Users} aria-label="Uncontrolled ref content - users"> + Users + + Containers}> + Containers + + Database}> + Database + + Disabled} isDisabled> + Disabled + + ARIA Disabled} isAriaDisabled> + ARIA Disabled + + ARIA Disabled (Tooltip)} isAriaDisabled tooltip={tooltip}> + ARIA Disabled (Tooltip) + + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsUnmountingInvisibleChildren.tsx b/packages/react-core/src/components/Tabs/examples/TabsUnmountingInvisibleChildren.tsx new file mode 100644 index 00000000000..ed5b275043c --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsUnmountingInvisibleChildren.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText } from '@patternfly/react-core'; + +export const TabsUnmountingInvisibleChildren: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + return ( + + Tab item 1} aria-label="Invisible children tab 1"> + Tab 1 section + + Tab item 2} aria-label="Invisible children tab 2"> + Tab 2 section + + Tab item 3} aria-label="Invisible children tab 3"> + Tab 3 section + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsVertical.tsx b/packages/react-core/src/components/Tabs/examples/TabsVertical.tsx new file mode 100644 index 00000000000..3b05d926fd6 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsVertical.tsx @@ -0,0 +1,72 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText, Checkbox, Tooltip } from '@patternfly/react-core'; + +export const TabsVertical: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isBox, setIsBox] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const toggleBox = (checked: boolean) => { + setIsBox(checked); + }; + + const tooltip = ( + + ); + + return ( +
    + + + Users + + } + aria-label="Vertical example content users" + > + Users + + Containers}> + Containers + + Database}> + Database + + Disabled} isDisabled> + Disabled + + ARIA Disabled} isAriaDisabled> + ARIA Disabled + + ARIA Disabled (Tooltip)} isAriaDisabled tooltip={tooltip}> + ARIA Disabled (Tooltip) + + +
    + +
    +
    + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsVerticalExpandable.tsx b/packages/react-core/src/components/Tabs/examples/TabsVerticalExpandable.tsx new file mode 100644 index 00000000000..5b31c6f8469 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsVerticalExpandable.tsx @@ -0,0 +1,51 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText } from '@patternfly/react-core'; + +export const TabsVerticalExpandable: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + const [isExpanded, setIsExpanded] = React.useState(false); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + const onToggle = (isExpanded: boolean) => { + setIsExpanded(isExpanded); + }; + + return ( + + Users} aria-label="Vertical expandable content users"> + Users + + Containers}> + Containers + + Database}> + Database + + Server}> + Server + + System}> + System + + Network}> + Network + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/examples/TabsVerticalExpandableUncontrolled.tsx b/packages/react-core/src/components/Tabs/examples/TabsVerticalExpandableUncontrolled.tsx new file mode 100644 index 00000000000..ac01f6f7dc3 --- /dev/null +++ b/packages/react-core/src/components/Tabs/examples/TabsVerticalExpandableUncontrolled.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { Tabs, Tab, TabTitleText } from '@patternfly/react-core'; +export const TabsVerticalExpandableUncontrolled: React.FunctionComponent = () => { + const [activeTabKey, setActiveTabKey] = React.useState(0); + // Toggle currently active tab + const handleTabClick = ( + event: React.MouseEvent | React.KeyboardEvent | MouseEvent, + tabIndex: string | number + ) => { + setActiveTabKey(tabIndex); + }; + + return ( + + Users} + aria-label="Vertical expandable uncontrolled content users" + > + Users + + Containers}> + Containers + + Database}> + Database + + Server}> + Server + + System}> + System + + Network}> + Network + + + ); +}; diff --git a/packages/react-core/src/components/Tabs/index.ts b/packages/react-core/src/components/Tabs/index.ts index 83aa2d999e2..cf7db30a898 100644 --- a/packages/react-core/src/components/Tabs/index.ts +++ b/packages/react-core/src/components/Tabs/index.ts @@ -1,4 +1,5 @@ export * from './Tab'; +export * from './TabAction'; export * from './Tabs'; export * from './TabContent'; export * from './TabContentBody'; diff --git a/packages/react-core/src/components/Text/TextList.tsx b/packages/react-core/src/components/Text/TextList.tsx index 85b4b84eeca..71b04420f1f 100644 --- a/packages/react-core/src/components/Text/TextList.tsx +++ b/packages/react-core/src/components/Text/TextList.tsx @@ -25,7 +25,7 @@ export const TextList: React.FunctionComponent = ({ const Component: any = component; return ( - + {children} ); diff --git a/packages/react-core/src/components/Text/TextListItem.tsx b/packages/react-core/src/components/Text/TextListItem.tsx index 7d545480239..81b6eeb7c83 100644 --- a/packages/react-core/src/components/Text/TextListItem.tsx +++ b/packages/react-core/src/components/Text/TextListItem.tsx @@ -25,7 +25,7 @@ export const TextListItem: React.FunctionComponent = ({ const Component: any = component; return ( - + {children} ); diff --git a/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextList.test.tsx.snap b/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextList.test.tsx.snap index 2586930f620..8c52190fe42 100644 --- a/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextList.test.tsx.snap +++ b/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextList.test.tsx.snap @@ -4,7 +4,6 @@ exports[`TextList should match snapshot (auto-generated) 1`] = `
      ReactNode
    diff --git a/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextListItem.test.tsx.snap b/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextListItem.test.tsx.snap index c9cd241161c..a22cc9cfcb4 100644 --- a/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextListItem.test.tsx.snap +++ b/packages/react-core/src/components/Text/__tests__/Generated/__snapshots__/TextListItem.test.tsx.snap @@ -4,7 +4,6 @@ exports[`TextListItem should match snapshot (auto-generated) 1`] = `
  • ReactNode
  • diff --git a/packages/react-core/src/components/Text/__tests__/Text.test.tsx b/packages/react-core/src/components/Text/__tests__/Text.test.tsx index ee40d979ff3..e0f8606f813 100644 --- a/packages/react-core/src/components/Text/__tests__/Text.test.tsx +++ b/packages/react-core/src/components/Text/__tests__/Text.test.tsx @@ -1,112 +1,101 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { TextContent } from '../TextContent'; -import { Text, TextVariants } from '../Text'; -import { TextList, TextListVariants } from '../TextList'; -import { TextListItem, TextListItemVariants } from '../TextListItem'; - -test('Text example should match snapshot', () => { - const { asFragment } = render( - - Hello World - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla accumsan, metus ultrices eleifend gravida, nulla - nunc varius lectus, nec rutrum justo nibh eu lectus. Ut vulputate semper dui. Fusce erat odio, sollicitudin vel - erat vel, interdum mattis neque. Sub works as well! - - Second level - - Curabitur accumsan turpis pharetra augue tincidunt blandit. Quisque condimentum maximus mi, sit - amet commodo arcu rutrum id. Proin pretium urna vel cursus venenatis. Suspendisse potenti. Etiam mattis sem - rhoncus lacus dapibus facilisis. Donec at dignissim dui. Ut et neque nisl. - - - In fermentum leo eu lectus mollis, quis dictum mi aliquet. - Morbi eu nulla lobortis, lobortis est in, fringilla felis. - - Aliquam nec felis in sapien venenatis viverra fermentum nec lectus. - - In fermentum leo eu lectus mollis, quis dictum mi aliquet. - Morbi eu nulla lobortis, lobortis est in, fringilla felis. - - - Ut non enim metus. - - Third level - - Quisque ante lacus, malesuada ac auctor vitae, congue{' '} - - non ante - - . Phasellus lacus ex, semper ac tortor nec, fringilla condimentum orci. Fusce eu rutrum tellus. - - - Donec blandit a lorem id convallis. - Cras gravida arcu at diam gravida gravida. - Integer in volutpat libero. - Donec a diam tellus. - Aenean nec tortor orci. - Quisque aliquam cursus urna, non bibendum massa viverra eget. - Vivamus maximus ultricies pulvinar. - - - Ut venenatis, nisl scelerisque sollicitudin fermentum, quam libero hendrerit ipsum, ut blandit est tellus sit - amet turpis. - - - Quisque at semper enim, eu hendrerit odio. Etiam auctor nisl et justo sodales elementum. Maecenas - ultrices lacus quis neque consectetur, et lobortis nisi molestie. - - - Sed sagittis enim ac tortor maximus rutrum. Nulla facilisi. Donec mattis vulputate risus in luctus. Maecenas - vestibulum interdum commodo. - - - Web - - The part of the Internet that contains websites and web pages - - HTML - A markup language for creating web pages - CSS - A technology to make HTML look better - - - Suspendisse egestas sapien non felis placerat elementum. Morbi tortor nisl, suscipit sed mi sit amet, mollis - malesuada nulla. Nulla facilisi. Nullam ac erat ante. - - Fourth level - - Nulla efficitur eleifend nisi, sit amet bibendum sapien fringilla ac. Mauris euismod metus a tellus laoreet, at - elementum ex efficitur. - - - Maecenas eleifend sollicitudin dui, faucibus sollicitudin augue cursus non. Ut finibus eleifend arcu ut - vehicula. Mauris eu est maximus est porta condimentum in eu justo. Nulla id iaculis sapien. - - Sometimes you need small text to display things like date created - - Phasellus porttitor enim id metus volutpat ultricies. Ut nisi nunc, blandit sed dapibus at, vestibulum in felis. - Etiam iaculis lorem ac nibh bibendum rhoncus. Nam interdum efficitur ligula sit amet ullamcorper. Etiam - tristique, leo vitae porta faucibus, mi lacus laoreet metus, at cursus leo est vel tellus. Sed ac posuere est. - Nunc ultricies nunc neque, vitae ultricies ex sodales quis. Aliquam eu nibh in libero accumsan pulvinar. Nullam - nec nisl placerat, pretium metus vel, euismod ipsum. Proin tempor cursus nisl vel condimentum. Nam pharetra - varius metus non pellentesque. - - Fifth level - - Aliquam sagittis rhoncus vulputate. Cras non luctus sem, sed tincidunt ligula. Vestibulum at nunc elit. Praesent - aliquet ligula mi, in luctus elit volutpat porta. Phasellus molestie diam vel nisi sodales, a eleifend augue - laoreet. Sed nec eleifend justo. Nam et sollicitudin odio. - - Sixth level - - Cras in nibh lacinia, venenatis nisi et, auctor urna. Donec pulvinar lacus sed diam dignissim, ut eleifend eros - accumsan. Phasellus non tortor eros. Ut sed rutrum lacus. Etiam purus nunc, scelerisque quis enim vitae, - malesuada ultrices turpis. Nunc vitae maximus purus, nec consectetur dui. Suspendisse euismod, elit vel rutrum - commodo, ipsum tortor maximus dui, sed varius sapien odio vitae est. Etiam at cursus metus. - - +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { Text } from '../Text'; + +test('Renders without children', () => { + render( +
    + +
    + ); + expect(screen.getByTestId('test-content').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders without class name by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toHaveClass(); +}); + +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); +}); + +test('Renders as "p" element by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'P'); +}); + +test('Renders as "h1" element when component="h1"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 1 })).toBeVisible(); +}); + +test('Renders as "h2" element when component="h2"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 2 })).toBeVisible(); +}); + +test('Renders as "h3" element when component="h3"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 3 })).toBeVisible(); +}); + +test('Renders as "h4" element when component="h4"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 4 })).toBeVisible(); +}); + +test('Renders as "h5" element when component="h5"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 5 })).toBeVisible(); +}); + +test('Renders as "h6" element when component="h6"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 6 })).toBeVisible(); +}); + +test('Renders as "a" element when component="a"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'A'); +}); + +test('Renders as "blockquote" element when component="blockquote"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'BLOCKQUOTE'); +}); + +test('Renders as "pre" element when component="pre"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'PRE'); +}); + +test('Renders without class name pf-m-visited by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toHaveClass('pf-m-visited'); +}); + +test('Renders with class name pf-m-visited when isVisited=true and component="a"', () => { + render( + + Test + ); + expect(screen.getByText('Test')).toHaveClass('pf-m-visited'); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); expect(asFragment()).toMatchSnapshot(); }); diff --git a/packages/react-core/src/components/Text/__tests__/TextContent.text.tsx b/packages/react-core/src/components/Text/__tests__/TextContent.text.tsx new file mode 100644 index 00000000000..38f526bb1a9 --- /dev/null +++ b/packages/react-core/src/components/Text/__tests__/TextContent.text.tsx @@ -0,0 +1,103 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { Text } from '../Text'; + +describe('Button', () => { + test('Renders without children', () => { + render( +
    + +
    + ); + expect(screen.getByTestId('test-content').firstChild).toBeVisible(); + }); + + test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); + }); + + test('Renders without class name by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toHaveClass(); + }); + + test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); + }); + + test('Renders as "p" element by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'P'); + }); + + test('Renders as "h1" element when component="h1"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 1 })).toBeVisible(); + }); + + test('Renders as "h2" element when component="h2"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 2 })).toBeVisible(); + }); + + test('Renders as "h3" element when component="h3"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 3 })).toBeVisible(); + }); + + test('Renders as "h4" element when component="h4"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 4 })).toBeVisible(); + }); + + test('Renders as "h5" element when component="h5"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 5 })).toBeVisible(); + }); + + test('Renders as "h6" element when component="h6"', () => { + render(Test); + expect(screen.getByRole('heading', { level: 6 })).toBeVisible(); + }); + + test('Renders as "a" element when component="a"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'A'); + }); + + test('Renders as "blockquote" element when component="blockquote"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'BLOCKQUOTE'); + }); + + test('Renders as "pre" element when component="pre"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'PRE'); + }); + + test('Renders without class name pf-m-visited by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toHaveClass('pf-m-visited'); + }); + + test('Renders with class name pf-m-visited when isVisited=true and component="a"', () => { + render( + + Test + + ); + expect(screen.getByText('Test')).toHaveClass('pf-m-visited'); + }); + + test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); + }); + + test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); + }); +}); diff --git a/packages/react-core/src/components/Text/__tests__/TextList.test.tsx b/packages/react-core/src/components/Text/__tests__/TextList.test.tsx new file mode 100644 index 00000000000..6bbfbb11726 --- /dev/null +++ b/packages/react-core/src/components/Text/__tests__/TextList.test.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TextList } from '../TextList'; + +test('Renders without children', () => { + render( +
    + +
    + ); + expect(screen.getByTestId('test-list').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders without class name by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toHaveClass(); +}); + +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); +}); + +test('Renders as "ul" element by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'UL'); +}); + +test('Renders as "ol" element when component="ol"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'OL'); +}); + +test('Renders as "dl" element when component="dl"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'DL'); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Text/__tests__/TextListItem.test.tsx b/packages/react-core/src/components/Text/__tests__/TextListItem.test.tsx new file mode 100644 index 00000000000..34f7fbb9039 --- /dev/null +++ b/packages/react-core/src/components/Text/__tests__/TextListItem.test.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; +import { render, screen } from '@testing-library/react'; +import { TextListItem } from '../TextListItem'; + +test('Renders without children', () => { + render( +
    + +
    + ); + expect(screen.getByTestId('test-list-item').firstChild).toBeVisible(); +}); + +test('Renders children', () => { + render(Test); + expect(screen.getByText('Test')).toBeVisible(); +}); + +test('Renders without class name by default', () => { + render(Test); + expect(screen.getByText('Test')).not.toHaveClass(); +}); + +test('Renders with custom class name when className prop is provided', () => { + render(Test); + expect(screen.getByText('Test')).toHaveClass('custom-class'); +}); + +test('Renders as "li" element by default', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'LI'); +}); + +test('Renders as "dt" element when component="dt"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'DT'); +}); + +test('Renders as "dd" element when component="dd"', () => { + render(Test); + expect(screen.getByText('Test')).toHaveProperty('nodeName', 'DD'); +}); + +test('Renders with inherited element props spread to the component', () => { + render(Test); + expect(screen.getByText('Test')).toHaveAccessibleName('Test label'); +}); + +test('Matches the snapshot', () => { + const { asFragment } = render(Test); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/Text/__tests__/__snapshots__/Text.test.tsx.snap b/packages/react-core/src/components/Text/__tests__/__snapshots__/Text.test.tsx.snap index 3d108df3f66..a260407f116 100644 --- a/packages/react-core/src/components/Text/__tests__/__snapshots__/Text.test.tsx.snap +++ b/packages/react-core/src/components/Text/__tests__/__snapshots__/Text.test.tsx.snap @@ -1,334 +1,15 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Text example should match snapshot 1`] = ` +exports[`Matches the snapshot 1`] = ` -
    -

    - Hello World -

    -

    - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla accumsan, metus ultrices eleifend gravida, nulla nunc varius lectus, nec rutrum justo nibh eu lectus. Ut vulputate semper dui. Fusce erat odio, sollicitudin vel erat vel, interdum mattis neque. Sub works as well! -

    -

    - Second level -

    -

    - Curabitur accumsan turpis pharetra - - augue tincidunt - - blandit. Quisque condimentum maximus mi, sit amet commodo arcu rutrum id. Proin pretium urna vel cursus venenatis. Suspendisse potenti. Etiam mattis sem rhoncus lacus dapibus facilisis. Donec at dignissim dui. Ut et neque nisl. -

    -
      -
    • - In fermentum leo eu lectus mollis, quis dictum mi aliquet. -
    • -
    • - Morbi eu nulla lobortis, lobortis est in, fringilla felis. -
    • -
    • - Aliquam nec felis in sapien venenatis viverra fermentum nec lectus. -
        -
      • - In fermentum leo eu lectus mollis, quis dictum mi aliquet. -
      • -
      • - Morbi eu nulla lobortis, lobortis est in, fringilla felis. -
      • -
      -
    • -
    • - Ut non enim metus. -
    • -
    -

    - Third level -

    -

    - Quisque ante lacus, malesuada ac auctor vitae, congue - - non ante - - . Phasellus lacus ex, semper ac tortor nec, fringilla condimentum orci. Fusce eu rutrum tellus. -

    -
      -
    1. - Donec blandit a lorem id convallis. -
    2. -
    3. - Cras gravida arcu at diam gravida gravida. -
    4. -
    5. - Integer in volutpat libero. -
    6. -
    7. - Donec a diam tellus. -
    8. -
    9. - Aenean nec tortor orci. -
    10. -
    11. - Quisque aliquam cursus urna, non bibendum massa viverra eget. -
    12. -
    13. - Vivamus maximus ultricies pulvinar. -
    14. -
    -
    - Ut venenatis, nisl scelerisque sollicitudin fermentum, quam libero hendrerit ipsum, ut blandit est tellus sit amet turpis. -
    -

    - Quisque at semper enim, eu hendrerit odio. Etiam auctor nisl et - - justo sodales - - elementum. Maecenas ultrices lacus quis neque consectetur, et lobortis nisi molestie. -

    -

    - Sed sagittis enim ac tortor maximus rutrum. Nulla facilisi. Donec mattis vulputate risus in luctus. Maecenas vestibulum interdum commodo. -

    -
    -
    - Web -
    -
    - The part of the Internet that contains websites and web pages -
    -
    - HTML -
    -
    - A markup language for creating web pages -
    -
    - CSS -
    -
    - A technology to make HTML look better -
    -
    -

    - Suspendisse egestas sapien non felis placerat elementum. Morbi tortor nisl, suscipit sed mi sit amet, mollis malesuada nulla. Nulla facilisi. Nullam ac erat ante. -

    -

    - Fourth level -

    -

    - Nulla efficitur eleifend nisi, sit amet bibendum sapien fringilla ac. Mauris euismod metus a tellus laoreet, at elementum ex efficitur. -

    -

    - Maecenas eleifend sollicitudin dui, faucibus sollicitudin augue cursus non. Ut finibus eleifend arcu ut vehicula. Mauris eu est maximus est porta condimentum in eu justo. Nulla id iaculis sapien. -

    - - Sometimes you need small text to display things like date created - -

    - Phasellus porttitor enim id metus volutpat ultricies. Ut nisi nunc, blandit sed dapibus at, vestibulum in felis. Etiam iaculis lorem ac nibh bibendum rhoncus. Nam interdum efficitur ligula sit amet ullamcorper. Etiam tristique, leo vitae porta faucibus, mi lacus laoreet metus, at cursus leo est vel tellus. Sed ac posuere est. Nunc ultricies nunc neque, vitae ultricies ex sodales quis. Aliquam eu nibh in libero accumsan pulvinar. Nullam nec nisl placerat, pretium metus vel, euismod ipsum. Proin tempor cursus nisl vel condimentum. Nam pharetra varius metus non pellentesque. -

    -
    - Fifth level -
    -

    - Aliquam sagittis rhoncus vulputate. Cras non luctus sem, sed tincidunt ligula. Vestibulum at nunc elit. Praesent aliquet ligula mi, in luctus elit volutpat porta. Phasellus molestie diam vel nisi sodales, a eleifend augue laoreet. Sed nec eleifend justo. Nam et sollicitudin odio. -

    -
    - Sixth level -
    -

    - Cras in nibh lacinia, venenatis nisi et, auctor urna. Donec pulvinar lacus sed diam dignissim, ut eleifend eros accumsan. Phasellus non tortor eros. Ut sed rutrum lacus. Etiam purus nunc, scelerisque quis enim vitae, malesuada ultrices turpis. Nunc vitae maximus purus, nec consectetur dui. Suspendisse euismod, elit vel rutrum commodo, ipsum tortor maximus dui, sed varius sapien odio vitae est. Etiam at cursus metus. -

    -
    + Test +

    `; diff --git a/packages/react-core/src/components/Text/__tests__/__snapshots__/TextContent.text.tsx.snap b/packages/react-core/src/components/Text/__tests__/__snapshots__/TextContent.text.tsx.snap new file mode 100644 index 00000000000..0b2bdb2cd6a --- /dev/null +++ b/packages/react-core/src/components/Text/__tests__/__snapshots__/TextContent.text.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Button Matches the snapshot 1`] = ` + +

    + Test +

    +
    +`; diff --git a/packages/react-core/src/components/Text/__tests__/__snapshots__/TextList.test.tsx.snap b/packages/react-core/src/components/Text/__tests__/__snapshots__/TextList.test.tsx.snap new file mode 100644 index 00000000000..511aedf785f --- /dev/null +++ b/packages/react-core/src/components/Text/__tests__/__snapshots__/TextList.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
      + Test +
    +
    +`; diff --git a/packages/react-core/src/components/Text/__tests__/__snapshots__/TextListItem.test.tsx.snap b/packages/react-core/src/components/Text/__tests__/__snapshots__/TextListItem.test.tsx.snap new file mode 100644 index 00000000000..98bbdbd6a00 --- /dev/null +++ b/packages/react-core/src/components/Text/__tests__/__snapshots__/TextListItem.test.tsx.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Matches the snapshot 1`] = ` + +
  • + Test +
  • +
    +`; diff --git a/packages/react-core/src/components/TextArea/examples/TextArea.md b/packages/react-core/src/components/TextArea/examples/TextArea.md index 235dfc24d63..4f80fdb6e52 100644 --- a/packages/react-core/src/components/TextArea/examples/TextArea.md +++ b/packages/react-core/src/components/TextArea/examples/TextArea.md @@ -9,300 +9,52 @@ propComponents: ['TextArea'] ### Basic -```js -import React from 'react'; -import { TextArea } from '@patternfly/react-core'; - -class SimpleTextArea extends React.Component { - constructor(props) { - super(props); - this.state = { - value: '' - }; - - this.handleTextAreaChange = value => { - this.setState({ value }); - }; - } - - render() { - const { value } = this.state; - - return