(null)
- const onMediaQueryChange = (event: MediaQueryListEvent): void => {
- isDarkMode.value = event.matches
- }
-
- onMounted(() => {
- // get `prefers-color-scheme` media query and set the initial mode
- mediaQuery.value = window.matchMedia('(prefers-color-scheme: dark)')
- isDarkMode.value = mediaQuery.value.matches
-
- // watch changes
- mediaQuery.value.addEventListener('change', onMediaQueryChange)
- watch(isDarkMode, updateDarkModeClass, { immediate: true })
- })
-
- onUnmounted(() => {
- mediaQuery.value?.removeEventListener('change', onMediaQueryChange)
- updateDarkModeClass(false)
- })
-
- return isDarkMode
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/composables/useNavLink.ts b/docs/.vuepress/theme-coreui/src/client/composables/useNavLink.ts
deleted file mode 100755
index ec1bdaf2..00000000
--- a/docs/.vuepress/theme-coreui/src/client/composables/useNavLink.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import type { NavLink } from '../../shared'
-import { useResolveRouteWithRedirect } from './useResolveRouteWithRedirect'
-
-/**
- * Resolve NavLink props from string
- *
- * @example
- * - Input: '/README.md'
- * - Output: { text: 'Home', link: '/' }
- */
-export const useNavLink = (item: string): NavLink => {
- const resolved = useResolveRouteWithRedirect(item)
- return {
- text: resolved.meta.title || item,
- link: resolved.name === '404' ? item : resolved.fullPath,
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/index.ts b/docs/.vuepress/theme-coreui/src/client/index.ts
deleted file mode 100755
index 27f6c206..00000000
--- a/docs/.vuepress/theme-coreui/src/client/index.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import type {
- NavItem,
- NavGroup,
- NavLink,
- NavbarItem,
- NavbarGroup,
- NavbarConfig,
- ResolvedNavbarItem,
- SidebarItem,
- SidebarConfigArray,
- SidebarConfigObject,
- SidebarConfig,
- ResolvedSidebarItem,
- DefaultThemePluginsOptions,
- DefaultThemeLocaleOptions,
- DefaultThemeData,
- DefaultThemeLocaleData,
- DefaultThemePageData,
- DefaultThemePageFrontmatter,
- DefaultThemeHomePageFrontmatter,
- DefaultThemeNormalPageFrontmatter,
-} from '../shared'
-
-export type {
- NavItem,
- NavGroup,
- NavLink,
- NavbarItem,
- NavbarGroup,
- NavbarConfig,
- ResolvedNavbarItem,
- SidebarItem,
- SidebarConfigArray,
- SidebarConfigObject,
- SidebarConfig,
- ResolvedSidebarItem,
- DefaultThemePluginsOptions,
- DefaultThemeLocaleOptions,
- DefaultThemeData,
- DefaultThemeLocaleData,
- DefaultThemePageData,
- DefaultThemePageFrontmatter,
- DefaultThemeHomePageFrontmatter,
- DefaultThemeNormalPageFrontmatter,
-}
-export * from './composables'
-export * from './utils'
diff --git a/docs/.vuepress/theme-coreui/src/client/layouts/Layout.vue b/docs/.vuepress/theme-coreui/src/client/layouts/Layout.vue
deleted file mode 100755
index bd16772b..00000000
--- a/docs/.vuepress/theme-coreui/src/client/layouts/Layout.vue
+++ /dev/null
@@ -1,115 +0,0 @@
-
-
-
isSidebarOpen = event" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- On this page
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_code-group.scss b/docs/.vuepress/theme-coreui/src/client/styles/_code-group.scss
deleted file mode 100755
index e975bed7..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/_code-group.scss
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * code-group
- */
-.code-group__nav {
- margin-top: 0.85rem;
- // 2 * margin + border-radius of tag
- margin-bottom: calc(-1.7rem - 6px);
- padding-bottom: calc(1.7rem - 6px);
- padding-left: 10px;
- padding-top: 10px;
- border-top-left-radius: 6px;
- border-top-right-radius: 6px;
- background-color: var(--code-bg-color);
-}
-
-.code-group__ul {
- margin: auto 0;
- padding-left: 0;
- display: inline-flex;
- list-style: none;
-}
-
-.code-group__nav-tab {
- border: 0;
- padding: 5px;
- cursor: pointer;
- background-color: transparent;
- font-size: 0.85em;
- line-height: 1.4;
- color: rgba(255, 255, 255, 0.9);
- font-weight: 600;
-}
-
-.code-group__nav-tab:focus {
- outline: none;
-}
-
-.code-group__nav-tab:focus-visible {
- outline: 1px solid rgba(255, 255, 255, 0.9);
-}
-
-.code-group__nav-tab-active {
- border-bottom: var(--c-brand) 1px solid;
-}
-
-@media (max-width: $MQMobileNarrow) {
- .code-group__nav {
- margin-left: -1.5rem;
- margin-right: -1.5rem;
- border-radius: 0;
- }
-}
-
-/**
- * code-group-item
- */
-.code-group-item {
- display: none;
-}
-
-.code-group-item__active {
- display: block;
-}
-
-.code-group-item > pre {
- background-color: orange;
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_code.scss b/docs/.vuepress/theme-coreui/src/client/styles/_code.scss
deleted file mode 100755
index f494e9b7..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/_code.scss
+++ /dev/null
@@ -1,267 +0,0 @@
-@import '_variables';
-
-// ===============================
-// Forked and modified from prismjs/themes/prism-tomorrow.css
-
-code[class*='language-'],
-pre[class*='language-'] {
- color: #ccc;
- background: none;
- font-family: var(--font-family-code);
- font-size: .875em;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- word-wrap: normal;
- line-height: 1.5;
-
- -moz-tab-size: 4;
- -o-tab-size: 4;
- tab-size: 4;
-
- -webkit-hyphens: none;
- -moz-hyphens: none;
- -ms-hyphens: none;
- hyphens: none;
-}
-
-/* Code blocks */
-pre[class*='language-'] {
- padding: 1em;
- margin: 0.5em 0;
- overflow: auto;
-}
-
-:not(pre) > code[class*='language-'],
-pre[class*='language-'] {
- background: #2d2d2d;
-}
-
-/* Inline code */
-:not(pre) > code[class*='language-'] {
- padding: 0.1em;
- border-radius: 0.3em;
- white-space: normal;
-}
-
-.token.comment,
-.token.block-comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
- color: #999;
-}
-
-.token.punctuation {
- color: #ccc;
-}
-
-.token.tag,
-.token.attr-name,
-.token.namespace,
-.token.deleted {
- color: #ec5975;
-}
-
-.token.function-name {
- color: #6196cc;
-}
-
-.token.boolean,
-.token.number,
-.token.function {
- color: #f08d49;
-}
-
-.token.property,
-.token.class-name,
-.token.constant,
-.token.symbol {
- color: #f8c555;
-}
-
-.token.selector,
-.token.important,
-.token.atrule,
-.token.keyword,
-.token.builtin {
- color: #cc99cd;
-}
-
-.token.string,
-.token.char,
-.token.attr-value,
-.token.regex,
-.token.variable {
- color: #7ec699;
-}
-
-.token.operator,
-.token.entity,
-.token.url {
- color: #67cdcc;
-}
-
-.token.important,
-.token.bold {
- font-weight: bold;
-}
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
-
-.token.inserted {
- color: var(--c-text-accent);
-}
-
-// ===============================
-
-.theme-default-content {
- pre,
- pre[class*='language-'] {
- line-height: 1.4;
- padding: 1.25rem 1.5rem;
- margin: 0.85rem 0;
- border-radius: 6px;
- overflow: auto;
-
- code {
- color: #fff;
- padding: 0;
- background-color: transparent;
- border-radius: 0;
- -webkit-font-smoothing: auto;
- -moz-osx-font-smoothing: auto;
- }
- }
-
- .line-number {
- font-family: var(--font-family-code);
- }
-}
-
-div[class*='language-'] {
- position: relative;
- background-color: var(--code-bg-color);
- border-radius: 6px;
-
- &::before {
- position: absolute;
- z-index: 3;
- top: 0.8em;
- right: 1em;
- font-size: 0.75rem;
- color: var(--code-ln-color);
- }
-
- pre,
- pre[class*='language-'] {
- // force override the background color to be compatible with shiki
- background: transparent !important;
- position: relative;
- z-index: 1;
- }
-
- .highlight-lines {
- user-select: none;
- padding-top: 1.3rem;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- line-height: 1.4;
-
- .highlight-line {
- background-color: var(--code-hl-bg-color);
- }
- }
-
- &:not(.line-numbers-mode) {
- .line-numbers {
- display: none;
- }
- }
-
- &.line-numbers-mode {
- .highlight-lines .highlight-line {
- position: relative;
-
- &::before {
- content: ' ';
- position: absolute;
- z-index: 2;
- left: 0;
- top: 0;
- display: block;
- width: var(--code-ln-wrapper-width);
- height: 100%;
- }
- }
-
- pre {
- margin-left: var(--code-ln-wrapper-width);
- padding-left: 1rem;
- vertical-align: middle;
- }
-
- .line-numbers {
- position: absolute;
- top: 0;
- width: var(--code-ln-wrapper-width);
- text-align: center;
- color: var(--code-ln-color);
- // padding-top: 1.09375rem;
- // padding-top: 1.25rem;
- padding-top: 1.25rem;
- line-height: 1.225;
- // line-height: 1.4;
-//225
-
- br {
- user-select: none;
- }
-
- .line-number {
- position: relative;
- z-index: 3;
- user-select: none;
- font-size: 0.85em;
- // font-size: 0.74375em;
- }
- }
-
- &::after {
- content: '';
- position: absolute;
- top: 0;
- left: 0;
- width: var(--code-ln-wrapper-width);
- height: 100%;
- border-radius: 6px 0 0 6px;
- border-right: 1px solid var(--code-hl-bg-color);
- }
- }
-}
-
-@each $lang in $codeLang {
- div[class*='language-'].ext-#{$lang} {
- &:before {
- content: '' + $lang;
- }
- }
-}
-
-// narrow mobile
-@media (max-width: $MQMobileNarrow) {
- .theme-default-content {
- div[class*='language-'] {
- margin: 0.85rem -1.5rem;
- border-radius: 0;
- }
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_demo.scss b/docs/.vuepress/theme-coreui/src/client/styles/_demo.scss
deleted file mode 100644
index f51a5c74..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/_demo.scss
+++ /dev/null
@@ -1,294 +0,0 @@
-
-.docs-example {
-
- + div[class*='language-'] {
- padding-top: 0;
- margin-top: 0;
- border-radius: 0 0 6px 6px;
- max-height: 500px;
- overflow: scroll;
-
- pre {
- margin-top: 0;
- }
- }
-}
-
-.docs-example-offcanvas .offcanvas {
- position: static;
- display: block;
- height: 200px;
- visibility: visible;
- transform: translate(0);
-}
-
-//
-// Grid examples
-//
-
-.docs-example-row {
- .row {
- > .col,
- > [class^="col-"] {
- padding-top: .75rem;
- padding-bottom: .75rem;
- background-color: rgba(39, 41, 43, .03);
- border: 1px solid rgba(39, 41, 43, .1);
- }
- }
-
- .row + .row {
- margin-top: 1rem;
- }
-}
-
-.docs-example-row-flex-cols .row {
- min-height: 10rem;
- background-color: rgba(255, 0, 0, .1);
-}
-
-.docs-example-cssgrid {
- text-align: center;
-
- .grid + .grid {
- margin-top: 1rem;
- }
-
- .grid > * {
- padding-top: .75rem;
- padding-bottom: .75rem;
- background-color: rgba(255, 0, 255, .1);
- border: 1px solid rgba(255, 0, 255, .25);
- }
-}
-
-// Grid mixins
-// .example-container {
-// width: 800px;
-// @include make-container();
-// }
-
-// .example-row {
-// @include make-row();
-// }
-
-// .example-content-main {
-// @include make-col-ready();
-
-// @include media-breakpoint-up(sm) {
-// @include make-col(6);
-// }
-
-// @include media-breakpoint-up(lg) {
-// @include make-col(8);
-// }
-// }
-
-// .example-content-secondary {
-// @include make-col-ready();
-
-// @include media-breakpoint-up(sm) {
-// @include make-col(6);
-// }
-
-// @include media-breakpoint-up(lg) {
-// @include make-col(4);
-// }
-// }
-
-
-//
-// Docs examples
-//
-
-.docs-example {
- // position: relative;
- // padding: 1rem;
- // margin: 1rem (-$grid-gutter-width * .5) 0;
- // border: solid $gray-200;
- // border-width: 1px 0 0;
- // @include clearfix();
-
- // @include media-breakpoint-up(sm) {
- // padding: 1.5rem;
- // margin-right: 0;
- // margin-left: 0;
- // border-width: 1px;
- // @include border-top-radius(.25rem);
-
- // + .docs-clipboard + .highlight {
- // @include border-bottom-radius(.25rem);
- // }
- // }
-
- + p {
- margin-top: 2rem;
- }
-
- > .form-control {
- + .form-control {
- margin-top: .5rem;
- }
- }
-
- > .nav + .nav,
- > .alert + .alert,
- > .navbar + .navbar,
- > .progress + .progress {
- margin-top: 1rem;
- }
-
- > .dropdown-menu {
- position: static;
- display: block;
- }
-
- > :last-child {
- margin-bottom: 0;
- }
-
- // Images
- > svg + svg,
- > img + img {
- margin-left: .5rem;
- }
-
- // Buttons
- > .btn,
- > .btn-group {
- margin: .25rem .125rem;
- }
- > .btn-toolbar + .btn-toolbar {
- margin-top: .5rem;
- }
-
- // List groups
- > .list-group {
- max-width: 400px;
- }
-
- > [class*="list-group-horizontal"] {
- max-width: 100%;
- }
-
- // Navbars
- .fixed-top,
- .sticky-top {
- position: static;
- margin: -1rem -1rem 1rem;
- }
-
- .fixed-bottom {
- position: static;
- margin: 1rem -1rem -1rem;
- }
-
- // @include media-breakpoint-up(sm) {
- // .fixed-top,
- // .sticky-top {
- // margin: -1.5rem -1.5rem 1rem;
- // }
- // .fixed-bottom {
- // margin: 1rem -1.5rem -1.5rem;
- // }
- // }
-
- // Pagination
- .pagination {
- margin-top: .5rem;
- margin-bottom: .5rem;
- }
-}
-
-// // Ratio helpers
-// .docs-example-ratios {
-// .ratio {
-// display: inline-block;
-// width: 10rem;
-// color: $gray-600;
-// background-color: $gray-100;
-// border: $border-width solid $border-color;
-
-// > div {
-// display: flex;
-// align-items: center;
-// justify-content: center;
-// }
-// }
-// }
-// .docs-example-ratios-breakpoint {
-// .ratio-4x3 {
-// width: 16rem;
-
-// // @include media-breakpoint-up(md) {
-// // aspect-ratio: 50%; // 2x1
-// // }
-// }
-// }
-
-.docs-example-modal {
- background-color: #fafafa;
-
- .modal {
- position: static;
- display: block;
- }
-}
-
-.docs-example-offcanvas {
- // @include border-start-radius(0);
-
- .offcanvas {
- position: static;
- display: block;
- height: 200px;
- visibility: visible;
- transform: translate(0);
- }
-}
-
-// Tooltips
-.tooltip-demo a {
- white-space: nowrap;
-}
-
-// Scrollspy demo on fixed height div
-.scrollspy-example {
- position: relative;
- height: 200px;
- margin-top: .5rem;
- overflow: auto;
-}
-
-.scrollspy-example-2 {
- position: relative;
- height: 350px;
- overflow: auto;
-}
-
-// .docs-example-position-utils {
-// position: relative;
-// padding: 3em;
-
-// .position-relative {
-// height: 200px;
-// background-color: #f5f5f5;
-// }
-
-// .position-absolute {
-// width: 2em;
-// height: 2em;
-// background-color: $dark;
-// }
-// }
-
-.docs-example-position-examples {
- &::after {
- content: none;
- }
-}
-
-// Toasts
-.docs-example-toasts {
- min-height: 240px;
-}
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_footer.scss b/docs/.vuepress/theme-coreui/src/client/styles/_footer.scss
deleted file mode 100644
index 22df3b8d..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/_footer.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-.docs-footer {
- --cui-footer-bg: #f0f4f7;
- font-size: 0.875rem;
-
- a {
- color: #768192;
- text-decoration: none;
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_sidebar.scss b/docs/.vuepress/theme-coreui/src/client/styles/_sidebar.scss
deleted file mode 100755
index faffdcd7..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/_sidebar.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.docs-sidebar {
- --cui-sidebar-bg: #f0f4f7;
- --cui-sidebar-brand-bg: transparent;
- --cui-sidebar-brand-color: rgba(44,56,74,0.87);
- --cui-sidebar-nav-link-color: rgba(44,56,74,0.87);
- --cui-sidebar-nav-link-active-color: #321fdb;
- --cui-sidebar-nav-link-hover-color: #321fdb;
- --cui-sidebar-nav-group-bg: transparent;
- --cui-sidebar-nav-group-toggle-show-color: #321fdb;
- --cui-sidebar-nav-link-disabled-color: #{$text-disabled};
-}
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_variables.scss b/docs/.vuepress/theme-coreui/src/client/styles/_variables.scss
deleted file mode 100755
index e3350532..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/_variables.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-@import '@vuepress/plugin-palette/palette';
-
-// responsive breakpoints
-$MQNarrow: 959px !default;
-$MQMobile: 719px !default;
-$MQMobileNarrow: 419px !default;
-
-// code languages
-$codeLang: 'c' 'cpp' 'cs' 'css' 'dart' 'docker' 'fs' 'go' 'html' 'java' 'js'
- 'json' 'kt' 'less' 'makefile' 'md' 'php' 'py' 'rb' 'rs' 'sass' 'scss' 'sh'
- 'styl' 'ts' 'toml' 'vue' 'yml' !default;
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/index.scss b/docs/.vuepress/theme-coreui/src/client/styles/index.scss
deleted file mode 100755
index 38936918..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/index.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-@import '@coreui/coreui/scss/coreui.scss';
-
-@import 'anchor';
-@import 'demo';
-@import 'footer';
-@import 'layout';
-@import 'sidebar';
-@import 'toc';
-
-@import 'vars';
-@import 'vars-dark';
-
-@import 'code';
-@import 'code-group';
-@import 'custom-container';
-@import 'page';
-@import 'transitions';
-
-@import '@vuepress/plugin-palette/style';
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/page.scss b/docs/.vuepress/theme-coreui/src/client/styles/page.scss
deleted file mode 100755
index da7cec05..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/page.scss
+++ /dev/null
@@ -1,65 +0,0 @@
-@import '_variables';
-
-.page {
- padding-bottom: 2rem;
- display: block;
-}
-
-.page-meta { padding-top: 1rem;
- padding-bottom: 1rem;
- overflow: auto;
-
- .meta-item {
- cursor: default;
- margin-top: 0.8rem;
-
- .meta-item-label {
- font-weight: 500;
- color: var(--c-text-lighter);
- }
-
- .meta-item-info {
- font-weight: 400;
- color: var(--c-text-quote);
- }
- }
-
- .edit-link {
- display: inline-block;
- margin-right: 0.25rem;
- }
-
- .last-updated {
- float: right;
- }
-}
-
-@media (max-width: $MQMobile) {
- .page-meta {
- .last-updated {
- font-size: 0.8em;
- float: none;
- }
-
- .contributors {
- font-size: 0.8em;
- }
- }
-}
-
-.page-nav {
- padding-top: 1rem;
- padding-bottom: 0;
-
- .inner {
- min-height: 2rem;
- margin-top: 0;
- border-top: 1px solid var(--c-border);
- padding-top: 1rem;
- overflow: auto;
- }
-
- .next {
- float: right;
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/transitions.scss b/docs/.vuepress/theme-coreui/src/client/styles/transitions.scss
deleted file mode 100755
index fda62674..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/transitions.scss
+++ /dev/null
@@ -1,13 +0,0 @@
-.fade-slide-y-enter-active {
- transition: all 0.3s ease;
-}
-
-.fade-slide-y-leave-active {
- transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
-}
-
-.fade-slide-y-enter-from,
-.fade-slide-y-leave-to {
- transform: translateY(10px);
- opacity: 0;
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/vars-dark.scss b/docs/.vuepress/theme-coreui/src/client/styles/vars-dark.scss
deleted file mode 100755
index 58e02fc5..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/vars-dark.scss
+++ /dev/null
@@ -1,46 +0,0 @@
-html.dark {
- // brand colors
- --c-brand: #3aa675;
- --c-brand-light: #349469;
-
- // background colors
- --c-bg: #22272e;
- --c-bg-light: #2b313a;
- --c-bg-lighter: #262c34;
-
- // text colors
- --c-text: #adbac7;
- --c-text-light: #96a7b7;
- --c-text-lighter: #8b9eb0;
- --c-text-lightest: #8094a8;
-
- // border colors
- --c-border: #3e4c5a;
- --c-border-dark: #34404c;
-
- // custom container colors
- --c-tip: #318a62;
- --c-warning: #ceab00;
- --c-warning-bg: #7e755b;
- --c-warning-title: #ceac03;
- --c-warning-text: #362e00;
- --c-danger: #940000;
- --c-danger-bg: #806161;
- --c-danger-title: #610000;
- --c-danger-text: #3a0000;
- --c-details-bg: #323843;
-
- // code blocks vars
- --code-hl-bg-color: #363b46;
-}
-
-// plugin-docsearch
-html.dark .DocSearch {
- --docsearch-logo-color: var(--c-text);
- --docsearch-modal-shadow: inset 1px 1px 0 0 #2c2e40, 0 3px 8px 0 #000309;
- --docsearch-key-shadow: inset 0 -2px 0 0 #282d55, inset 0 0 1px 1px #51577d,
- 0 2px 2px 0 rgba(3, 4, 9, 0.3);
- --docsearch-key-gradient: linear-gradient(-225deg, #444950, #1c1e21);
- --docsearch-footer-shadow: inset 0 1px 0 0 rgba(73, 76, 106, 0.5),
- 0 -4px 8px 0 rgba(0, 0, 0, 0.2);
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/vars.scss b/docs/.vuepress/theme-coreui/src/client/styles/vars.scss
deleted file mode 100755
index 5e791a43..00000000
--- a/docs/.vuepress/theme-coreui/src/client/styles/vars.scss
+++ /dev/null
@@ -1,124 +0,0 @@
-:root {
- // brand colors
- --c-brand: #3eaf7c;
- --c-brand-light: #4abf8a;
-
- // background colors
- --c-bg: #ffffff;
- --c-bg-light: #f3f4f5;
- --c-bg-lighter: #eeeeee;
- --c-bg-navbar: var(--c-bg);
- --c-bg-sidebar: var(--c-bg);
- --c-bg-arrow: #cccccc;
-
- // text colors
- --c-text: #2c3e50;
- --c-text-accent: var(--c-brand);
- --c-text-light: #3a5169;
- --c-text-lighter: #4e6e8e;
- --c-text-lightest: #6a8bad;
- --c-text-quote: #999999;
-
- // border colors
- --c-border: #eaecef;
- --c-border-dark: #dfe2e5;
-
- // custom container colors
- --c-tip: #42b983;
- --c-tip-bg: var(--c-bg-light);
- --c-tip-title: var(--c-text);
- --c-tip-text: var(--c-text);
- --c-tip-text-accent: var(--c-text-accent);
- --c-warning: #e7c000;
- --c-warning-bg: #fffae3;
- --c-warning-title: #ad9000;
- --c-warning-text: #746000;
- --c-warning-text-accent: var(--c-text);
- --c-danger: #cc0000;
- --c-danger-bg: #ffe0e0;
- --c-danger-title: #990000;
- --c-danger-text: #660000;
- --c-danger-text-accent: var(--c-text);
- --c-details-bg: #eeeeee;
-
- // badge component colors
- --c-badge-tip: var(--c-tip);
- --c-badge-warning: var(--c-warning);
- --c-badge-danger: var(--c-danger);
-
- // code blocks vars
- --code-bg-color: #282c34;
- --code-hl-bg-color: rgba(0, 0, 0, 0.66);
- --code-ln-color: #9e9e9e;
- --code-ln-wrapper-width: 3.5rem;
-
- // font vars
- --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen,
- Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
- --font-family-code: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
-
- // layout vars
- --navbar-height: 3.6rem;
- --navbar-padding-v: 0.7rem;
- --navbar-padding-h: 1.5rem;
- --sidebar-width: 20rem;
- --sidebar-width-mobile: calc(var(--sidebar-width) * 0.82);
- --content-width: 960px;
- --homepage-width: 960px;
-}
-
-// plugin-back-to-top
-.back-to-top {
- --back-to-top-color: var(--c-brand);
- --back-to-top-color-hover: var(--c-brand-light);
-}
-
-// plugin-docsearch
-.DocSearch {
- --docsearch-primary-color: var(--c-brand);
- --docsearch-text-color: var(--c-text);
- --docsearch-highlight-color: var(--c-brand);
- --docsearch-muted-color: var(--c-text-quote);
- --docsearch-container-background: rgba(9, 10, 17, 0.8);
- --docsearch-modal-background: var(--c-bg-light);
- --docsearch-searchbox-background: var(--c-bg-lighter);
- --docsearch-searchbox-focus-background: var(--c-bg);
- --docsearch-searchbox-shadow: inset 0 0 0 2px var(--c-brand);
- --docsearch-hit-color: var(--c-text-light);
- --docsearch-hit-active-color: var(--c-bg);
- --docsearch-hit-background: var(--c-bg);
- --docsearch-hit-shadow: 0 1px 3px 0 var(--c-border-dark);
- --docsearch-footer-background: var(--c-bg);
-}
-
-// plugin-medium-zoom
-.medium-zoom-overlay {
- --medium-zoom-bg-color: var(--c-bg);
-}
-
-// plugin-nprogress
-#nprogress {
- --nprogress-color: var(--c-brand);
-}
-
-// plugin-pwa-popup
-.pwa-popup {
- --pwa-popup-text-color: var(--c-text);
- --pwa-popup-bg-color: var(--c-bg);
- --pwa-popup-border-color: var(--c-brand);
- --pwa-popup-shadow: 0 4px 16px var(--c-brand);
- --pwa-popup-btn-text-color: var(--c-bg);
- --pwa-popup-btn-bg-color: var(--c-brand);
- --pwa-popup-btn-hover-bg-color: var(--c-brand-light);
-}
-
-// plugin-search
-.search-box {
- --search-bg-color: var(--c-bg);
- --search-accent-color: var(--c-brand);
- --search-text-color: var(--c-text);
- --search-border-color: var(--c-border);
-
- --search-item-text-color: var(--c-text-lighter);
- --search-item-focus-bg-color: var(--c-bg-light);
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/utils/index.ts b/docs/.vuepress/theme-coreui/src/client/utils/index.ts
deleted file mode 100755
index 93f94a89..00000000
--- a/docs/.vuepress/theme-coreui/src/client/utils/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './resolveEditLink'
-export * from './resolveRepoType'
diff --git a/docs/.vuepress/theme-coreui/src/client/utils/resolveEditLink.ts b/docs/.vuepress/theme-coreui/src/client/utils/resolveEditLink.ts
deleted file mode 100755
index 58381d4b..00000000
--- a/docs/.vuepress/theme-coreui/src/client/utils/resolveEditLink.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import {
- isLinkHttp,
- removeLeadingSlash,
- removeEndingSlash,
-} from '@vuepress/shared'
-import { resolveRepoType } from './resolveRepoType'
-import type { RepoType } from './resolveRepoType'
-
-export const editLinkPatterns: Record, string> = {
- GitHub: ':repo/edit/:branch/:path',
- GitLab: ':repo/-/edit/:branch/:path',
- Gitee: ':repo/edit/:branch/:path',
- Bitbucket:
- ':repo/src/:branch/:path?mode=edit&spa=0&at=:branch&fileviewer=file-view-default',
-}
-
-export const resolveEditLink = ({
- docsRepo,
- docsBranch,
- docsDir,
- filePathRelative,
- editLinkPattern,
-}: {
- docsRepo: string
- docsBranch: string
- docsDir: string
- filePathRelative: string
- editLinkPattern?: string
-}): string | null => {
- const repoType = resolveRepoType(docsRepo)
-
- let pattern: string | undefined
-
- if (editLinkPattern) {
- pattern = editLinkPattern
- } else if (repoType !== null) {
- pattern = editLinkPatterns[repoType]
- }
-
- if (!pattern) return null
-
- return pattern
- .replace(
- /:repo/,
- isLinkHttp(docsRepo) ? docsRepo : `https://github.com/${docsRepo}`
- )
- .replace(/:branch/, docsBranch)
- .replace(
- /:path/,
- removeLeadingSlash(`${removeEndingSlash(docsDir)}/${filePathRelative}`)
- )
-}
diff --git a/docs/.vuepress/theme-coreui/src/client/utils/resolveRepoType.ts b/docs/.vuepress/theme-coreui/src/client/utils/resolveRepoType.ts
deleted file mode 100755
index c63b5d22..00000000
--- a/docs/.vuepress/theme-coreui/src/client/utils/resolveRepoType.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { isLinkHttp } from '@vuepress/shared'
-
-export type RepoType = 'GitHub' | 'GitLab' | 'Gitee' | 'Bitbucket' | null
-
-export const resolveRepoType = (repo: string): RepoType => {
- if (!isLinkHttp(repo) || /github\.com/.test(repo)) return 'GitHub'
- if (/bitbucket\.org/.test(repo)) return 'Bitbucket'
- if (/gitlab\.com/.test(repo)) return 'GitLab'
- if (/gitee\.com/.test(repo)) return 'Gitee'
- return null
-}
diff --git a/docs/.vuepress/theme-coreui/src/node/defaultTheme.ts b/docs/.vuepress/theme-coreui/src/node/defaultTheme.ts
deleted file mode 100755
index 004caec3..00000000
--- a/docs/.vuepress/theme-coreui/src/node/defaultTheme.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import type { Theme, ThemeConfig } from '@vuepress/core'
-import { path } from '@vuepress/utils'
-import type { DefaultThemeLocaleOptions, DefaultThemePluginsOptions } from '../shared'
-import {
- assignDefaultLocaleOptions,
- // resolveActiveHeaderLinksPluginOptions,
- // resolveContainerPluginOptions,
- // resolveContainerPluginOptionsForDetails,
- // resolveContainerPluginOptionsForCodeGroup,
- // resolveContainerPluginOptionsForCodeGroupItem,
- resolveGitPluginOptions,
- // resolveMediumZoomPluginOptions,
-} from './utils'
-
-export interface DefaultThemeOptions extends ThemeConfig, DefaultThemeLocaleOptions {
- /**
- * To avoid confusion with the root `plugins` option,
- * we use `themePlugins`
- */
- themePlugins?: DefaultThemePluginsOptions
-}
-
-export const defaultTheme: Theme = ({
- themePlugins = {},
- ...localeOptions
-}) => {
- assignDefaultLocaleOptions(localeOptions)
-
- return {
- name: '@vuepress/theme-default',
-
- layouts: path.resolve(__dirname, '../client/layouts'),
-
- clientAppEnhanceFiles: path.resolve(__dirname, '../client/clientAppEnhance.ts'),
-
- clientAppSetupFiles: path.resolve(__dirname, '../client/clientAppSetup.ts'),
-
- // use the relative file path to generate edit link
- extendsPageData: ({ filePathRelative }) => ({ filePathRelative }),
-
- plugins: [
- [
- '@vuepress/active-header-links',
- {
- headerLinkSelector: 'a.sidebar-item',
- headerAnchorSelector: '.anchor-link',
- },
- ],
- ['@vuepress/back-to-top', themePlugins.backToTop !== false],
- // ['@vuepress/container', resolveContainerPluginOptions(themePlugins, localeOptions, 'tip')],
- // [
- // '@vuepress/container',
- // resolveContainerPluginOptions(themePlugins, localeOptions, 'warning'),
- // ],
- // ['@vuepress/container', resolveContainerPluginOptions(themePlugins, localeOptions, 'danger')],
- // ['@vuepress/container', resolveContainerPluginOptionsForDetails(themePlugins)],
- // ['@vuepress/container', resolveContainerPluginOptionsForCodeGroup(themePlugins)],
- // ['@vuepress/container', resolveContainerPluginOptionsForCodeGroupItem(themePlugins)],
- ['@vuepress/git', resolveGitPluginOptions(themePlugins, localeOptions)],
- // ['@vuepress/medium-zoom', resolveMediumZoomPluginOptions(themePlugins)],
- // ['@vuepress/nprogress', themePlugins.nprogress !== false],
- ['@vuepress/palette', { preset: 'sass' }],
- ['@vuepress/prismjs', themePlugins.prismjs !== false],
- ['@vuepress/theme-data', { themeData: localeOptions }],
- ],
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/node/utils/index.ts b/docs/.vuepress/theme-coreui/src/node/utils/index.ts
deleted file mode 100755
index 17cd5b4e..00000000
--- a/docs/.vuepress/theme-coreui/src/node/utils/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export * from './assignDefaultLocaleOptions'
-export * from './resolveActiveHeaderLinksPluginOptions'
-export * from './resolveContainerPluginOptions'
-export * from './resolveGitPluginOptions'
-export * from './resolveMediumZoomPluginOptions'
diff --git a/docs/.vuepress/theme-coreui/src/node/utils/resolveActiveHeaderLinksPluginOptions.ts b/docs/.vuepress/theme-coreui/src/node/utils/resolveActiveHeaderLinksPluginOptions.ts
deleted file mode 100755
index ed52e8f9..00000000
--- a/docs/.vuepress/theme-coreui/src/node/utils/resolveActiveHeaderLinksPluginOptions.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import type { ActiveHeaderLinksPluginOptions } from '@vuepress/plugin-active-header-links'
-import type { DefaultThemePluginsOptions } from '../../shared'
-
-/**
- * Resolve options for @vuepress/plugin-active-header-links
- */
-export const resolveActiveHeaderLinksPluginOptions = (
- themePlugins: DefaultThemePluginsOptions
-): ActiveHeaderLinksPluginOptions | boolean => {
- if (themePlugins?.activeHeaderLinks === false) {
- return false
- }
-
- return {
- headerLinkSelector: 'a.sidebar-item',
- headerAnchorSelector: '.anchor-link',
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/node/utils/resolveContainerPluginOptions.ts b/docs/.vuepress/theme-coreui/src/node/utils/resolveContainerPluginOptions.ts
deleted file mode 100755
index 5d6ec139..00000000
--- a/docs/.vuepress/theme-coreui/src/node/utils/resolveContainerPluginOptions.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import type { ContainerPluginOptions } from '@vuepress/plugin-container'
-import type { DefaultThemePluginsOptions, DefaultThemeData } from '../../shared'
-
-/**
- * Resolve options for @vuepress/plugin-container
- *
- * For custom containers default title
- */
-export const resolveContainerPluginOptions = (
- themePlugins: DefaultThemePluginsOptions,
- localeOptions: DefaultThemeData,
- type: 'tip' | 'warning' | 'danger'
-): ContainerPluginOptions | boolean => {
- if (themePlugins?.container?.[type] === false) {
- return false
- }
-
- const locales = Object.entries(localeOptions.locales || {}).reduce(
- (result, [key, value]) => {
- result[key] = {
- defaultInfo: value?.[type] ?? localeOptions[type],
- }
- return result
- },
- {}
- )
-
- return {
- type,
- locales,
- }
-}
-
-/**
- * Resolve options for @vuepress/plugin-container
- *
- * For details container
- */
-export const resolveContainerPluginOptionsForDetails = (
- themePlugins: DefaultThemePluginsOptions
-): ContainerPluginOptions | boolean => {
- if (themePlugins?.container?.details === false) {
- return false
- }
-
- return {
- type: 'details',
- before: (info) =>
- `${
- info ? `${info} ` : ''
- }\n`,
- after: () => ' \n',
- }
-}
-
-/**
- * Resolve options for @vuepress/plugin-container
- *
- * For code-group container
- */
-export const resolveContainerPluginOptionsForCodeGroup = (
- themePlugins: DefaultThemePluginsOptions
-): ContainerPluginOptions | boolean => {
- if (themePlugins?.container?.codeGroup === false) {
- return false
- }
-
- return {
- type: 'code-group',
- before: () => `\n`,
- after: () => ' \n',
- }
-}
-
-/**
- * Resolve options for @vuepress/plugin-container
- *
- * For code-group-item block
- */
-export const resolveContainerPluginOptionsForCodeGroupItem = (
- themePlugins: DefaultThemePluginsOptions
-): ContainerPluginOptions | boolean => {
- if (themePlugins?.container?.codeGroupItem === false) {
- return false
- }
-
- return {
- type: 'code-group-item',
- before: (info) => `\n`,
- after: () => ' \n',
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/node/utils/resolveGitPluginOptions.ts b/docs/.vuepress/theme-coreui/src/node/utils/resolveGitPluginOptions.ts
deleted file mode 100755
index a7348e3c..00000000
--- a/docs/.vuepress/theme-coreui/src/node/utils/resolveGitPluginOptions.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-import type { GitPluginOptions } from '@vuepress/plugin-git'
-import type {
- DefaultThemePluginsOptions,
- DefaultThemeLocaleOptions,
-} from '../../shared'
-
-/**
- * Resolve options for @vuepress/plugin-git
- */
-export const resolveGitPluginOptions = (
- themePlugins: DefaultThemePluginsOptions,
- localeOptions: DefaultThemeLocaleOptions
-): GitPluginOptions | boolean => {
- if (themePlugins?.git === false) {
- return false
- }
-
- const enableUpdatedTime = localeOptions.lastUpdated !== false
- const enableContributors = localeOptions.contributors !== false
-
- if (!enableUpdatedTime && !enableContributors) {
- return false
- }
-
- return {
- createdTime: false,
- updatedTime: enableUpdatedTime,
- contributors: enableContributors,
- }
-}
diff --git a/docs/.vuepress/theme-coreui/src/node/utils/resolveMediumZoomPluginOptions.ts b/docs/.vuepress/theme-coreui/src/node/utils/resolveMediumZoomPluginOptions.ts
deleted file mode 100755
index e8fe2e35..00000000
--- a/docs/.vuepress/theme-coreui/src/node/utils/resolveMediumZoomPluginOptions.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import type { MediumZoomPluginOptions } from '@vuepress/plugin-medium-zoom'
-import type { DefaultThemePluginsOptions } from '../../shared'
-
-/**
- * Resolve options for @vuepress/plugin-medium-zoom
- */
-export const resolveMediumZoomPluginOptions = (
- themePlugins: DefaultThemePluginsOptions
-): MediumZoomPluginOptions | boolean => {
- if (themePlugins?.mediumZoom === false) {
- return false
- }
-
- return {
- selector:
- '.theme-default-content > img, .theme-default-content :not(a) > img',
- zoomOptions: {},
- // should greater than page transition duration
- delay: 400,
- }
-}
diff --git a/docs/api/accordion/CAccordion.api.md b/docs/api/accordion/CAccordion.api.md
deleted file mode 100644
index a05d6d91..00000000
--- a/docs/api/accordion/CAccordion.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CAccordion
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
-| flush
| Removes the default background-color, some borders, and some rounded corners to render accordions edge-to-edge with their parent container. | boolean | - | |
-
----
diff --git a/docs/api/accordion/CAccordionBody.api.md b/docs/api/accordion/CAccordionBody.api.md
deleted file mode 100644
index 8667f3a9..00000000
--- a/docs/api/accordion/CAccordionBody.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CAccordionBody
-
----
diff --git a/docs/api/accordion/CAccordionButton.api.md b/docs/api/accordion/CAccordionButton.api.md
deleted file mode 100644
index bbccd198..00000000
--- a/docs/api/accordion/CAccordionButton.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CAccordionButton
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------ | ------- | ------ | ------- |
-| collapsed
| Set button state to collapsed. | boolean | - | |
-
----
diff --git a/docs/api/accordion/CAccordionCollapse.api.md b/docs/api/accordion/CAccordionCollapse.api.md
deleted file mode 100644
index 374f234c..00000000
--- a/docs/api/accordion/CAccordionCollapse.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CAccordionCollapse
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | ----------------------------------- | ------- | ------ | ------- |
-| visible
| Toggle the visibility of component. | boolean | - | |
-
----
diff --git a/docs/api/accordion/CAccordionHeader.api.md b/docs/api/accordion/CAccordionHeader.api.md
deleted file mode 100644
index e18cdc11..00000000
--- a/docs/api/accordion/CAccordionHeader.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CAccordionHeader
-
----
diff --git a/docs/api/accordion/CAccordionItem.api.md b/docs/api/accordion/CAccordionItem.api.md
deleted file mode 100644
index 5c8716de..00000000
--- a/docs/api/accordion/CAccordionItem.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CAccordionItem
-
----
diff --git a/docs/api/alert/CAlert.api.md b/docs/api/alert/CAlert.api.md
deleted file mode 100644
index a98e368c..00000000
--- a/docs/api/alert/CAlert.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### CAlert
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------------ | ------------------------------------------------------------------------- | ------- | ------ | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | - | |
-| dismissible
| Optionally add a close button to alert and allow it to self dismisss. | boolean | - | false |
-| variant
| Set the alert variant to a solid. | string | - | undefined |
-| visible
| Toggle the visibility of alert component. | boolean | - | true |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------- | ---------- | ------------------------------------------------------- |
-| dismiss
| | Event called before the dissmiss animation has started. |
-
----
diff --git a/docs/api/alert/CAlertHeading.api.md b/docs/api/alert/CAlertHeading.api.md
deleted file mode 100644
index de0c24c0..00000000
--- a/docs/api/alert/CAlertHeading.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CAlertHeading
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h4' |
-
----
diff --git a/docs/api/alert/CAlertLink.api.md b/docs/api/alert/CAlertLink.api.md
deleted file mode 100644
index e987a019..00000000
--- a/docs/api/alert/CAlertLink.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CAlertLink
-
----
diff --git a/docs/api/avatar/CAvatar.api.md b/docs/api/avatar/CAvatar.api.md
deleted file mode 100644
index ec1a0bec..00000000
--- a/docs/api/avatar/CAvatar.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CAvatar
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------ | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. `@type` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string | Color | - | |
-| shape
| Select the shape of the component. `@type` 'rounded' \| 'rounded-top' \| 'rounded-end' \| 'rounded-bottom' \| 'rounded-start' \| 'rounded-circle' \| 'rounded-pill' \| 'rounded-0' \| 'rounded-1' \| 'rounded-2' \| 'rounded-3' \| string | Shape | - | |
-| size
| Size the component small, large, or extra large. | string | - | undefined |
-| src
| The src attribute for the img element. | string | - | undefined |
-| status
| Sets the color context of the status indicator to one of CoreUI’s themed colors. `@type` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string | string | - | undefined |
-| textColor
| Sets the text color of the component to one of CoreUI’s themed colors. `@value` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| 'white' \| 'muted' \| string | TextColor | - | |
-
----
diff --git a/docs/api/backdrop/CBackdrop.api.md b/docs/api/backdrop/CBackdrop.api.md
deleted file mode 100644
index 60cb6b6f..00000000
--- a/docs/api/backdrop/CBackdrop.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CBackdrop
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | ----------------------------------------- | ------- | ------ | ------- |
-| visible
| Toggle the visibility of modal component. | boolean | - | false |
-
----
diff --git a/docs/api/badge/CBadge.api.md b/docs/api/badge/CBadge.api.md
deleted file mode 100644
index 16ec609a..00000000
--- a/docs/api/badge/CBadge.api.md
+++ /dev/null
@@ -1,13 +0,0 @@
-### CBadge
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------ | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. `@type` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' | Color | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'span' | string | - | 'span' |
-| shape
| Select the shape of the component. `@type` 'rounded' \| 'rounded-top' \| 'rounded-end' \| 'rounded-bottom' \| 'rounded-start' \| 'rounded-circle' \| 'rounded-pill' \| 'rounded-0' \| 'rounded-1' \| 'rounded-2' \| 'rounded-3' \| string | Shape | - | |
-| size
| Size the component small. `@type` 'sm' | string | - | undefined |
-| textColor
| Sets the text color of the component to one of CoreUI’s themed colors. `@value` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| 'white' \| 'muted' \| string | TextColor | - | |
-
----
diff --git a/docs/api/breadcrumb/CBreadcrumb.api.md b/docs/api/breadcrumb/CBreadcrumb.api.md
deleted file mode 100644
index 751ce9e7..00000000
--- a/docs/api/breadcrumb/CBreadcrumb.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CBreadcrumb
-
----
diff --git a/docs/api/breadcrumb/CBreadcrumbItem.api.md b/docs/api/breadcrumb/CBreadcrumbItem.api.md
deleted file mode 100644
index 699070c0..00000000
--- a/docs/api/breadcrumb/CBreadcrumbItem.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CBreadcrumbItem
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------- | -------------------------------------------------- | ------- | ------ | --------- |
-| active
| Toggle the active state for the component. | boolean | - | |
-| href
| The `href` attribute for the inner link component. | string | - | undefined |
-
----
diff --git a/docs/api/button-group/CButtonGroup.api.md b/docs/api/button-group/CButtonGroup.api.md
deleted file mode 100644
index f409f6a1..00000000
--- a/docs/api/button-group/CButtonGroup.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CButtonGroup
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------- | ---------- | --------- |
-| size
| Size the component small or large. `@type` undefined | string | `sm`, `lg` | undefined |
-| vertical
| Create a set of buttons that appear vertically stacked rather than horizontally. Split button dropdowns are not supported here. | boolean | - | |
-
----
diff --git a/docs/api/button-group/CButtonToolbar.api.md b/docs/api/button-group/CButtonToolbar.api.md
deleted file mode 100644
index 49f4ebdc..00000000
--- a/docs/api/button-group/CButtonToolbar.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CButtonToolbar
-
----
diff --git a/docs/api/button/CButton.api.md b/docs/api/button/CButton.api.md
deleted file mode 100644
index 456bec28..00000000
--- a/docs/api/button/CButton.api.md
+++ /dev/null
@@ -1,16 +0,0 @@
-### CButton
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| active
| Toggle the active state for the component. | boolean | - | false |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'button' |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| href
| The href attribute specifies the URL of the page the link goes to. | string | - | undefined |
-| shape
| Select the shape of the component. | Shape | - | |
-| size
| Size the component small or large. | string | - | undefined |
-| variant
| Set the button variant to an outlined button or a ghost button. | string | - | undefined |
-
----
diff --git a/docs/api/callout/CCallout.api.md b/docs/api/callout/CCallout.api.md
deleted file mode 100644
index e7ecafcb..00000000
--- a/docs/api/callout/CCallout.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCallout
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- | ------ | ------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. `@type` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string | Color | - | |
-
----
diff --git a/docs/api/card/CCard.api.md b/docs/api/card/CCard.api.md
deleted file mode 100644
index b0a3a21f..00000000
--- a/docs/api/card/CCard.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CCard
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | ------ | ------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. `@type` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string | Color | - | |
-| textColor
| Sets the text color context of the component to one of CoreUI’s themed colors. `@type` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| 'white' \| 'muted' \| string | TextColor | - | |
-
----
diff --git a/docs/api/card/CCardBody.api.md b/docs/api/card/CCardBody.api.md
deleted file mode 100644
index dc997b0e..00000000
--- a/docs/api/card/CCardBody.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CCardBody
-
----
diff --git a/docs/api/card/CCardFooter.api.md b/docs/api/card/CCardFooter.api.md
deleted file mode 100644
index c4b049d8..00000000
--- a/docs/api/card/CCardFooter.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CCardFooter
-
----
diff --git a/docs/api/card/CCardGroup.api.md b/docs/api/card/CCardGroup.api.md
deleted file mode 100644
index 0870a2d3..00000000
--- a/docs/api/card/CCardGroup.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CCardGroup
-
----
diff --git a/docs/api/card/CCardHeader.api.md b/docs/api/card/CCardHeader.api.md
deleted file mode 100644
index 69660d8f..00000000
--- a/docs/api/card/CCardHeader.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCardHeader
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------------------------------------------------------------------------------------ | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'div' | string | - | 'div' |
-
----
diff --git a/docs/api/card/CCardImage.api.md b/docs/api/card/CCardImage.api.md
deleted file mode 100644
index 29b661a6..00000000
--- a/docs/api/card/CCardImage.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CCardImage
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------------ | ------------------------------------------------------------------------------------------------------------ | ------ | ------ | --------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'img' | string | - | 'img' |
-| orientation
| Optionally orientate the image to the top, bottom, or make it overlaid across the card. | string | - | undefined |
-
----
diff --git a/docs/api/card/CCardImageOverlay.api.md b/docs/api/card/CCardImageOverlay.api.md
deleted file mode 100644
index 7956c445..00000000
--- a/docs/api/card/CCardImageOverlay.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CCardImageOverlay
-
----
diff --git a/docs/api/card/CCardLink.api.md b/docs/api/card/CCardLink.api.md
deleted file mode 100644
index 8896f75a..00000000
--- a/docs/api/card/CCardLink.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCardLink
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ----------------- | ------------------------------------------------------------------ | ------ | ------ | ------- |
-| href
| The href attribute specifies the URL of the page the link goes to. | string | - | '#' |
-
----
diff --git a/docs/api/card/CCardSubtitle.api.md b/docs/api/card/CCardSubtitle.api.md
deleted file mode 100644
index f8a1f109..00000000
--- a/docs/api/card/CCardSubtitle.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCardSubtitle
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'h6' | string | - | 'h6' |
-
----
diff --git a/docs/api/card/CCardText.api.md b/docs/api/card/CCardText.api.md
deleted file mode 100644
index 3ef7d6bf..00000000
--- a/docs/api/card/CCardText.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCardText
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'p' | string | - | 'p' |
-
----
diff --git a/docs/api/card/CCardTitle.api.md b/docs/api/card/CCardTitle.api.md
deleted file mode 100644
index 3f3ced61..00000000
--- a/docs/api/card/CCardTitle.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCardTitle
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'h5' | string | - | 'h5' |
-
----
diff --git a/docs/api/carousel/CCarousel.api.md b/docs/api/carousel/CCarousel.api.md
deleted file mode 100644
index 56600823..00000000
--- a/docs/api/carousel/CCarousel.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CCarousel
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ----------------------- | ------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------------ | ------- |
-| controls
| Adding in the previous and next controls. | boolean | - | |
-| dark
| Add darker controls, indicators, and captions. | boolean | - | |
-| index
| index of the active item. `@default` 0 | number | - | 0 |
-| indicators
| Adding indicators at the bottom of the carousel for each item. | boolean | - | |
-| interval
| The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle. | boolean\|number | - | 5000 |
-| transition
| Adding indicators at the bottom of the carousel for each item. `@default` 'slide' | string | `'crossfade'`, `'slide'` | 'slide' |
-
----
diff --git a/docs/api/carousel/CCarouselCaption.api.md b/docs/api/carousel/CCarouselCaption.api.md
deleted file mode 100644
index 4b0f72bc..00000000
--- a/docs/api/carousel/CCarouselCaption.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CCarouselCaption
-
----
diff --git a/docs/api/carousel/CCarouselItem.api.md b/docs/api/carousel/CCarouselItem.api.md
deleted file mode 100644
index d85e4646..00000000
--- a/docs/api/carousel/CCarouselItem.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CCarouselItem
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------- | ------- | ------ | ------- |
-| active
| | boolean | - | false |
-| direction
| | string | - | 'next' |
-
----
diff --git a/docs/api/close-button/CCloseButton.api.md b/docs/api/close-button/CCloseButton.api.md
deleted file mode 100644
index 1ca0d9b3..00000000
--- a/docs/api/close-button/CCloseButton.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CCloseButton
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | -------------------------------------------- | ------- | ------ | ------- |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| white
| Change the default color to white. | boolean | - | |
-
----
diff --git a/docs/api/collapse/CCollapse.api.md b/docs/api/collapse/CCollapse.api.md
deleted file mode 100644
index 99717daa..00000000
--- a/docs/api/collapse/CCollapse.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CCollapse
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | ----------------------------------- | ------- | ------ | ------- |
-| visible
| Toggle the visibility of component. | boolean | - | |
-
----
diff --git a/docs/api/dropdown/CDropdown.api.md b/docs/api/dropdown/CDropdown.api.md
deleted file mode 100644
index 1dad8ac2..00000000
--- a/docs/api/dropdown/CDropdown.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### CDropdown
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
-| alignment
| | string\|object | `{ 'start' \| 'end' \| { xs: 'start' \| 'end' } \| { sm: 'start' \| 'end' } \| { md: 'start' \| 'end' } \| { lg: 'start' \| 'end' } \| { xl: 'start' \| 'end'} \| { xxl: 'start' \| 'end'} }` | undefined |
-| caret
| Enables pseudo element caret on toggler. `@default` true | boolean | - | true |
-| dark
| Sets a darker color scheme to match a dark navbar. | boolean | - | |
-| direction
| Sets a specified direction and location of the dropdown menu. | string | `'dropup' \| 'dropend' \| 'dropstart'` | undefined |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| placement
| Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. `@default` 'bottom-start' | Placement | `'auto' \| 'top-end' \| 'top' \| 'top-start' \| 'bottom-end' \| 'bottom' \| 'bottom-start' \| 'right-start' \| 'right' \| 'right-end' \| 'left-start' \| 'left' \| 'left-end'` | 'bottom-start' |
-| popper
| If you want to disable dynamic positioning set this property to `true`. | boolean | - | true |
-| trigger
| Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | string\|array | - | 'click' |
-| variant
| Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item. | string | - | 'btn-group' |
-| visible
| Toggle the visibility of dropdown menu component. `@default` false | boolean | - | |
-
----
diff --git a/docs/api/dropdown/CDropdownDivider.api.md b/docs/api/dropdown/CDropdownDivider.api.md
deleted file mode 100644
index 495f86b8..00000000
--- a/docs/api/dropdown/CDropdownDivider.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CDropdownDivider
-
----
diff --git a/docs/api/dropdown/CDropdownHeader.api.md b/docs/api/dropdown/CDropdownHeader.api.md
deleted file mode 100644
index 9bda76c2..00000000
--- a/docs/api/dropdown/CDropdownHeader.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CDropdownHeader
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'h6' | string | - | 'h6' |
-
----
diff --git a/docs/api/dropdown/CDropdownItem.api.md b/docs/api/dropdown/CDropdownItem.api.md
deleted file mode 100644
index 62c21a35..00000000
--- a/docs/api/dropdown/CDropdownItem.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CDropdownItem
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| active
| Toggle the active state for the component. | boolean | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| href
| The href attribute specifies the URL of the page the link goes to. | string | - | undefined |
-
----
diff --git a/docs/api/dropdown/CDropdownMenu.api.md b/docs/api/dropdown/CDropdownMenu.api.md
deleted file mode 100644
index 725e7508..00000000
--- a/docs/api/dropdown/CDropdownMenu.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CDropdownMenu
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------ | --------------- | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | `'div'`, `'ul'` | 'div' |
-
----
diff --git a/docs/api/dropdown/CDropdownToggle.api.md b/docs/api/dropdown/CDropdownToggle.api.md
deleted file mode 100644
index f65c33ac..00000000
--- a/docs/api/dropdown/CDropdownToggle.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### CDropdownToggle
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | --------- |
-| active
| Toggle the active state for the component. | boolean | - | false |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | |
-| caret
| Enables pseudo element caret on toggler. `@default` true | boolean | - | true |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'button' |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| shape
| Select the shape of the component. | Shape | - | |
-| size
| Size the component small or large. | string | - | undefined |
-| split
| Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` className for proper spacing around the dropdown caret. | boolean | - | |
-| variant
| Set the button variant to an outlined button or a ghost button. | string | - | undefined |
-| togglerVariant
| | string | - | undefined |
-
----
diff --git a/docs/api/footer/CFooter.api.md b/docs/api/footer/CFooter.api.md
deleted file mode 100644
index 276cc21a..00000000
--- a/docs/api/footer/CFooter.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CFooter
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ------------------------------------- | ------ | ------ | --------- |
-| position
| Place footer in non-static positions. | string | - | undefined |
-
----
diff --git a/docs/api/form/CForm.api.md b/docs/api/form/CForm.api.md
deleted file mode 100644
index 63967c5f..00000000
--- a/docs/api/form/CForm.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CForm
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
-| validated
| Mark a form as validated. If you set it `true`, all validation styles will be applied to the forms component. | boolean | - | |
-
----
diff --git a/docs/api/form/CFormCheck.api.md b/docs/api/form/CFormCheck.api.md
deleted file mode 100644
index 6dcac5a7..00000000
--- a/docs/api/form/CFormCheck.api.md
+++ /dev/null
@@ -1,15 +0,0 @@
-### CFormCheck
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------- | ---------- |
-| button
| Create button-like checkboxes and radio buttons. | shape({ /** _ Sets the color context of the component to one of CoreUI’s themed colors. _ _ @values 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string _/ color: Color, /** _ Select the shape of the component. _ _ @values 'rounded' \| 'rounded-top' \| 'rounded-end' \| 'rounded-bottom' \| 'rounded-start' \| 'rounded-circle' \| 'rounded-pill' \| 'rounded-0' \| 'rounded-1' \| 'rounded-2' \| 'rounded-3' \| string _/ shape: Shape, /** _ Size the component small or large. _ _ @values 'sm' \| 'lg' _/ size: { type: String, default: undefined, required: false, validator: (value: string) => { return ['sm', 'lg'].includes(value) }, }, /** _ Set the button variant to an outlined button or a ghost button. _/ variant: { type: String, default: undefined, required: false, validator: (value: string) => { return ['outline', 'ghost'].includes(value) }, }, }) | - | |
-| id
| The id global attribute defines an identifier (ID) that must be unique in the whole document. | string | - | undefined |
-| inline
| Group checkboxes or radios on the same horizontal row by adding. | boolean | - | |
-| invalid
| Set component validation state to invalid. | boolean | - | |
-| label
| The element represents a caption for a component. | string | - | undefined |
-| type
| Specifies the type of component. `@default` 'checkbox' | string | `'checkbox'`, `'radio'` | 'checkbox' |
-| valid
| Set component validation state to valid. | boolean | - | |
-
----
diff --git a/docs/api/form/CFormControl.api.md b/docs/api/form/CFormControl.api.md
deleted file mode 100644
index e7c28875..00000000
--- a/docs/api/form/CFormControl.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CFormControl
-
----
diff --git a/docs/api/form/CFormFeedback.api.md b/docs/api/form/CFormFeedback.api.md
deleted file mode 100644
index 4bc04ca7..00000000
--- a/docs/api/form/CFormFeedback.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CFormFeedback
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------------------------------------------------------------------------------------ | ------- | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'div' | string | - | 'div' |
-| invalid
| Method called immediately after the `value` prop changes. | boolean | - | |
-| tooltip
| If your form layout allows it, you can display validation feedback in a styled tooltip. | boolean | - | |
-| valid
| Set component validation state to valid. | boolean | - | |
-
----
diff --git a/docs/api/form/CFormFloating.api.md b/docs/api/form/CFormFloating.api.md
deleted file mode 100644
index 5cd7d714..00000000
--- a/docs/api/form/CFormFloating.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CFormFloating
-
----
diff --git a/docs/api/form/CFormInput.api.md b/docs/api/form/CFormInput.api.md
deleted file mode 100644
index c176b671..00000000
--- a/docs/api/form/CFormInput.api.md
+++ /dev/null
@@ -1,15 +0,0 @@
-### CFormInput
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------- | --------- |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| invalid
| Set component validation state to invalid. | boolean | - | |
-| plainText
| Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. | boolean | - | |
-| readonly
| Toggle the readonly state for the component. | boolean | - | |
-| size
| Size the component small or large. | string | `'sm' \| 'lg'` | undefined |
-| type
| Specifies the type of component. `@default` 'text' | string | `'color' \| 'file' \| 'text' \| string` | 'text' |
-| valid
| Set component validation state to valid. | boolean | - | |
-
----
diff --git a/docs/api/form/CFormLabel.api.md b/docs/api/form/CFormLabel.api.md
deleted file mode 100644
index 26770025..00000000
--- a/docs/api/form/CFormLabel.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CFormLabel
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------------- | --------------------------------------------------------------------------------------------------------- | ------------- | ------ | --------- |
-| customClassName
| A string of all className you want to be applied to the component, and override standard className value. | array\|string | - | undefined |
-
----
diff --git a/docs/api/form/CFormRange.api.md b/docs/api/form/CFormRange.api.md
deleted file mode 100644
index 566a644a..00000000
--- a/docs/api/form/CFormRange.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CFormRange
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ---------------------------------------------------------------- | ------- | ------ | --------- |
-| disabled
| Toggle the disabled state for the component. | boolean | - | undefined |
-| max
| Specifies the maximum value for the component. | number | - | undefined |
-| min
| Specifies the minimum value for the component. | number | - | undefined |
-| readonly
| Toggle the readonly state for the component. | boolean | - | |
-| steps
| Specifies the interval between legal numbers in the component. | number | - | undefined |
-| value
| The `value` attribute of component. `@controllable` onChange | number | - | undefined |
-
----
diff --git a/docs/api/form/CFormSelect.api.md b/docs/api/form/CFormSelect.api.md
deleted file mode 100644
index 17315ebe..00000000
--- a/docs/api/form/CFormSelect.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CFormSelect
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ------------------------------------------------------------ | ------- | -------------- | --------- |
-| htmlSize
| Specifies the number of visible options in a drop-down list. | number | - | undefined |
-| invalid
| Set component validation state to invalid. | boolean | - | |
-| size
| Size the component small or large. | string | `'sm' \| 'lg'` | undefined |
-| valid
| Set component validation state to valid. | boolean | - | |
-
----
diff --git a/docs/api/form/CFormSwitch.api.md b/docs/api/form/CFormSwitch.api.md
deleted file mode 100644
index f133210a..00000000
--- a/docs/api/form/CFormSwitch.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CFormSwitch
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | -------------------------------------------------------------------------------------------- | ------- | ----------------------- | ---------- |
-| id
| The id global attribute defines an identifier (ID) that must be unique in the whole document | string | - | undefined |
-| invalid
| Set component validation state to invalid. | boolean | - | |
-| label
| The element represents a caption for a component. | string | - | undefined |
-| size
| Size the component large or extra large. Works only with `switch`. | string | `'lg' \| 'xl'` | undefined |
-| type
| Specifies the type of component. `@default` 'checkbox' | string | `'checkbox'`, `'radio'` | 'checkbox' |
-| valid
| Set component validation state to valid. | boolean | - | |
-
----
diff --git a/docs/api/form/CFormText.api.md b/docs/api/form/CFormText.api.md
deleted file mode 100644
index 60658e9b..00000000
--- a/docs/api/form/CFormText.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CFormText
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------------------------------------------------------------------------------------ | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'div' | string | - | 'div' |
-
----
diff --git a/docs/api/form/CFormTextarea.api.md b/docs/api/form/CFormTextarea.api.md
deleted file mode 100644
index 375c01f2..00000000
--- a/docs/api/form/CFormTextarea.api.md
+++ /dev/null
@@ -1,13 +0,0 @@
-### CFormTextarea
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| invalid
| Set component validation state to invalid. | boolean | - | |
-| plainText
| Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. | boolean | - | |
-| readonly
| Toggle the readonly state for the component. | boolean | - | |
-| valid
| Set component validation state to valid. | boolean | - | |
-
----
diff --git a/docs/api/form/CInputGroup.api.md b/docs/api/form/CInputGroup.api.md
deleted file mode 100644
index e9b6988b..00000000
--- a/docs/api/form/CInputGroup.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CInputGroup
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ----------------- | ----------------------------------------------------------- | ------ | ------ | --------- |
-| size
| Size the component small or large. `@type` 'sm' \| 'lg' | string | - | undefined |
-
----
diff --git a/docs/api/form/CInputGroupText.api.md b/docs/api/form/CInputGroupText.api.md
deleted file mode 100644
index 82268a4d..00000000
--- a/docs/api/form/CInputGroupText.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CInputGroupText
-
----
diff --git a/docs/api/grid/CCol.api.md b/docs/api/grid/CCol.api.md
deleted file mode 100644
index 46f4c117..00000000
--- a/docs/api/grid/CCol.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CCol
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------- | ------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- |
-| xs
| The number of columns/offset/order on extra small devices (<576px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | undefined |
-| sm
| The number of columns/offset/order on small devices (<768px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | undefined |
-| md
| The number of columns/offset/order on medium devices (<992px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | undefined |
-| lg
| The number of columns/offset/order on large devices (<1200px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | undefined |
-| xl
| The number of columns/offset/order on X-Large devices (<1400px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | undefined |
-| xxl
| The number of columns/offset/order on XX-Large devices (≥1400px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | undefined |
-
----
diff --git a/docs/api/grid/CContainer.api.md b/docs/api/grid/CContainer.api.md
deleted file mode 100644
index 449b88df..00000000
--- a/docs/api/grid/CContainer.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CContainer
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ------------------------------------------------------------------- | ------- | ------ | ------- |
-| sm
| Set container 100% wide until small breakpoint. | boolean | - | |
-| md
| Set container 100% wide until medium breakpoint. | boolean | - | |
-| lg
| Set container 100% wide until large breakpoint. | boolean | - | |
-| xl
| Set container 100% wide until X-large breakpoint. | boolean | - | |
-| xxl
| Set container 100% wide until XX-large breakpoint. | boolean | - | |
-| fluid
| Set container 100% wide, spanning the entire width of the viewport. | boolean | - | |
-
----
diff --git a/docs/api/grid/CRow.api.md b/docs/api/grid/CRow.api.md
deleted file mode 100644
index bc4b9e0d..00000000
--- a/docs/api/grid/CRow.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CRow
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------- | ------------------------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | --------- |
-| xs
| The number of columns/offset/order on extra small devices (<576px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | undefined |
-| sm
| The number of columns/offset/order on small devices (<768px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | undefined |
-| md
| | Object as () => BPObject | - | undefined |
-| lg
| The number of columns/offset/order on large devices (<1200px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | undefined |
-| xl
| The number of columns/offset/order on X-Large devices (<1400px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | undefined |
-| xxl
| The number of columns/offset/order on XX-Large devices (≥1400px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | undefined |
-
----
diff --git a/docs/api/header/CHeader.api.md b/docs/api/header/CHeader.api.md
deleted file mode 100644
index 874bcdcb..00000000
--- a/docs/api/header/CHeader.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CHeader
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ------------------------------------------------------ | --------------- | ------------------------------------------------------------- | --------- |
-| container
| Defines optional container wrapping children elements. | boolean\|string | `boolean \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl' \| 'fluid'` | undefined |
-| position
| Place header in non-static positions. | string | - | undefined |
-
----
diff --git a/docs/api/header/CHeaderBrand.api.md b/docs/api/header/CHeaderBrand.api.md
deleted file mode 100644
index cfd9dc15..00000000
--- a/docs/api/header/CHeaderBrand.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CHeaderBrand
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'a' | string | - | 'a' |
-
----
diff --git a/docs/api/header/CHeaderDivider.api.md b/docs/api/header/CHeaderDivider.api.md
deleted file mode 100644
index b96d736e..00000000
--- a/docs/api/header/CHeaderDivider.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CHeaderDivider
-
----
diff --git a/docs/api/header/CHeaderNav.api.md b/docs/api/header/CHeaderNav.api.md
deleted file mode 100644
index 56fee2a6..00000000
--- a/docs/api/header/CHeaderNav.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CHeaderNav
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'ul' | string | - | 'ul' |
-
----
diff --git a/docs/api/header/CHeaderText.api.md b/docs/api/header/CHeaderText.api.md
deleted file mode 100644
index 9e1dd1b6..00000000
--- a/docs/api/header/CHeaderText.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CHeaderText
-
----
diff --git a/docs/api/header/CHeaderToggler.api.md b/docs/api/header/CHeaderToggler.api.md
deleted file mode 100644
index 93f63bd6..00000000
--- a/docs/api/header/CHeaderToggler.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CHeaderToggler
-
----
diff --git a/docs/api/image/CImage.api.md b/docs/api/image/CImage.api.md
deleted file mode 100644
index a5a5f9cc..00000000
--- a/docs/api/image/CImage.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CImage
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ---------------------------------------------- | ------- | ------------------------------ | --------- |
-| align
| Set the horizontal aligment. | string | `'start'`, `'center'`, `'end'` | undefined |
-| fluid
| Make image responsive. | boolean | - | |
-| rounded
| Make image rounded. | boolean | - | |
-| thumbnail
| Give an image a rounded 1px border appearance. | boolean | - | |
-
----
diff --git a/docs/api/link/CLink.api.md b/docs/api/link/CLink.api.md
deleted file mode 100644
index 075bd466..00000000
--- a/docs/api/link/CLink.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### CLink
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| active
| Toggle the active state for the component. | boolean | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| href
| The href attribute specifies the URL of the page the link goes to. | string | - | undefined |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------- | ---------- | ----------- |
-| onClick
| |
-
----
diff --git a/docs/api/list-group/CListGroup.api.md b/docs/api/list-group/CListGroup.api.md
deleted file mode 100644
index 07318240..00000000
--- a/docs/api/list-group/CListGroup.api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-### CListGroup
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'ul' | string | - | 'ul' |
-| flush
| Remove some borders and rounded corners to render list group items edge-to-edge in a parent component (e.g., ``) | boolean | - | |
-| layout
| Specify a layout type. `@value` 'horizontal', 'horizontal-sm', 'horizontal-md', 'horizontal-lg', 'horizontal-xl', 'horizontal-xxl', | string | - | undefined |
-
----
diff --git a/docs/api/list-group/CListGroupItem.api.md b/docs/api/list-group/CListGroupItem.api.md
deleted file mode 100644
index 9c99c419..00000000
--- a/docs/api/list-group/CListGroupItem.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CListGroupItem
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | ------- |
-| active
| Toggle the active state for the component. | boolean | - | |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'li' | string | - | 'li' |
-
----
diff --git a/docs/api/modal/CModal.api.md b/docs/api/modal/CModal.api.md
deleted file mode 100644
index 69e585e0..00000000
--- a/docs/api/modal/CModal.api.md
+++ /dev/null
@@ -1,24 +0,0 @@
-### CModal
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | -------------------------------------------------- | --------- |
-| alignment
| Align the modal in the center or top of the screen. `@default` 'top' | string | `'top'`, `'center'` | 'top' |
-| backdrop
| Apply a backdrop on body while offcanvas is open. `@default` true | boolean\|string | `boolean`, `'static'` | true |
-| className
| A string of all className you want applied to the modal content component. TODO: Consider if we should change this prop name to describe better its role. | string | - | undefined |
-| fullscreen
| Set modal to covers the entire user viewport | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | undefined |
-| keyboard
| Closes the modal when escape key is pressed. `@default` true | boolean | - | true |
-| dismiss
| Does the modal dialog itself scroll, or does the whole dialog scroll within the window. | boolean | - | false |
-| scrollable
| Create a scrollable modal that allows scrolling the modal body. | boolean | - | |
-| size
| Size the component small, large, or extra large. | string | `'sm'`, `'lg'`, `'xl'` | undefined |
-| transition
| Remove animation to create modal that simply appear rather than fade in to view. | boolean | - | true |
-| visible
| Toggle the visibility of alert component. | boolean | - | |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------- | ---------- | ------------------------------------------------------- |
-| dismiss
| | Event called before the dissmiss animation has started. |
-
----
diff --git a/docs/api/modal/CModalBody.api.md b/docs/api/modal/CModalBody.api.md
deleted file mode 100644
index 29a354ff..00000000
--- a/docs/api/modal/CModalBody.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CModalBody
-
----
diff --git a/docs/api/modal/CModalFooter.api.md b/docs/api/modal/CModalFooter.api.md
deleted file mode 100644
index 1f4bc4d9..00000000
--- a/docs/api/modal/CModalFooter.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CModalFooter
-
----
diff --git a/docs/api/modal/CModalHeader.api.md b/docs/api/modal/CModalHeader.api.md
deleted file mode 100644
index 5925419e..00000000
--- a/docs/api/modal/CModalHeader.api.md
+++ /dev/null
@@ -1,15 +0,0 @@
-### CModalHeader
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | --------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
-| dismiss
| Add a close button component to the header which will call the provided handler when clicked. | boolean | - | false |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------- | ---------- | ------------------------------------------------------- |
-| dismiss
| | Event called before the dissmiss animation has started. |
-
----
diff --git a/docs/api/modal/CModalTitle.api.md b/docs/api/modal/CModalTitle.api.md
deleted file mode 100644
index ef2252b5..00000000
--- a/docs/api/modal/CModalTitle.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CModalTitle
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'h5' | string | - | 'h5' |
-
----
diff --git a/docs/api/nav/CNav.api.md b/docs/api/nav/CNav.api.md
deleted file mode 100644
index d53349a9..00000000
--- a/docs/api/nav/CNav.api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-### CNav
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ----------------------- | --------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'ul' | string | - | 'ul' |
-| layout
| Specify a layout type for component. | string | `'fill'`, `'justified'` | undefined |
-| variant
| Set the nav variant to tabs or pills. | string | `'tabs'`, `'pills'` | undefined |
-
----
diff --git a/docs/api/nav/CNavGroup.api.md b/docs/api/nav/CNavGroup.api.md
deleted file mode 100644
index 64159900..00000000
--- a/docs/api/nav/CNavGroup.api.md
+++ /dev/null
@@ -1,15 +0,0 @@
-### CNavGroup
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | --------------------- | ------- | ------ | ------- |
-| visible
| Show nav group items. | boolean | - | false |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------------- | ---------- | ----------- |
-| visibleChange
| |
-
----
diff --git a/docs/api/nav/CNavGroupItems.api.md b/docs/api/nav/CNavGroupItems.api.md
deleted file mode 100644
index a30f6be8..00000000
--- a/docs/api/nav/CNavGroupItems.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CNavGroupItems
-
----
diff --git a/docs/api/nav/CNavItem.api.md b/docs/api/nav/CNavItem.api.md
deleted file mode 100644
index 9e14d515..00000000
--- a/docs/api/nav/CNavItem.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CNavItem
-
----
diff --git a/docs/api/nav/CNavLink.api.md b/docs/api/nav/CNavLink.api.md
deleted file mode 100644
index 5ec7d3b7..00000000
--- a/docs/api/nav/CNavLink.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CNavLink
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| active
| Toggle the active state for the component. | boolean | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'a' | string | - | 'a' |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| href
| `@ignore` true | string | - | undefined |
-
----
diff --git a/docs/api/nav/CNavTitle.api.md b/docs/api/nav/CNavTitle.api.md
deleted file mode 100644
index b9e9a83b..00000000
--- a/docs/api/nav/CNavTitle.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CNavTitle
-
----
diff --git a/docs/api/navbar/CNavbar.api.md b/docs/api/navbar/CNavbar.api.md
deleted file mode 100644
index 59350100..00000000
--- a/docs/api/navbar/CNavbar.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CNavbar
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------------ | ------------------------------------------------------------------------------------------------------------ | --------------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-| colorScheme
| Sets if the color of text should be colored for a light or dark dark background. | string | `'dark'`, `'light'` | undefined |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'nav' | string | - | 'nav' |
-| container
| Defines optional container wrapping children elements. | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'`, `'fluid'` | undefined |
-| expand
| Defines the responsive breakpoint to determine when content collapses. | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | undefined |
-| placement
| Place component in non-static positions. | string | `'fixed-top'`, `'fixed-bottom'`, `'sticky-top'` | undefined |
-
----
diff --git a/docs/api/navbar/CNavbarBrand.api.md b/docs/api/navbar/CNavbarBrand.api.md
deleted file mode 100644
index 261181b8..00000000
--- a/docs/api/navbar/CNavbarBrand.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CNavbarBrand
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------ | ------ | --------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
-| href
| The href attribute specifies the URL of the page the link goes to. | string | - | undefined |
-
----
diff --git a/docs/api/navbar/CNavbarNav.api.md b/docs/api/navbar/CNavbarNav.api.md
deleted file mode 100644
index b29d7d8e..00000000
--- a/docs/api/navbar/CNavbarNav.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CNavbarNav
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'ul' | string | - | 'ul' |
-
----
diff --git a/docs/api/navbar/CNavbarText.api.md b/docs/api/navbar/CNavbarText.api.md
deleted file mode 100644
index c7def2a6..00000000
--- a/docs/api/navbar/CNavbarText.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CNavbarText
-
----
diff --git a/docs/api/navbar/CNavbarToggler.api.md b/docs/api/navbar/CNavbarToggler.api.md
deleted file mode 100644
index 70ad1552..00000000
--- a/docs/api/navbar/CNavbarToggler.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CNavbarToggler
-
----
diff --git a/docs/api/offcanvas/COffcanvas.api.md b/docs/api/offcanvas/COffcanvas.api.md
deleted file mode 100644
index dd5bb4c2..00000000
--- a/docs/api/offcanvas/COffcanvas.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### COffcanvas
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------- | ------- | --------------------------------------- | --------- |
-| backdrop
| Apply a backdrop on body while offcanvas is open. `@default` true | boolean | - | true |
-| keyboard
| Closes the offcanvas when escape key is pressed. `@default` true | boolean | - | true |
-| placement
| Components placement, there’s no default placement. | string | `'start'`, `'end'`, `'top'`, `'bottom'` | undefined |
-| visible
| Toggle the visibility of offcanvas component. | boolean | - | |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------- | ---------- | ------------------------------------------------------- |
-| dismiss
| | Event called before the dissmiss animation has started. |
-
----
diff --git a/docs/api/offcanvas/COffcanvasBody.api.md b/docs/api/offcanvas/COffcanvasBody.api.md
deleted file mode 100644
index fe8b7725..00000000
--- a/docs/api/offcanvas/COffcanvasBody.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### COffcanvasBody
-
----
diff --git a/docs/api/offcanvas/COffcanvasHeader.api.md b/docs/api/offcanvas/COffcanvasHeader.api.md
deleted file mode 100644
index 033977e9..00000000
--- a/docs/api/offcanvas/COffcanvasHeader.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### COffcanvasHeader
-
----
diff --git a/docs/api/offcanvas/COffcanvasTitle.api.md b/docs/api/offcanvas/COffcanvasTitle.api.md
deleted file mode 100644
index f001f943..00000000
--- a/docs/api/offcanvas/COffcanvasTitle.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### COffcanvasTitle
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | ----------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'h5' | string | - | 'h5' |
-
----
diff --git a/docs/api/pagination/CPagination.api.md b/docs/api/pagination/CPagination.api.md
deleted file mode 100644
index a379059b..00000000
--- a/docs/api/pagination/CPagination.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CPagination
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ----------------- | ---------------------------------- | ------ | -------------- | --------- |
-| size
| Size the component small or large. | string | `'sm'`, `'lg'` | undefined |
-
----
diff --git a/docs/api/pagination/CPaginationItem.api.md b/docs/api/pagination/CPaginationItem.api.md
deleted file mode 100644
index 2b7769a9..00000000
--- a/docs/api/pagination/CPaginationItem.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CPaginationItem
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| active
| Toggle the active state for the component. | boolean | - | |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | undefined |
-| disabled
| Toggle the disabled state for the component. | boolean | - | |
-| href
| The href attribute specifies the URL of the page the link goes to. | string | - | undefined |
-
----
diff --git a/docs/api/progress/CProgress.api.md b/docs/api/progress/CProgress.api.md
deleted file mode 100644
index 073c6991..00000000
--- a/docs/api/progress/CProgress.api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-### CProgress
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| height
| Sets the height of the component. If you set that value the inner `` will automatically resize accordingly. `@default` 'undefined' | number | - | undefined |
-| thin
| Makes progress bar thinner. | boolean | - | |
-| white
| Change the default color to white. | boolean | - | |
-
----
diff --git a/docs/api/progress/CProgressBar.api.md b/docs/api/progress/CProgressBar.api.md
deleted file mode 100644
index f12a389d..00000000
--- a/docs/api/progress/CProgressBar.api.md
+++ /dev/null
@@ -1,12 +0,0 @@
-### CProgressBar
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | --------- |
-| animated
| Use to animate the stripes right to left via CSS3 animations. | boolean | - | |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | undefined |
-| value
| The percent to progress the ProgressBar. `@default` 0 | number | - | 0 |
-| variant
| Set the progress bar variant to optional striped. | string | `'striped'` | undefined |
-
----
diff --git a/docs/api/sidebar/CSidebar.api.md b/docs/api/sidebar/CSidebar.api.md
deleted file mode 100644
index 3e4ea62d..00000000
--- a/docs/api/sidebar/CSidebar.api.md
+++ /dev/null
@@ -1,15 +0,0 @@
-### CSidebar
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | --------------- | ----------------------------------------------- | --------- |
-| hide
| Hide sidebar. | boolean | - | |
-| narrow
| Make sidebar narrow. | boolean | - | |
-| overlaid
| Set sidebar to overlaid variant. | boolean | - | |
-| position
| Place sidebar in non-static positions. | string | - | undefined |
-| selfHiding
| Make any sidebar self hiding across all viewports or pick a maximum breakpoint with which to have a self hiding up to. | boolean\|string | `'xs'`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | undefined |
-| unfoldable
| Expand narrowed sidebar on hover. | string | - | undefined |
-| visible
| Toggle the visibility of sidebar component. | boolean | - | |
-
----
diff --git a/docs/api/sidebar/CSidebarBrand.api.md b/docs/api/sidebar/CSidebarBrand.api.md
deleted file mode 100644
index dd7cf8cd..00000000
--- a/docs/api/sidebar/CSidebarBrand.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CSidebarBrand
-
----
diff --git a/docs/api/sidebar/CSidebarFooter.api.md b/docs/api/sidebar/CSidebarFooter.api.md
deleted file mode 100644
index be8546fa..00000000
--- a/docs/api/sidebar/CSidebarFooter.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CSidebarFooter
-
----
diff --git a/docs/api/sidebar/CSidebarHeader.api.md b/docs/api/sidebar/CSidebarHeader.api.md
deleted file mode 100644
index 15b8a8e7..00000000
--- a/docs/api/sidebar/CSidebarHeader.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CSidebarHeader
-
----
diff --git a/docs/api/sidebar/CSidebarNav.api.md b/docs/api/sidebar/CSidebarNav.api.md
deleted file mode 100644
index 96924912..00000000
--- a/docs/api/sidebar/CSidebarNav.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CSidebarNav
-
----
diff --git a/docs/api/sidebar/CSidebarToggler.api.md b/docs/api/sidebar/CSidebarToggler.api.md
deleted file mode 100644
index cea08bd3..00000000
--- a/docs/api/sidebar/CSidebarToggler.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CSidebarToggler
-
----
diff --git a/docs/api/spinner/CSpinner.api.md b/docs/api/spinner/CSpinner.api.md
deleted file mode 100644
index 821bce70..00000000
--- a/docs/api/spinner/CSpinner.api.md
+++ /dev/null
@@ -1,13 +0,0 @@
-### CSpinner
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------------------- | ------------------------------------------------------------------------------------------------------------ | ------ | ----------------------------------------------------------------------------------------------- | ------------ |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | undefined |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. `@default` 'div' | string | - | 'div' |
-| size
| Size the component small. | string | `'sm'` | undefined |
-| variant
| Set the button variant to an outlined button or a ghost button. `@default` 'border' | string | `'border'`, `'grow'` | 'border' |
-| visuallyHiddenLabel
| Set visually hidden label for accessibility purposes. `@default` 'Loading...' | string | - | 'Loading...' |
-
----
diff --git a/docs/api/table/CTable.api.md b/docs/api/table/CTable.api.md
deleted file mode 100644
index 1c2c44e7..00000000
--- a/docs/api/table/CTable.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### CTable
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| align
| Set the vertical aligment. | string | `'bottom'`, `'middle'`, `'top'` | undefined |
-| borderColor
| Sets the border color of the component to one of CoreUI’s themed colors. `@value` 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string | Color | - | |
-| bordered
| Add borders on all sides of the table and cells. | boolean | - | |
-| borderless
| Remove borders on all sides of the table and cells. | boolean | - | |
-| caption
| Put the `` on the top of the table. | string | `'top'` | undefined |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-| hover
| Enable a hover state on table rows within a ``. | boolean | - | |
-| responsive
| Make any table responsive across all viewports or pick a maximum breakpoint with which to have a responsive table up to. | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | undefined |
-| small
| Make table more compact by cutting all cell `padding` in half. | boolean | - | |
-| striped
| Add zebra-striping to any table row within the ``. | boolean | - | |
-
----
diff --git a/docs/api/table/CTableBody.api.md b/docs/api/table/CTableBody.api.md
deleted file mode 100644
index 0a15568d..00000000
--- a/docs/api/table/CTableBody.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CTableBody
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ------------------------------------------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------- | ------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-
----
diff --git a/docs/api/table/CTableCaption.api.md b/docs/api/table/CTableCaption.api.md
deleted file mode 100644
index 421b53ee..00000000
--- a/docs/api/table/CTableCaption.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CTableCaption
-
----
diff --git a/docs/api/table/CTableDataCell.api.md b/docs/api/table/CTableDataCell.api.md
deleted file mode 100644
index 6b66ce48..00000000
--- a/docs/api/table/CTableDataCell.api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-### CTableDataCell
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------- | ------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| active
| Highlight a table row or cell. | boolean | - | |
-| align
| Set the vertical aligment. | string | `'bottom'`, `'middle'`, `'top'` | undefined |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-
----
diff --git a/docs/api/table/CTableFoot.api.md b/docs/api/table/CTableFoot.api.md
deleted file mode 100644
index 7e206ac2..00000000
--- a/docs/api/table/CTableFoot.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CTableFoot
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ------------------------------------------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------- | ------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-
----
diff --git a/docs/api/table/CTableHead.api.md b/docs/api/table/CTableHead.api.md
deleted file mode 100644
index aa56ec54..00000000
--- a/docs/api/table/CTableHead.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CTableHead
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ------------------------------------------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------- | ------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-
----
diff --git a/docs/api/table/CTableHeaderCell.api.md b/docs/api/table/CTableHeaderCell.api.md
deleted file mode 100644
index 0a7f0877..00000000
--- a/docs/api/table/CTableHeaderCell.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CTableHeaderCell
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ------------------------------------------------------------------------- | ----- | --------------------------------------------------------------------------------------------------------- | ------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-
----
diff --git a/docs/api/table/CTableRow.api.md b/docs/api/table/CTableRow.api.md
deleted file mode 100644
index a8b2f3f7..00000000
--- a/docs/api/table/CTableRow.api.md
+++ /dev/null
@@ -1,11 +0,0 @@
-### CTableRow
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------- | ------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| active
| Highlight a table row or cell.. | boolean | - | |
-| align
| Set the vertical aligment. | string | `'bottom'`, `'middle'`, `'top'` | undefined |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. | Color | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | |
-
----
diff --git a/docs/api/tabs/CTabContent.api.md b/docs/api/tabs/CTabContent.api.md
deleted file mode 100644
index a30f6be8..00000000
--- a/docs/api/tabs/CTabContent.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CNavGroupItems
-
----
diff --git a/docs/api/tabs/CTabPane.api.md b/docs/api/tabs/CTabPane.api.md
deleted file mode 100644
index 09f25587..00000000
--- a/docs/api/tabs/CTabPane.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CTabPane
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | ----------------------------------- | ------- | ------ | ------- |
-| visible
| Toggle the visibility of component. | boolean | - | false |
-
----
diff --git a/docs/api/toast/CToast.api.md b/docs/api/toast/CToast.api.md
deleted file mode 100644
index d0c86588..00000000
--- a/docs/api/toast/CToast.api.md
+++ /dev/null
@@ -1,21 +0,0 @@
-### CToast
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | --------- |
-| autohide
| Auto hide the toast. `@default` true | boolean | - | true |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. `@default` 'primary' `@value` 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string | Color | - | |
-| delay
| Delay hiding the toast (ms). | number | - | 5000 |
-| dismissible
| Optionally add a close button to component and allow it to self dismiss. `@default` true | boolean | - | true |
-| key
| | number | - | undefined |
-| title
| Title node for your component. | string | - | undefined |
-| visible
| Toggle the visibility of component. `@default` true | boolean | - | true |
-
-#### Events
-
-| Event name | Properties | Description |
-| -------------------- | ---------- | ------------------------------------------------------- |
-| dismiss
| | Event called before the dissmiss animation has started. |
-
----
diff --git a/docs/api/toast/CToastBody.api.md b/docs/api/toast/CToastBody.api.md
deleted file mode 100644
index bf87eafc..00000000
--- a/docs/api/toast/CToastBody.api.md
+++ /dev/null
@@ -1,3 +0,0 @@
-### CToastBody
-
----
diff --git a/docs/api/toast/CToastClose.api.md b/docs/api/toast/CToastClose.api.md
deleted file mode 100644
index 29bd7363..00000000
--- a/docs/api/toast/CToastClose.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CToastClose
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | --------------------------------------------------------------------------------------- | ------ | ------ | --------- |
-| component
| Component used for the root node. Either a string to use a HTML element or a component. | string | - | undefined |
-
----
diff --git a/docs/api/toast/CToastHeader.api.md b/docs/api/toast/CToastHeader.api.md
deleted file mode 100644
index 1f4c8199..00000000
--- a/docs/api/toast/CToastHeader.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CToastHeader
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | ----------------------------------------------- | ------- | ------ | ------- |
-| dismiss
| Automatically add a close button to the header. | boolean | - | |
-
----
diff --git a/docs/api/toast/CToaster.api.md b/docs/api/toast/CToaster.api.md
deleted file mode 100644
index db63ddd5..00000000
--- a/docs/api/toast/CToaster.api.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### CToaster
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ---------------------- | -------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------- | --------- |
-| placement
| Describes the placement of component. `@default` 'top-end' | string | `'top-start'`, `'top'`, `'top-end'`, `'middle-start'`, `'middle'`, `'middle-end'`, `'bottom-start'`, `'bottom'`, `'bottom-end'` | undefined |
-
----
diff --git a/docs/api/widgets/CWidgetStatsA.api.md b/docs/api/widgets/CWidgetStatsA.api.md
deleted file mode 100644
index 65326c4d..00000000
--- a/docs/api/widgets/CWidgetStatsA.api.md
+++ /dev/null
@@ -1,18 +0,0 @@
-### CWidgetStatsA
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------ | --------- |
-| color
| | string | - | undefined |
-| title
| Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| value
| Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
-
-#### Slots
-
-| Name | Description | Bindings |
-| ------ | ------------------------------------------------- | -------- |
-| chart | Location for chart component. | |
-| action | Location for action component, ex. ``. | |
-
----
diff --git a/docs/api/widgets/CWidgetStatsB.api.md b/docs/api/widgets/CWidgetStatsB.api.md
deleted file mode 100644
index 2900d200..00000000
--- a/docs/api/widgets/CWidgetStatsB.api.md
+++ /dev/null
@@ -1,14 +0,0 @@
-### CWidgetStatsB
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors | Color | `'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string` | |
-| inverse
| Colors have been inverted from their default dark shade. | boolean | - | undefined |
-| progress
| | shape({ /** _ Sets the color context of the progress bar to one of CoreUI’s themed colors _ _ @values 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string _/ color: Color, /** _ The percent to progress the ProgressBar (out of 100). _ @default 0 \*/ value: { type: Number, default: 0, }, }) | - | |
-| text
| Helper text for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| title
| Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| value
| Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
-
----
diff --git a/docs/api/widgets/CWidgetStatsC.api.md b/docs/api/widgets/CWidgetStatsC.api.md
deleted file mode 100644
index 4532c72f..00000000
--- a/docs/api/widgets/CWidgetStatsC.api.md
+++ /dev/null
@@ -1,13 +0,0 @@
-### CWidgetStatsC
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. [docs] | Color | `'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string` | |
-| inverse
| Colors have been inverted from their default dark shade. | boolean | - | undefined |
-| progress
| | shape({ /** _ Sets the color context of the progress bar to one of CoreUI’s themed colors _ _ @values 'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string _/ color: Color, /** _ The percent to progress the ProgressBar (out of 100). _ @default 0 \*/ value: { type: Number, default: 0, }, }) | - | |
-| title
| Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| value
| Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
-
----
diff --git a/docs/api/widgets/CWidgetStatsD.api.md b/docs/api/widgets/CWidgetStatsD.api.md
deleted file mode 100644
index 004f98bf..00000000
--- a/docs/api/widgets/CWidgetStatsD.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CWidgetStatsD
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------- | -------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------- | -------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. [docs] | Color | `'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string` | |
-| values
| Values and titles for your component. | number[] \| string[] | - | () => [] |
-
----
diff --git a/docs/api/widgets/CWidgetStatsE.api.md b/docs/api/widgets/CWidgetStatsE.api.md
deleted file mode 100644
index 4701ff98..00000000
--- a/docs/api/widgets/CWidgetStatsE.api.md
+++ /dev/null
@@ -1,10 +0,0 @@
-### CWidgetStatsE
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------ | --------- |
-| title
| Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| value
| Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
-
----
diff --git a/docs/api/widgets/CWidgetStatsF.api.md b/docs/api/widgets/CWidgetStatsF.api.md
deleted file mode 100644
index c069a958..00000000
--- a/docs/api/widgets/CWidgetStatsF.api.md
+++ /dev/null
@@ -1,13 +0,0 @@
-### CWidgetStatsF
-
-#### Props
-
-| Prop name | Description | Type | Values | Default |
-| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | --------------------------------------------------------------------------------------------------------- | --------- |
-| color
| Sets the color context of the component to one of CoreUI’s themed colors. [docs] | Color | `'primary' \| 'secondary' \| 'success' \| 'danger' \| 'warning' \| 'info' \| 'dark' \| 'light' \| string` | |
-| padding
| Set padding of your component. [docs] | boolean | - | true |
-| title
| Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| text
| Helper text for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | undefined |
-| value
| Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
-
----
diff --git a/docs/components/accordion.md b/docs/components/accordion.md
deleted file mode 100644
index 9acc2cca..00000000
--- a/docs/components/accordion.md
+++ /dev/null
@@ -1,254 +0,0 @@
----
-title: Vue Accordion Component
-name: Accordion
-description: Build vertically collapsing accordions in combination with our Vue Collapse component.
----
-
-## Examples
-
-Click the accordions below to expand/collapse the accordion content.
-
-::: demo
-
-
-
- { activeKey === 1 ? activeKey = 0 : activeKey = 1 }">
- Accordion Item #1
-
-
-
-
- This is the first item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { activeKey === 2 ? activeKey = 0 : activeKey = 2 }">
- Accordion Item #2
-
-
-
-
- This is the second item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { activeKey === 3 ? activeKey = 0 : activeKey = 3 }">
- Accordion Item #3
-
-
-
-
- This is the third item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-:::
-```vue
-
-
-
- { activeKey === 1 ? activeKey = 0 : activeKey = 1 }">
- Accordion Item #1
-
-
-
-
- This is the first item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { activeKey === 2 ? activeKey = 0 : activeKey = 2 }">
- Accordion Item #2
-
-
-
-
- This is the second item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { activeKey === 3 ? activeKey = 0 : activeKey = 3 }">
- Accordion Item #3
-
-
-
-
- This is the third item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-```
-
-### Flush
-
-Add `flush` to remove the default `background-color`, some borders, and some rounded corners to render accordions edge-to-edge with their parent container.
-
-:::demo
-
-
-
- { flushActiveKey === 1 ? flushActiveKey = 0 : flushActiveKey = 1 }">
- Accordion Item #1
-
-
-
-
- This is the first item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { flushActiveKey === 2 ? flushActiveKey = 0 : flushActiveKey = 2 }">
- Accordion Item #2
-
-
-
-
- This is the second item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { flushActiveKey === 3 ? flushActiveKey = 0 : flushActiveKey = 3 }">
- Accordion Item #3
-
-
-
-
- This is the third item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-:::
-```vue
-
-
-
- { flushActiveKey === 1 ? flushActiveKey = 0 : flushActiveKey = 1 }">
- Accordion Item #1
-
-
-
-
- This is the first item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { flushActiveKey === 2 ? flushActiveKey = 0 : flushActiveKey = 2 }">
- Accordion Item #2
-
-
-
-
- This is the second item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-
- { flushActiveKey === 3 ? flushActiveKey = 0 : flushActiveKey = 3 }">
- Accordion Item #3
-
-
-
-
- This is the third item's accordion body. It is hidden by default,
- until the collapse plugin adds the appropriate classes that we use to style each
- element. These classes control the overall appearance, as well as the showing and
- hiding via CSS transitions. You can modify any of this with custom CSS or overriding
- our default variables. It's also worth noting that just about any HTML can go within
- the .accordion-body
, though the transition does limit overflow.
-
-
-
-
-```
-
-
-
-## API
-
-!!!include(./docs/api/accordion/CAccordion.api.md)!!!
-
-!!!include(./docs/api/accordion/CAccordionButton.api.md)!!!
-
-!!!include(./docs/api/accordion/CAccordionCollapse.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/alert.md b/docs/components/alert.md
deleted file mode 100644
index 7efa4fd8..00000000
--- a/docs/components/alert.md
+++ /dev/null
@@ -1,151 +0,0 @@
----
-title: Alert
-description: Vue alert component gives contextual feedback information for common user operations. The alert component is delivered with a bunch of usable and adjustable alert messages.
----
-
-## Examples
-
-Vue Alert is prepared for any length of text, as well as an optional close button. For a styling, use one of the **required** contextual `color` props (e.g., `primary`). For inline dismissal, use the [dismissing prop](#dismissing).
-
-::: demo
-A simple primary alert—check it out!
-A simple secondary alert—check it out!
-A simple success alert—check it out!
-A simple danger alert—check it out!
-A simple warning alert—check it out!
-A simple info alert—check it out!
-A simple light alert—check it out!
-A simple dark alert—check it out!
-:::
-
-```vue
-A simple primary alert—check it out!
-A simple secondary alert—check it out!
-A simple success alert—check it out!
-A simple danger alert—check it out!
-A simple warning alert—check it out!
-A simple info alert—check it out!
-A simple light alert—check it out!
-A simple dark alert—check it out!
-```
-
-## Link color
-
-Use the `` component to immediately give matching colored links inside any alert.
-::: demo
-
- A simple primary alert with an example link . Give it a click if you like.
-
-
- A simple secondary alert with an example link . Give it a click if you like.
-
-
- A simple success alert with an example link . Give it a click if you like.
-
-
- A simple danger alert with an example link . Give it a click if you like.
-
-
- A simple warning alert with an example link . Give it a click if you like.
-
-
- A simple info alert with an example link . Give it a click if you like.
-
-
- A simple light alert with an example link . Give it a click if you like.
-
-
- A simple dark alert with an example link . Give it a click if you like.
-
-:::
-
-```vue
-
- A simple primary alert with an example link . Give it a click if you like.
-
-
- A simple secondary alert with an example link . Give it a click if you like.
-
-
- A simple success alert with an example link . Give it a click if you like.
-
-
- A simple danger alert with an example link . Give it a click if you like.
-
-
- A simple warning alert with an example link . Give it a click if you like.
-
-
- A simple info alert with an example link . Give it a click if you like.
-
-
- A simple light alert with an example link . Give it a click if you like.
-
-
- A simple dark alert with an example link . Give it a click if you like.
-
-```
-
-## Additional content
-
-Alert can also incorporate supplementary HTML elements like heading, paragraph, and divider.
-
-::: demo
-
- Well done!
- Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.
-
- Whenever you need to, be sure to use margin utilities to keep things nice and tidy.
-
-:::
-
-```vue
-
- Well done!
- Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.
-
- Whenever you need to, be sure to use margin utilities to keep things nice and tidy.
-
-```
-
-## Dismissing
-
-Alerts can also be easily dismissed. Just add the `dismissible` prop.
-
-::: demo
-
- Go right ahead and click that dimiss over there on the right.
-
-
-
-:::
-
-```vue
-
- Go right ahead and click that dimiss over there on the right.
-
-
-
-```
-
-## API
-
-!!!include(./docs/api/alert/CAlert.api.md)!!!
-
-!!!include(./docs/api/alert/CAlertHeading.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/nav.md b/docs/components/nav.md
deleted file mode 100644
index bf37386a..00000000
--- a/docs/components/nav.md
+++ /dev/null
@@ -1,562 +0,0 @@
----
-title: Vue Nav Component
-name: Nav
-description: Documentation and examples for how to use CoreUI's included Vue navigation components.
-
----
-
-## Base nav
-
-Navigation available in CoreUI for Vue share general markup and styles, from the base `.nav` class to the active and disabled states. Swap modifier classes to switch between each style.
-
-The base `.nav` component is built with flexbox and provide a strong foundation for building all types of navigation components. It includes some style overrides (for working with lists), some link padding for larger hit areas, and basic disabled styling.
-
-::: demo
-
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-
-:::
-```vue
-
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-
-```
-
-Classes are used throughout, so your markup can be super flexible. Use ``s like above, `` if the order of your items is important, or roll your own with a `` element. Because the .nav uses display: flex, the nav links behave the same as nav items would, but without the extra markup.
-
-::: demo
-
-
-
- Active
-
- Link
- Link
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
- Link
- Link
-
- Disabled
-
-
-
-```
-
-## Available styles
-
-Change the style of `.nav`s component with modifiers and utilities. Mix and match as needed, or build your own.
-
-### Horizontal alignment
-
-Change the horizontal alignment of your nav with [flexbox utilities](https://coreui.io/docs/layout/grid/#horizontal-alignment). By default, navs are left-aligned, but you can easily change them to center or right aligned.
-
-Centered with `.justify-content-center`:
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-Right-aligned with `.justify-content-end`:
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-### Vertical
-
-Stack your navigation by changing the flex item direction with the `.flex-column` utility. Need to stack them on some viewports but not others? Use the responsive versions (e.g., `.flex-sm-column`).
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-### Tabs
-
-Takes the basic nav from above and adds the `variant="tabs"` class to generate a tabbed interface
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-### Pills
-
-Take that same HTML, but use `variant="pills"` instead:
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-### Fill and justify
-
-Force your `.nav`'s contents to extend the full available width one of two modifier classes. To proportionately fill all available space with your `.nav-item`s, use `layout="fill"`. Notice that all horizontal space is occupied, but not every nav item has the same width.
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-For equal-width elements, use `layout="justified"`. All horizontal space will be occupied by nav links, but unlike the .nav-fill above, every nav item will be the same width.
-
-::: demo
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Link
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-## Working with flex utilities
-
-If you need responsive nav variations, consider using a series of [flexbox utilities](https://coreui.io/docs/utilities/flex). While more verbose, these utilities offer greater customization across responsive breakpoints. In the example below, our nav will be stacked on the lowest breakpoint, then adapt to a horizontal layout that fills the available width starting from the small breakpoint.
-
-::: demo
-
-
- Active
-
- Link
- Link
-
- Disabled
-
-
-:::
-```vue
-
-
- Active
-
- Link
- Link
-
- Disabled
-
-
-```
-
-## Regarding accessibility
-
-If you're using navs to provide a navigation bar, be sure to add a `role="navigation"` to the most logical parent container of the ``, or wrap a `` element around the whole navigation. Do not add the role to the `` itself, as this would prevent it from being announced as an actual list by assistive technologies.
-
-Note that navigation bars, even if visually styled as tabs with the `.nav-tabs` class, should **not** be given `role="tablist"`, `role="tab"` or `role="tabpanel"` attributes. These are only appropriate for dynamic tabbed interfaces, as described in the [WAI ARIA Authoring Practices](https://www.w3.org/TR/wai-aria-practices/#tabpanel). See [JavaScript behavior](#javascript-behavior) for dynamic tabbed interfaces in this section for an example. The `aria-current` attribute is not necessary on dynamic tabbed interfaces since our JavaScript handles the selected state by adding `aria-selected="true"` on the active tab.
-
-## Using dropdowns
-
-Add dropdown menus with a little extra HTML.
-
-### Tabs with dropdowns
-
-::: demo
-
-
-
- Active
-
-
-
- Dropdown button
-
- Action
- Another action
- Something else here
-
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Dropdown button
-
- Action
- Another action
- Something else here
-
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-### Pills with dropdowns
-
-::: demo
-
-
-
- Active
-
-
-
- Dropdown button
-
- Action
- Another action
- Something else here
-
-
-
- Link
-
-
-
- Disabled
-
-
-
-:::
-```vue
-
-
-
- Active
-
-
-
- Dropdown button
-
- Action
- Another action
- Something else here
-
-
-
- Link
-
-
-
- Disabled
-
-
-
-```
-
-## API
-
-!!!include(./docs/api/nav/CNav.api.md)!!!
-
-!!!include(./docs/api/nav/CNavGroup.api.md)!!!
-
-!!!include(./docs/api/nav/CNavItem.api.md)!!!
-
-`CNavItem` and `CNavLink` have the same properties. If you set the `href` property on `CNavItem` then, `CNavLink` will be generated inside `CNavItem`.
-
-!!!include(./docs/api/nav/CNavLink.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/offcanvas.md b/docs/components/offcanvas.md
deleted file mode 100644
index 841549f1..00000000
--- a/docs/components/offcanvas.md
+++ /dev/null
@@ -1,229 +0,0 @@
----
-title: Vue Offcanvas Component
-name: Offcanvas
-description: Vue alert component allows build hidden sidebars into your project for navigation, shopping carts.
-
----
-
-
-## Examples
-
-### Offcanvas components
-
-Below is an offcanvas example that is shown by default (via `:visible="true"`). Offcanvas includes support for a header with a close button and an optional body class for some initial `padding`. We suggest that you include offcanvas headers with dismiss actions whenever possible, or provide an explicit dismiss action.
-
-
-::: demo
-
-
-
- Offcanvas
-
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-
-:::
-```vue
-
-
- Offcanvas
-
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-```
-
-### Live demo
-
-Use the buttons below to show and hide an offcanvas component.
-
-- `:visible="false"` hides content (default)
-- `visible` or `:visible="true"` shows content
-
-::: demo
- { visible = !visible }">Toggle offcanvas
- { visible = !visible }">
-
- Offcanvas
- { visible = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-:::
-```vue
-
- { visible = !visible }">Toggle offcanvas
- { visible = !visible }">
-
- Offcanvas
- { visible = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-
-
-```
-
-## Placement
-
-There's no default placement for offcanvas components, so you must add one of the modifier classes below;
-
-- `placement="start"` places offcanvas on the left of the viewport (shown above)
-- `placement="end"` places offcanvas on the right of the viewport
-- `placement="top"` places offcanvas on the top of the viewport
-- `placement="bottom"` places offcanvas on the bottom of the viewport
-
-Try the top, right, and bottom examples out below.
-
-::: demo
- { visibleTop = !visibleTop }">Toggle top offcanvas
- { visibleTop = !visibleTop }">
-
- Offcanvas
- { visibleTop = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-:::
-```vue
-
- { visibleTop = !visibleTop }">Toggle top offcanvas
- { visibleTop = !visibleTop }">
-
- Offcanvas
- { visibleTop = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-
-
-```
-
-::: demo
- { visibleEnd = !visibleEnd }">Toggle right offcanvas
- { visibleEnd = !visibleEnd }">
-
- Offcanvas
- { visibleEnd = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-:::
-```vue
-
- { visibleEnd = !visibleEnd }">Toggle right offcanvas
- { visibleEnd = !visibleEnd }">
-
- Offcanvas
- { visibleEnd = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-
-
-```
-
-::: demo
- { visibleBottom = !visibleBottom }">Toggle bottom offcanvas
- { visibleBottom = !visibleBottom }">
-
- Offcanvas
- { visibleBottom = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-:::
-```vue
-
- { visibleBottom = !visibleBottom }">Toggle bottom offcanvas
- { visibleBottom = !visibleBottom }">
-
- Offcanvas
- { visibleBottom = false }"/>
-
-
- Content for the offcanvas goes here. You can place just about any Bootstrap component or
- custom elements here.
-
-
-
-
-```
-
-
-## API
-
-!!!include(./docs/api/offcanvas/COffcanvas.api.md)!!!
-
-!!!include(./docs/api/offcanvas/COffcanvasTitle.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/popover.md b/docs/components/popover.md
deleted file mode 100644
index 07b7d94e..00000000
--- a/docs/components/popover.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: Vue Popover Component
-name: Popover
-description: Documentation and examples for adding Vue popovers, like those found in iOS, to any element on your site.
----
-
-## Example
-
-::: demo
-Click to toggle popover
-:::
-```vue
-Click to toggle popover
-```
-
-### Four directions
-
-Four options are available: top, right, bottom, and left aligned. Directions are mirrored when using CoreUI for Vue in RTL.
-
-::: demo
-Popover on top
-Popover on right
-Popover on bottom
-Popover on left
-:::
-```vue
-Popover on top
-Popover on right
-Popover on bottom
-Popover on left
-```
-
diff --git a/docs/components/tooltip.md b/docs/components/tooltip.md
deleted file mode 100644
index e04605a3..00000000
--- a/docs/components/tooltip.md
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: Vue Tooltip Component
-name: Tooltip
-description: Documentation and examples for adding Vue Tooltips.
----
-
-::: demo
-
- Tight pants next level keffiyeh
- you probably
- haven't heard of them.
- Photo booth beard raw denim letterpress vegan messenger
- bag stumptown. Farm-to-table seitan, mcsweeney's fixie
- sustainable quinoa 8-bit american apparel
- have a
- terry richardson vinyl chambray. Beard stumptown,
- cardigans banh mi lomo thundercats. Tofu biodiesel
- williamsburg marfa, four loko mcsweeney''s cleanse
- vegan chambray. A really ironic artisan
- whatever keytar
- scenester farm-to-table banksy Austin
- twitter handle
- freegan cred raw denim single-origin coffee viral.
-
-:::
-```vue demo
-
- Tight pants next level keffiyeh
- you probably
- haven't heard of them.
- Photo booth beard raw denim letterpress vegan messenger
- bag stumptown. Farm-to-table seitan, mcsweeney's fixie
- sustainable quinoa 8-bit american apparel
- have a
- terry richardson vinyl chambray. Beard stumptown,
- cardigans banh mi lomo thundercats. Tofu biodiesel
- williamsburg marfa, four loko mcsweeney''s cleanse
- vegan chambray. A really ironic artisan
- whatever keytar
- scenester farm-to-table banksy Austin
- twitter handle
- freegan cred raw denim single-origin coffee viral.
-
-```
-
-Hover over the buttons below to see the four tooltips directions: top, right, bottom, and left. Directions are mirrored when using CoreUI in RTL.
-
-::: demo
-Tooltip on top
-Tooltip on right
-Tooltip on bottom
-Tooltip on left
-:::
\ No newline at end of file
diff --git a/docs/forms/validation.md b/docs/forms/validation.md
deleted file mode 100644
index 1236689f..00000000
--- a/docs/forms/validation.md
+++ /dev/null
@@ -1,620 +0,0 @@
----
-title: Vue Form Validation
-name: Validation
-description: Provide valuable, actionable feedback to your users with HTML5 form validation, via browser default behaviors or custom styles and JavaScript.
----
-
-## Custom styles
-
-For custom CoreUI form validation messages, you'll need to add the `noValidate` boolean property to your ``. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript. Try to submit the form below; our JavaScript will intercept the submit button and relay feedback to you. When attempting to submit, you'll see the `:invalid` and `:valid` styles applied to your form controls.
-
-Custom feedback styles apply custom colors, borders, focus styles, and background icons to better communicate feedback.
-
-::: demo
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
-
-
- You must agree before submitting.
-
-
-
- Submit form
-
-
-:::
-```vue
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
-
-
- You must agree before submitting.
-
-
-
- Submit form
-
-
-```
-
-## Browser defaults
-
-Not interested in custom validation feedback messages or writing JavaScript to change form behaviors? All good, you can use the browser defaults. Try submitting the form below. Depending on your browser and OS, you'll see a slightly different style of feedback.
-
-While these feedback styles cannot be styled with CSS, you can still customize the feedback text through JavaScript.
-
-::: demo
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
-
-
- You must agree before submitting.
-
-
-
- Submit form
-
-
-:::
-```vue
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
-
-
- You must agree before submitting.
-
-
-
- Submit form
-
-
-```
-
-## Server side
-
-We recommend using client-side validation, but in case you require server-side validation, you can indicate invalid and valid form fields with `invalid` and `valid` boolean properties.
-
-For invalid fields, ensure that the invalid feedback/error message is associated with the relevant form field using `aria-describedby` (noting that this attribute allows more than one `id` to be referenced, in case the field already points to additional form text).
-
-
-::: demo
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
-
-
- You must agree before submitting.
-
-
-
- Submit form
-
-
-:::
-```vue
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
-
-
- You must agree before submitting.
-
-
-
- Submit form
-
-
-```
-
-## Supported elements
-
-Validation styles are available for the following form controls and components:
-
-- ``s
-- ``s
-- ``s
-- ``s
-
-::: demo
-
-
- Textarea
-
-
- Please enter a message in the textarea.
-
-
-
- Example invalid feedback text
-
-
- More example invalid feedback text
-
-
- Open this select menu
- One
- Two
- Three
-
- Example invalid select feedback
-
-
-
- Example invalid form file feedback
-
-
- Submit form
-
-
-:::
-```vue
-
-
- Textarea
-
-
- Please enter a message in the textarea.
-
-
-
- Example invalid feedback text
-
-
- More example invalid feedback text
-
-
- Open this select menu
- One
- Two
- Three
-
- Example invalid select feedback
-
-
-
- Example invalid form file feedback
-
-
- Submit form
-
-
-```
-
-## Tooltips
-
-If your form layout allows it, you can swap the text for the tooltip to display validation feedback in a styled tooltip. Be sure to have a parent with `position: relative` on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup.
-
-::: demo
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
- Submit form
-
-
-:::
-```vue
-
-
- Email
-
-
- Looks good!
-
-
-
- Email
-
-
- Looks good!
-
-
-
- Username
-
- @
-
-
- Please choose a username.
-
-
-
-
- City
-
-
- Please provide a valid city.
-
-
-
- City
-
- Choose...
- ...
-
-
- Please provide a valid city.
-
-
-
- City
-
-
- Please provide a valid zip.
-
-
-
- Submit form
-
-
-```
-
-
\ No newline at end of file
diff --git a/lerna.json b/lerna.json
new file mode 100644
index 00000000..d8c6d770
--- /dev/null
+++ b/lerna.json
@@ -0,0 +1,6 @@
+{
+ "npmClient": "yarn",
+ "packages": ["packages/*"],
+ "version": "4.10.2",
+ "$schema": "node_modules/lerna/schemas/lerna-schema.json"
+}
diff --git a/package.json b/package.json
index 6d36e3c8..048e9734 100644
--- a/package.json
+++ b/package.json
@@ -1,104 +1,39 @@
{
- "name": "@coreui/vue",
- "description": "UI Components Library for Vue.js",
- "version": "4.0.0-beta.2",
- "config": {
- "version_short": "4.0"
- },
- "main": "dist/index.cjs.js",
- "module": "dist/index.esm.js",
- "files": [
- "src",
- "dist"
+ "private": true,
+ "workspaces": [
+ "packages/*"
],
"scripts": {
- "build": "rollup -c",
- "changelog": "auto-changelog --template build/changelog-template.hbs --commit-limit false --package --backfill-limit 0 --starting-version v4.0.0-alpha.0",
- "docs:api": "vue-docgen -c build/docgen.config.js",
- "docs:dev": "vuepress dev docs --clean-cache",
- "docs:build": "vuepress build docs",
- "lint": "eslint 'src/components/**/*.{js,ts,tsx}'",
- "test": "jest --coverage",
- "test:clear": "jest --clearCache"
- },
- "homepage": "https://coreui.io/vue/",
- "author": "The CoreUI Team (https://github.com/orgs/coreui/people)",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/coreui/coreui-vue.git"
- },
- "bugs": {
- "url": "https://github.com/coreui/coreui-vue/issues"
+ "charts:build": "lerna run --scope \"@coreui/vue-chartjs\" build --stream",
+ "charts:test": "lerna run --scope \"@coreui/vue-chartjs\" test --stream",
+ "charts:test:update": "lerna run --scope \"@coreui/vue-chartjs\" test:update --stream",
+ "docs:api": "lerna run --scope \"@coreui/vue-docs\" api --stream",
+ "docs:dev": "lerna run --scope \"@coreui/vue-docs\" dev --stream",
+ "docs:build": "lerna run --scope \"@coreui/vue-docs\" build --stream",
+ "docs:dist": "lerna run --scope \"@coreui/vue-docs\" dist --stream",
+ "icons:build": "lerna run --scope \"@coreui/icons-vue\" build --stream",
+ "icons:test": "lerna run --scope \"@coreui/icons-vue\" test --stream",
+ "icons:test:update": "lerna run --scope \"@coreui/icons-vue\" test:update --stream",
+ "lib:build": "lerna run --scope \"@coreui/vue\" build --stream",
+ "lib:test": "lerna run --scope \"@coreui/vue\" test --stream",
+ "lib:test:update": "lerna run --scope \"@coreui/vue\" test:update --stream",
+ "lint": "eslint \"packages/**/src/**/*.{js,ts,tsx}\"",
+ "test": "npm-run-all charts:test icons:test lib:test",
+ "test:update": "npm-run-all charts:test:update icons:test:update lib:test:update"
},
- "license": "MIT",
"devDependencies": {
- "@babel/core": "^7.15.0",
- "@babel/plugin-syntax-jsx": "^7.14.5",
- "@babel/preset-env": "^7.15.0",
- "@babel/preset-typescript": "^7.15.0",
- "@coreui/coreui": "^4.0.1",
- "@coreui/icons": "^2.0.1",
- "@coreui/icons-vue": "^2.0.0-beta.0",
- "@coreui/vue-chartjs": "^2.0.0-beta.0",
- "@popperjs/core": "^2.9.3",
- "@rollup/plugin-commonjs": "^20.0.0",
- "@rollup/plugin-node-resolve": "^13.0.4",
- "@rollup/plugin-typescript": "^8.2.5",
- "@types/jest": "^27.0.1",
- "@typescript-eslint/eslint-plugin": "^4.29.3",
- "@typescript-eslint/parser": "^4.29.3",
- "@vue/compiler-sfc": "^3.2.5",
- "@vue/server-renderer": "^3.2.5",
- "@vue/test-utils": "^2.0.0-rc.4",
- "@vuepress/plugin-toc": "^2.0.0-beta.24",
- "auto-changelog": "^2.3.0",
- "babel-loader": "^8.2.2",
- "eslint": "^7.32.0",
- "eslint-config-prettier": "^8.3.0",
- "eslint-plugin-prettier": "^3.4.1",
- "eslint-plugin-vue": "^7.16.0",
- "jest": "^27.0.6",
- "markdown-it-include": "^2.0.0",
- "postcss": "^8.3.6",
- "postcss-loader": "^6.1.1",
- "prettier": "^2.3.2",
- "requires": "^1.0.2",
- "rollup": "^2.56.3",
- "rollup-plugin-peer-deps-external": "^2.2.4",
- "rollup-plugin-vue": "^6.0.0",
- "ts-jest": "^27.0.5",
- "typescript": "4.3.5",
- "vue": "^3.2.6",
- "vue-docgen-cli": "^4.41.1",
- "vue-jest": "^5.0.0-alpha.7",
- "vue-prism-component": "^2.0.0",
- "vue-router": "^4.0.11",
- "vue-types": "^4.0.3",
- "vuepress": "^2.0.0-beta.24"
- },
- "peerDependencies": {
- "@coreui/coreui": "^4.0.1",
- "vue": "^3.2.5"
- },
- "jest": {
- "preset": "ts-jest",
- "testEnvironment": "jsdom",
- "moduleFileExtensions": [
- "tsx",
- "js",
- "ts",
- "json",
- "vue"
- ],
- "transform": {
- ".*\\.(vue)$": "vue-jest"
- },
- "testRegex": "/src/.*\\.(spec.tsx)$"
- },
- "standard": {
- "ignore": [
- "node_modules/",
- "build/"
- ]
+ "@typescript-eslint/eslint-plugin": "^5.61.0",
+ "@typescript-eslint/parser": "^5.61.0",
+ "@vue/eslint-config-prettier": "^7.1.0",
+ "@vue/eslint-config-typescript": "^11.0.3",
+ "@vue/vue3-jest": "29.2.4",
+ "eslint": "8.44.0",
+ "eslint-plugin-prettier": "^4.2.1",
+ "eslint-plugin-vue": "^9.15.1",
+ "eslint-config-prettier": "^8.8.0",
+ "eslint-plugin-unicorn": "^47.0.0",
+ "lerna": "^7.1.1",
+ "npm-run-all": "^4.1.5",
+ "prettier": "^3.0.0"
}
}
diff --git a/packages/coreui-icons-vue b/packages/coreui-icons-vue
new file mode 160000
index 00000000..4caafa13
--- /dev/null
+++ b/packages/coreui-icons-vue
@@ -0,0 +1 @@
+Subproject commit 4caafa13b155f5f915c3a2a05dbd6d74a1ef8977
diff --git a/packages/coreui-vue-chartjs b/packages/coreui-vue-chartjs
new file mode 160000
index 00000000..cc734c3a
--- /dev/null
+++ b/packages/coreui-vue-chartjs
@@ -0,0 +1 @@
+Subproject commit cc734c3abd6797191096be80e2b0429b37990f25
diff --git a/packages/coreui-vue/.browserslistrc b/packages/coreui-vue/.browserslistrc
new file mode 100644
index 00000000..bd3ad98e
--- /dev/null
+++ b/packages/coreui-vue/.browserslistrc
@@ -0,0 +1,3 @@
+> 1%
+last 2 versions
+not ie <= 8
\ No newline at end of file
diff --git a/packages/coreui-vue/LICENSE b/packages/coreui-vue/LICENSE
new file mode 100644
index 00000000..f19fc729
--- /dev/null
+++ b/packages/coreui-vue/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 creativeLabs Łukasz Holeczek
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/packages/coreui-vue/README.md b/packages/coreui-vue/README.md
new file mode 100644
index 00000000..ba8470df
--- /dev/null
+++ b/packages/coreui-vue/README.md
@@ -0,0 +1,265 @@
+
+
+
+
+
+
+CoreUI for Vue.js
+
+
+ Vue.js Components Library built on top of Bootstrap 5 and TypeScript.
+
+ Explore CoreUI for Vue.js docs »
+
+
+ Report bug
+ ·
+ Request feature
+ ·
+ Blog
+
+
+
+## Table of contents
+
+- [Quick start](#quick-start)
+- [Components](#components)
+- [Status](#status)
+- [Bugs and feature requests](#bugs-and-feature-requests)
+- [Documentation](#documentation)
+- [Frameworks](#frameworks)
+- [Templates](#templates)
+- [Contributing](#contributing)
+- [Community](#community)
+- [Versioning](#versioning)
+- [Creators](#creators)
+- [Support CoreUI Development](#support-coreui-development)
+- [Copyright and license](#copyright-and-license)
+
+## Quick start
+
+### Instalation
+
+Several quick start options are available:
+
+- [Download the latest release](https://github.com/coreui/coreui-vue/archive/v4.10.2.zip)
+- Clone the repo: `git clone https://github.com/coreui/coreui-vue.git`
+- Install with [npm](https://www.npmjs.com/): `npm install @coreui/vue`
+- Install with [yarn](https://yarnpkg.com/): `yarn add @coreui/vue`
+
+Read the [Getting started page](https://coreui.io/vue/docs/getting-started/introduction/) for information on the framework contents, templates and examples, and more.
+
+### Stylesheets
+
+Vue components are styled using `@coreui/coreui` CSS library, but you can use them also with bootstrap CSS library. That is possible because `@coreui/coreui` library is compatible with bootstrap, it just extends its functionalities. The only exception are custom CoreUI components, which don't exist in the Bootstrap ecosystem.
+
+#### CoreUI CSS files
+
+##### Installation
+
+```bash
+yarn add @coreui/coreui
+```
+
+or
+
+```bash
+npm install @coreui/coreui --save
+```
+
+##### Basic usage
+
+```js
+import '@coreui/coreui/dist/css/coreui.min.css'
+```
+
+#### Bootstrap CSS files
+
+##### Installation
+
+```bash
+yarn add bootstrap
+```
+
+or
+
+```bash
+npm install bootstrap
+```
+
+##### Basic usage
+
+```js
+import "bootstrap/dist/css/bootstrap.min.css";
+```
+
+## Components
+
+- [Vue Accordion](https://coreui.io/vue/docs/components/accordion.html)
+- [Vue Alert](https://coreui.io/vue/docs/components/alert.html)
+- [Vue Avatar](https://coreui.io/vue/docs/components/avatar.html)
+- [Vue Badge](https://coreui.io/vue/docs/components/badge.html)
+- [Vue Breadcrumb](https://coreui.io/vue/docs/components/breadcrumb.html)
+- [Vue Button](https://coreui.io/vue/docs/components/button.html)
+- [Vue Button Group](https://coreui.io/vue/docs/components/button-group.html)
+- [Vue Callout](https://coreui.io/vue/docs/components/callout.html)
+- [Vue Card](https://coreui.io/vue/docs/components/card.html)
+- [Vue Carousel](https://coreui.io/vue/docs/components/carousel.html)
+- [Vue Checkbox](https://coreui.io/vue/docs/forms/checkbox.html)
+- [Vue Close Button](https://coreui.io/vue/docs/components/close-button.html)
+- [Vue Collapse](https://coreui.io/vue/docs/components/collapse.html)
+- [Vue Date Picker](https://coreui.io/vue/docs/forms/date-picker.html) **PRO**
+- [Vue Date Range Picker](https://coreui.io/vue/docs/forms/date-range-picker.html) **PRO**
+- [Vue Dropdown](https://coreui.io/vue/docs/components/dropdown.html)
+- [Vue Floating Labels](https://coreui.io/vue/docs/forms/floating-labels.html)
+- [Vue Footer](https://coreui.io/vue/docs/components/footer.html)
+- [Vue Header](https://coreui.io/vue/docs/components/header.html)
+- [Vue Image](https://coreui.io/vue/docs/components/image.html)
+- [Vue Input](https://coreui.io/vue/docs/forms/input.html)
+- [Vue Input Group](https://coreui.io/vue/docs/forms/input-group.html)
+- [Vue List Group](https://coreui.io/vue/docs/components/list-group.html)
+- [Vue Loading Button](https://coreui.io/vue/docs/components/loading-button.html) **PRO**
+- [Vue Modal](https://coreui.io/vue/docs/components/modal.html)
+- [Vue Multi Select](https://coreui.io/vue/docs/forms/multi-select.html) **PRO**
+- [Vue Navs & Tabs](https://coreui.io/vue/docs/components/navs-tabs.html)
+- [Vue Navbar](https://coreui.io/vue/docs/components/navbar.html)
+- [Vue Offcanvas](https://coreui.io/vue/docs/components/offcanvas.html)
+- [Vue Pagination](https://coreui.io/vue/docs/components/pagination.html)
+- [Vue Placeholder](https://coreui.io/vue/docs/components/placeholder.html)
+- [Vue Popover](https://coreui.io/vue/docs/components/popover.html)
+- [Vue Progress](https://coreui.io/vue/docs/components/progress.html)
+- [Vue Radio](https://coreui.io/vue/docs/forms/radio.html)
+- [Vue Range](https://coreui.io/vue/docs/forms/range.html)
+- [Vue Select](https://coreui.io/vue/docs/forms/select.html)
+- [Vue Sidebar](https://coreui.io/vue/docs/components/sidebar.html)
+- [Vue Smart Pagination](https://coreui.io/vue/docs/components/smart-pagination.html) **PRO**
+- [Vue Smart Table](https://coreui.io/vue/docs/components/smart-table.html) **PRO**
+- [Vue Spinner](https://coreui.io/vue/docs/components/spinner.html)
+- [Vue Switch](https://coreui.io/vue/docs/forms/switch.html)
+- [Vue Table](https://coreui.io/vue/docs/components/table.html)
+- [Vue Textarea](https://coreui.io/vue/docs/forms/textarea.html)
+- [Vue Time Picker](https://coreui.io/vue/docs/forms/time-picker.html) **PRO**
+- [Vue Toast](https://coreui.io/vue/docs/components/toast.html)
+- [Vue Tooltip](https://coreui.io/vue/docs/components/tooltip.html)
+
+## Status
+
+[](https://github.com/coreui/coreui-vue/actions?query=workflow%3AJS+Tests+branch%3Amain)
+[](https://www.npmjs.com/package/@coreui/vue)
+[](https://david-dm.org/coreui/coreui?type=peer)
+[](https://david-dm.org/coreui/coreui?type=dev)
+[](https://coveralls.io/github/coreui/coreui-vue?branch=v4)
+
+## Bugs and feature requests
+
+Have a bug or a feature request? Please first read the [issue guidelines](https://github.com/coreui/coreui-vue/blob/main/.github/CONTRIBUTING.md#using-the-issue-tracker) and search for existing and closed issues. If your problem or idea is not addressed yet, [please open a new issue](https://github.com/coreui/coreui-vue/issues/new).
+
+## Documentation
+
+The documentation for the CoreUI & CoreUI PRO is hosted at our website [CoreUI for Vue](https://coreui.io/vue/docs/getting-started/introduction)
+
+### Running documentation locally
+
+1. Run `yarn install` or `npm install` to install the Node.js dependencies.
+2. Run `yarn bootstrap` or `npm run bootstrap` to link local packages together and install remaining package dependencies.
+3. From the root directory, run `yarn docs:dev` or `npm run docs:dev` (or a specific npm script) to rebuild distributed CSS and JavaScript files, as well as our docs assets.
+4. Open `http://localhost:8000/` in your browser, and voilà.
+
+## Frameworks
+
+CoreUI supports most popular frameworks.
+
+- [CoreUI for Angular](https://github.com/coreui/coreui-angular)
+- [CoreUI for Bootstrap (Vanilla JS)](https://github.com/coreui/coreui)
+- [CoreUI for React](https://github.com/coreui/coreui-react)
+- [CoreUI for Vue](https://github.com/coreui/coreui-vue)
+
+## Templates
+
+Fully featured, out-of-the-box, templates for your application based on CoreUI.
+
+- [Angular Admin Template](https://coreui.io/angular)
+- [Bootstrap Admin Template](https://coreui.io/)
+- [React Admin Template](https://coreui.io/react)
+- [Vue Admin Template](https://coreui.io/vue)
+
+## Contributing
+
+Please read through our [contributing guidelines](https://github.com/coreui/coreui-vue/blob/main/.github/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.
+
+Editor preferences are available in the [editor config](https://github.com/coreui/coreui-vue/blob/main/.editorconfig) for easy use in common text editors. Read more and download plugins at .
+
+## Community
+
+Stay up to date on the development of CoreUI and reach out to the community with these helpful resources.
+
+- Read and subscribe to [The Official CoreUI Blog](https://coreui.io/blog/).
+
+You can also follow [@core_ui on Twitter](https://twitter.com/core_ui).
+
+## Versioning
+
+For transparency into our release cycle and in striving to maintain backward compatibility, CoreUI is maintained under [the Semantic Versioning guidelines](http://semver.org/).
+
+See [the Releases section of our project](https://github.com/coreui/coreui-vue/releases) for changelogs for each release version.
+
+## Creators
+
+**Łukasz Holeczek**
+
+-
+-
+
+**Andrzej Kopański**
+
+-
+
+**The CoreUI Team**
+
+-
+
+## Support CoreUI Development
+
+CoreUI is an MIT-licensed open source project and is completely free to use. However, the amount of effort needed to maintain and develop new features for the project is not sustainable without proper financial backing. You can support development by buying the [CoreUI PRO](https://coreui.io/pricing/) or by becoming a sponsor via [Open Collective](https://opencollective.com/coreui/).
+
+
+
+### Platinum Sponsors
+
+Support this project by [becoming a Platinum Sponsor](https://opencollective.com/coreui/contribute/platinum-sponsor-40959/). A large company logo will be added here with a link to your website.
+
+
+
+### Gold Sponsors
+
+Support this project by [becoming a Gold Sponsor](https://opencollective.com/coreui/contribute/gold-sponsor-40960/). A big company logo will be added here with a link to your website.
+
+
+
+### Silver Sponsors
+
+Support this project by [becoming a Silver Sponsor](https://opencollective.com/coreui/contribute/silver-sponsor-40967/). A medium company logo will be added here with a link to your website.
+
+
+
+### Bronze Sponsors
+
+Support this project by [becoming a Bronze Sponsor](https://opencollective.com/coreui/contribute/bronze-sponsor-40966/). The company avatar will show up here with a link to your OpenCollective Profile.
+
+
+
+### Backers
+
+Thanks to all the backers and sponsors! Support this project by [becoming a backer](https://opencollective.com/coreui/contribute/backer-40965/).
+
+
+
+
+
+## Copyright and license
+
+Copyright 2022 creativeLabs Łukasz Holeczek. Code released under the [MIT License](https://github.com/coreui/coreui-vue/blob/main/LICENSE). Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).
diff --git a/packages/coreui-vue/jest.config.js b/packages/coreui-vue/jest.config.js
new file mode 100644
index 00000000..8367c2b3
--- /dev/null
+++ b/packages/coreui-vue/jest.config.js
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2013-present, creativeLabs Lukasz Holeczek.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+'use strict'
+
+module.exports = {
+ moduleFileExtensions: ['tsx', 'js', 'ts', 'json', 'vue'],
+ preset: 'ts-jest',
+ testEnvironment: 'jsdom',
+ testEnvironmentOptions: {
+ customExportConditions: ['node', 'node-addons'],
+ },
+ testPathIgnorePatterns: ['dist/'],
+ transform: {
+ '.*\\.(ts)$': 'ts-jest',
+ '.*\\.(vue)$': '@vue/vue3-jest',
+ },
+}
diff --git a/packages/coreui-vue/package.json b/packages/coreui-vue/package.json
new file mode 100644
index 00000000..d905abdc
--- /dev/null
+++ b/packages/coreui-vue/package.json
@@ -0,0 +1,66 @@
+{
+ "name": "@coreui/vue",
+ "version": "4.10.2",
+ "description": "UI Components Library for Vue.js",
+ "keywords": [
+ "vue",
+ "vue-component",
+ "vue component",
+ "vue bootstrap",
+ "bootstrap vue",
+ "ui library",
+ "ui components",
+ "component library",
+ "components"
+ ],
+ "homepage": "https://coreui.io/vue/",
+ "bugs": {
+ "url": "https://github.com/coreui/coreui-vue/issues"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/coreui/coreui-vue.git"
+ },
+ "license": "MIT",
+ "author": "The CoreUI Team (https://github.com/orgs/coreui/people)",
+ "main": "dist/index.js",
+ "module": "dist/index.es.js",
+ "types": "dist/index.d.ts",
+ "files": [
+ "dist/",
+ "src/"
+ ],
+ "scripts": {
+ "build": "rollup -c --bundleConfigAsCjs",
+ "test": "jest --coverage",
+ "test:clear": "jest --clearCache",
+ "test:update": "jest --coverage --updateSnapshot"
+ },
+ "devDependencies": {
+ "@popperjs/core": "^2.11.8",
+ "@rollup/plugin-commonjs": "^25.0.2",
+ "@rollup/plugin-node-resolve": "^15.1.0",
+ "@rollup/plugin-typescript": "^11.1.2",
+ "@types/jest": "^29.5.2",
+ "@vue/test-utils": "^2.4.0",
+ "@vue/vue3-jest": "29.2.4",
+ "jest": "^29.6.1",
+ "jest-environment-jsdom": "^29.6.1",
+ "rollup": "^3.26.2",
+ "rollup-plugin-vue": "^6.0.0",
+ "ts-jest": "^29.1.1",
+ "typescript": "^4.9.5",
+ "vue": "^3.3.4",
+ "vue-types": "^5.1.0"
+ },
+ "peerDependencies": {
+ "@coreui/coreui": "^4.2.6",
+ "vue": "^3.2.21"
+ },
+ "standard": {
+ "ignore": [
+ "node_modules/",
+ "build/"
+ ]
+ }
+}
diff --git a/rollup.config.js b/packages/coreui-vue/rollup.config.js
similarity index 67%
rename from rollup.config.js
rename to packages/coreui-vue/rollup.config.js
index 7c97d2ec..c4b5a462 100644
--- a/rollup.config.js
+++ b/packages/coreui-vue/rollup.config.js
@@ -1,12 +1,10 @@
import commonjs from '@rollup/plugin-commonjs'
import typescript from '@rollup/plugin-typescript'
-// import external from 'rollup-plugin-peer-deps-external'
import resolve from '@rollup/plugin-node-resolve'
import vue from 'rollup-plugin-vue'
import pkg from './package.json'
const plugins = [
- // external(),
resolve({
dedupe: ['vue'],
extensions: ['.ts', '.json', '.vue'],
@@ -16,7 +14,7 @@ const plugins = [
tsconfig: './tsconfig.json',
}),
commonjs({
- include: ['node_modules/**'],
+ include: ['../../node_modules/**'],
}),
]
@@ -27,10 +25,15 @@ export default [
{
input: 'src/index.ts',
output: {
- format: 'esm',
+ format: 'es',
file: pkg.module,
exports: 'named',
sourcemap: true,
+ sourcemapPathTransform: (relativeSourcePath) => {
+ return relativeSourcePath
+ .replace('../../node_modules/', '../')
+ .replace('../packages/coreui-vue', '..')
+ },
},
external,
plugins: [...plugins, vue()],
@@ -43,19 +46,13 @@ export default [
file: pkg.main,
exports: 'named',
sourcemap: true,
+ sourcemapPathTransform: (relativeSourcePath) => {
+ return relativeSourcePath
+ .replace('../../node_modules/', '../')
+ .replace('../packages/coreui-vue', '..')
+ },
},
external,
plugins: [...plugins, vue({ template: { optimizeSSR: true } })],
},
- // Browser build.
- // {
- // input: 'src/wrapper.js',
- // output: {
- // format: 'iife',
- // file: 'dist/library.js'
- // },
- // plugins: [
- // vue()
- // ]
- // }
]
diff --git a/packages/coreui-vue/src/components/accordion/CAccordion.ts b/packages/coreui-vue/src/components/accordion/CAccordion.ts
new file mode 100644
index 00000000..eee9a535
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/CAccordion.ts
@@ -0,0 +1,40 @@
+import { defineComponent, h, provide, ref, watch } from 'vue'
+
+const CAccordion = defineComponent({
+ name: 'CAccordion',
+ props: {
+ /**
+ * The active item key.
+ */
+ activeItemKey: [Number, String],
+ /**
+ * Make accordion items stay open when another item is opened
+ */
+ alwaysOpen: Boolean,
+ /**
+ * Removes the default background-color, some borders, and some rounded corners to render accordions edge-to-edge with their parent container.
+ */
+ flush: Boolean,
+ },
+ setup(props, { slots }) {
+ const activeItemKey = ref(props.activeItemKey)
+ const setActiveItemKey = (key: string | number) => {
+ activeItemKey.value = key
+ }
+
+ watch(() => props.activeItemKey, value => activeItemKey.value = value)
+
+ provide('activeItemKey', activeItemKey)
+ provide('alwaysOpen', props.alwaysOpen)
+ provide('setActiveItemKey', setActiveItemKey)
+
+ return () =>
+ h(
+ 'div',
+ { class: ['accordion', { ['accordion-flush']: props.flush }] },
+ slots.default && slots.default(),
+ )
+ },
+})
+
+export { CAccordion }
diff --git a/packages/coreui-vue/src/components/accordion/CAccordionBody.ts b/packages/coreui-vue/src/components/accordion/CAccordionBody.ts
new file mode 100644
index 00000000..4a8d83ff
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/CAccordionBody.ts
@@ -0,0 +1,19 @@
+import { defineComponent, h, inject, Ref } from 'vue'
+import { CCollapse } from '../collapse/CCollapse'
+
+const CAccordionBody = defineComponent({
+ name: 'CAccordionBody',
+ setup(_, { slots }) {
+ const visible = inject('visible') as Ref
+ return () =>
+ h(
+ CCollapse,
+ { class: 'accordion-collapse', visible: visible.value },
+ {
+ default: () => h('div', { class: ['accordion-body'] }, slots.default && slots.default()),
+ },
+ )
+ },
+})
+
+export { CAccordionBody }
diff --git a/packages/coreui-vue/src/components/accordion/CAccordionButton.ts b/packages/coreui-vue/src/components/accordion/CAccordionButton.ts
new file mode 100644
index 00000000..69ab7a00
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/CAccordionButton.ts
@@ -0,0 +1,23 @@
+import { defineComponent, h, inject, Ref } from 'vue'
+
+const CAccordionButton = defineComponent({
+ name: 'CAccordionButton',
+ setup(_, { slots }) {
+ const toggleVisibility = inject('toggleVisibility') as () => void
+ const visible = inject('visible') as Ref
+
+ return () =>
+ h(
+ 'button',
+ {
+ type: 'button',
+ 'aria-expanded': !visible.value,
+ class: ['accordion-button', { ['collapsed']: !visible.value }],
+ onClick: () => toggleVisibility(),
+ },
+ slots.default && slots.default(),
+ )
+ },
+})
+
+export { CAccordionButton }
diff --git a/packages/coreui-vue/src/components/accordion/CAccordionHeader.ts b/packages/coreui-vue/src/components/accordion/CAccordionHeader.ts
new file mode 100644
index 00000000..a74a2821
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/CAccordionHeader.ts
@@ -0,0 +1,22 @@
+import { defineComponent, h } from 'vue'
+import { CAccordionButton } from './CAccordionButton'
+
+const CAccordionHeader = defineComponent({
+ name: 'CAccordionHeader',
+ setup(_, { slots }) {
+ return () =>
+ h(
+ 'div',
+ { class: ['accordion-header'] },
+ h(
+ CAccordionButton,
+ {},
+ {
+ default: () => slots.default && slots.default(),
+ },
+ ),
+ )
+ },
+})
+
+export { CAccordionHeader }
diff --git a/packages/coreui-vue/src/components/accordion/CAccordionItem.ts b/packages/coreui-vue/src/components/accordion/CAccordionItem.ts
new file mode 100644
index 00000000..20575085
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/CAccordionItem.ts
@@ -0,0 +1,33 @@
+import { defineComponent, h, inject, provide, ref, watch, Ref } from 'vue'
+
+const CAccordionItem = defineComponent({
+ name: 'CAccordionItem',
+ props: {
+ /**
+ * The item key.
+ */
+ itemKey: [Number, String],
+ },
+ setup(props, { slots }) {
+ const activeItemKey = inject('activeItemKey') as Ref
+ const alwaysOpen = inject('alwaysOpen') as boolean
+ const setActiveItemKey = inject('setActiveItemKey') as (key: number | string) => void
+
+ const itemKey = ref(props.itemKey ?? Math.random().toString(36).slice(2, 11))
+ const visible = ref(Boolean(activeItemKey.value === itemKey.value))
+
+ watch(activeItemKey, () => (visible.value = Boolean(activeItemKey.value === itemKey.value)))
+
+ const toggleVisibility = () => {
+ visible.value = !visible.value
+ !alwaysOpen && visible && setActiveItemKey(itemKey.value)
+ }
+
+ provide('visible', visible)
+ provide('toggleVisibility', toggleVisibility)
+
+ return () => h('div', { class: ['accordion-item'] }, slots.default && slots.default())
+ },
+})
+
+export { CAccordionItem }
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/CAccordion.spec.ts b/packages/coreui-vue/src/components/accordion/__tests__/CAccordion.spec.ts
new file mode 100644
index 00000000..f4a15e0d
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/CAccordion.spec.ts
@@ -0,0 +1,27 @@
+import { mount } from '@vue/test-utils'
+import { CAccordion as Component } from '../../../index'
+
+const ComponentName = 'CAccordion'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ flush: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('accordion')).toBe(true)
+ expect(defaultWrapper.classes('accordion-flush')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/CAccordionBody.spec.ts b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionBody.spec.ts
new file mode 100644
index 00000000..09b94266
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionBody.spec.ts
@@ -0,0 +1,29 @@
+import { mount } from '@vue/test-utils'
+import { CAccordionBody as Component } from '../../../index'
+
+const ComponentName = 'CAccordionBody'
+
+const defaultWrapper = mount(Component, {
+ global: {
+ provide: {
+ visible: true,
+ },
+ },
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('.accordion-body').classes('accordion-body')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/CAccordionButton.spec.ts b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionButton.spec.ts
new file mode 100644
index 00000000..bbaad1a7
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionButton.spec.ts
@@ -0,0 +1,35 @@
+import { mount } from '@vue/test-utils'
+import { CAccordionButton as Component } from '../../../index'
+
+const ComponentName = 'CAccordionButton'
+
+const toggleVisibility = (v: boolean) => {
+ return v
+}
+
+const defaultWrapper = mount(Component, {
+ global: {
+ provide: {
+ toggleVisibility: toggleVisibility,
+ visible: true,
+ },
+ },
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('accordion-button')).toBe(true)
+ expect(defaultWrapper.classes('collapsed')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/CAccordionHeader.spec.ts b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionHeader.spec.ts
new file mode 100644
index 00000000..4bbf217d
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionHeader.spec.ts
@@ -0,0 +1,29 @@
+import { mount } from '@vue/test-utils'
+import { CAccordionHeader as Component } from '../../../index'
+
+const ComponentName = 'CAccordionHeader'
+
+const defaultWrapper = mount(Component, {
+ global: {
+ provide: {
+ visible: true,
+ },
+ },
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('accordion-header')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/CAccordionItem.spec.ts b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionItem.spec.ts
new file mode 100644
index 00000000..aab28ac8
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/CAccordionItem.spec.ts
@@ -0,0 +1,29 @@
+import { mount } from '@vue/test-utils'
+import { CAccordionItem as Component } from '../../../index'
+
+const ComponentName = 'CAccordionItem'
+
+const defaultWrapper = mount(Component, {
+ global: {
+ provide: {
+ activeItemKey: 1,
+ },
+ },
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('accordion-item')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.ts.snap b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.ts.snap
new file mode 100644
index 00000000..3bd49f3b
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordion.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAccordion component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.ts.snap b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.ts.snap
new file mode 100644
index 00000000..30734b2b
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionBody.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAccordionBody component renders correctly 1`] = `
+"
+
+ "
+`;
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.ts.snap b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.ts.snap
new file mode 100644
index 00000000..fb38caae
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionButton.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAccordionButton component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.ts.snap b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.ts.snap
new file mode 100644
index 00000000..01863eed
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionHeader.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAccordionHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.ts.snap b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.ts.snap
new file mode 100644
index 00000000..cead44ef
--- /dev/null
+++ b/packages/coreui-vue/src/components/accordion/__tests__/__snapshots__/CAccordionItem.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAccordionItem component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/accordion/index.ts b/packages/coreui-vue/src/components/accordion/index.ts
similarity index 83%
rename from src/components/accordion/index.ts
rename to packages/coreui-vue/src/components/accordion/index.ts
index 338a345c..ee2326db 100644
--- a/src/components/accordion/index.ts
+++ b/packages/coreui-vue/src/components/accordion/index.ts
@@ -2,7 +2,6 @@ import { App } from 'vue'
import { CAccordion } from './CAccordion'
import { CAccordionBody } from './CAccordionBody'
import { CAccordionButton } from './CAccordionButton'
-import { CAccordionCollapse } from './CAccordionCollapse'
import { CAccordionHeader } from './CAccordionHeader'
import { CAccordionItem } from './CAccordionItem'
@@ -11,7 +10,6 @@ const CAccordionPlugin = {
app.component(CAccordion.name, CAccordion)
app.component(CAccordionBody.name, CAccordionBody)
app.component(CAccordionButton.name, CAccordionButton)
- app.component(CAccordionCollapse.name, CAccordionCollapse)
app.component(CAccordionHeader.name, CAccordionHeader)
app.component(CAccordionItem.name, CAccordionItem)
},
@@ -22,7 +20,6 @@ export {
CAccordion,
CAccordionBody,
CAccordionButton,
- CAccordionCollapse,
CAccordionHeader,
CAccordionItem,
}
diff --git a/src/components/alert/CAlert.ts b/packages/coreui-vue/src/components/alert/CAlert.ts
similarity index 70%
rename from src/components/alert/CAlert.ts
rename to packages/coreui-vue/src/components/alert/CAlert.ts
index b38cca2c..117c4ee2 100644
--- a/src/components/alert/CAlert.ts
+++ b/packages/coreui-vue/src/components/alert/CAlert.ts
@@ -1,30 +1,29 @@
-import { defineComponent, h, ref, Transition } from 'vue'
+import { defineComponent, h, ref, Transition, watch } from 'vue'
-import { Color } from '../props'
-import { CCloseButton } from '../close-button/CCloseButton'
+import { CCloseButton } from '../close-button'
+
+import { Color } from '../../props'
export const CAlert = defineComponent({
name: 'CAlert',
props: {
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* Optionally add a close button to alert and allow it to self dismisss.
*/
- dismissible: {
- type: Boolean,
- default: false,
- required: false,
- },
+ dismissible: Boolean,
/**
* Set the alert variant to a solid.
+ *
+ * @values 'solid'
*/
variant: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return value === 'solid'
},
@@ -35,29 +34,36 @@ export const CAlert = defineComponent({
visible: {
type: Boolean,
default: true,
- required: false,
},
},
emits: [
/**
- * Event called before the dissmiss animation has started.
+ * Callback fired when the component requests to be closed.
*/
- 'dismiss',
+ 'close',
],
setup(props, { slots, emit }) {
const visible = ref(props.visible)
+
+ watch(
+ () => props.visible,
+ () => {
+ visible.value = props.visible
+ },
+ )
+
const handleDismiss = () => {
visible.value = false
- emit('dismiss')
+ emit('close')
}
return () =>
h(
Transition,
{
- name: 'fade',
- duration: 200,
- enterActiveClass: 'fade show',
+ enterFromClass: '',
+ enterActiveClass: 'fade',
+ enterToClass: 'fade show',
leaveActiveClass: 'fade',
},
{
@@ -69,7 +75,7 @@ export const CAlert = defineComponent({
class: [
'alert',
props.variant === 'solid'
- ? `bg-${props.color} text-white`
+ ? `bg-${props.color} text-white border-0`
: `alert-${props.color}`,
{
[`alert-${props.color}`]: props.color,
diff --git a/src/components/alert/CAlertHeading.ts b/packages/coreui-vue/src/components/alert/CAlertHeading.ts
similarity index 95%
rename from src/components/alert/CAlertHeading.ts
rename to packages/coreui-vue/src/components/alert/CAlertHeading.ts
index dbae5e6e..fbf38c69 100644
--- a/src/components/alert/CAlertHeading.ts
+++ b/packages/coreui-vue/src/components/alert/CAlertHeading.ts
@@ -9,7 +9,6 @@ export const CAlertHeading = defineComponent({
component: {
type: String,
default: 'h4',
- required: false,
},
},
setup(props, { slots }) {
diff --git a/src/components/alert/CAlertLink.ts b/packages/coreui-vue/src/components/alert/CAlertLink.ts
similarity index 100%
rename from src/components/alert/CAlertLink.ts
rename to packages/coreui-vue/src/components/alert/CAlertLink.ts
diff --git a/packages/coreui-vue/src/components/alert/__tests__/CAlert.spec.ts b/packages/coreui-vue/src/components/alert/__tests__/CAlert.spec.ts
new file mode 100644
index 00000000..572cd284
--- /dev/null
+++ b/packages/coreui-vue/src/components/alert/__tests__/CAlert.spec.ts
@@ -0,0 +1,38 @@
+import { shallowMount } from '@vue/test-utils'
+import { CAlert as Component } from '../../'
+
+const ComponentName = 'CAlert'
+const wrapper = shallowMount(Component)
+const customWrapper = shallowMount(Component, {
+ props: {
+ color: 'success',
+ },
+ attrs: {
+ class: 'bazinga',
+ },
+ slots: {
+ default: 'Hello World!',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(wrapper.element).toMatchSnapshot()
+ })
+ it('renders correctly with slot', () => {
+ expect(customWrapper.element).toMatchSnapshot()
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('has a prope class names', () => {
+ expect(customWrapper.find('div').classes('alert')).toBe(true)
+ expect(customWrapper.find('div').classes('alert-success')).toBe(true)
+ })
+ it('default slot contains text', () => {
+ expect(customWrapper.text()).toBe('Hello World!')
+ })
+})
diff --git a/packages/coreui-vue/src/components/alert/__tests__/CAlertHeading.spec.ts b/packages/coreui-vue/src/components/alert/__tests__/CAlertHeading.spec.ts
new file mode 100644
index 00000000..628ba7ad
--- /dev/null
+++ b/packages/coreui-vue/src/components/alert/__tests__/CAlertHeading.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CAlertHeading as Component } from '../../../index'
+
+const ComponentName = 'CAlertHeading'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'h2',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('alert-heading')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('alert-heading')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/alert/__tests__/CAlertLink.spec.ts b/packages/coreui-vue/src/components/alert/__tests__/CAlertLink.spec.ts
new file mode 100644
index 00000000..161ff262
--- /dev/null
+++ b/packages/coreui-vue/src/components/alert/__tests__/CAlertLink.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CAlertLink as Component } from '../../../index'
+
+const ComponentName = 'CAlertLink'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('alert-link')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlert.spec.ts.snap b/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlert.spec.ts.snap
new file mode 100644
index 00000000..cbb36d96
--- /dev/null
+++ b/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlert.spec.ts.snap
@@ -0,0 +1,42 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAlert component renders correctly 1`] = `
+
+
+
+
+
+
+`;
+
+exports[`Loads and display CAlert component renders correctly with slot 1`] = `
+
+
+
+ Hello World!
+
+
+
+
+`;
diff --git a/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.ts.snap b/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.ts.snap
new file mode 100644
index 00000000..c24927f7
--- /dev/null
+++ b/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlertHeading.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CAlertHeading component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CAlertHeading component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.ts.snap b/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.ts.snap
new file mode 100644
index 00000000..02173479
--- /dev/null
+++ b/packages/coreui-vue/src/components/alert/__tests__/__snapshots__/CAlertLink.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAlertLink component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/alert/index.ts b/packages/coreui-vue/src/components/alert/index.ts
similarity index 100%
rename from src/components/alert/index.ts
rename to packages/coreui-vue/src/components/alert/index.ts
diff --git a/src/components/avatar/CAvatar.ts b/packages/coreui-vue/src/components/avatar/CAvatar.ts
similarity index 69%
rename from src/components/avatar/CAvatar.ts
rename to packages/coreui-vue/src/components/avatar/CAvatar.ts
index a891ecd0..27008005 100644
--- a/src/components/avatar/CAvatar.ts
+++ b/packages/coreui-vue/src/components/avatar/CAvatar.ts
@@ -1,5 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color, Shape, TextColor } from '../props'
+
+import { Color, Shape, TextColor } from '../../props'
const CAvatar = defineComponent({
name: 'CAvatar',
@@ -7,22 +8,22 @@ const CAvatar = defineComponent({
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
*
- * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* Select the shape of the component.
*
- * @type 'rounded' | 'rounded-top' | 'rounded-end' | 'rounded-bottom' | 'rounded-start' | 'rounded-circle' | 'rounded-pill' | 'rounded-0' | 'rounded-1' | 'rounded-2' | 'rounded-3' | string
+ * @values 'rounded', 'rounded-top', 'rounded-end', 'rounded-bottom', 'rounded-start', 'rounded-circle', 'rounded-pill', 'rounded-0', 'rounded-1', 'rounded-2', 'rounded-3'
*/
shape: Shape,
/**
* Size the component small, large, or extra large.
+ *
+ * @values 'sm', 'md', 'lg', 'xl'
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['sm', 'md', 'lg', 'xl'].includes(value)
},
@@ -30,20 +31,14 @@ const CAvatar = defineComponent({
/**
* The src attribute for the img element.
*/
- src: {
- type: String,
- default: undefined,
- required: false,
- },
+ src: String,
/**
* Sets the color context of the status indicator to one of CoreUI’s themed colors.
*
- * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
status: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return [
'primary',
@@ -60,7 +55,7 @@ const CAvatar = defineComponent({
/**
* Sets the text color of the component to one of CoreUI’s themed colors.
*
- * @value 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'white' | 'muted' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', 'white', 'muted', 'high-emphasis', 'medium-emphasis', 'disabled', 'high-emphasis-inverse', 'medium-emphasis-inverse', 'disabled-inverse'
*/
textColor: TextColor,
},
diff --git a/packages/coreui-vue/src/components/avatar/__tests__/CAvatar.spec.ts b/packages/coreui-vue/src/components/avatar/__tests__/CAvatar.spec.ts
new file mode 100644
index 00000000..427a120b
--- /dev/null
+++ b/packages/coreui-vue/src/components/avatar/__tests__/CAvatar.spec.ts
@@ -0,0 +1,57 @@
+import { mount } from '@vue/test-utils'
+import { CAvatar as Component } from '../../../index'
+
+const ComponentName = 'CAvatar'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ shape: 'rounded-bottom',
+ size: 'md',
+ src: '/bazinga',
+ status: 'danger',
+ textColor: 'light',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('avatar')).toBe(true)
+ })
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('avatar')).toBe(true)
+ expect(customWrapper.classes('bg-warning')).toBe(true)
+ expect(customWrapper.classes('avatar-md')).toBe(true)
+ expect(customWrapper.classes('text-light')).toBe(true)
+ expect(customWrapper.find('img').classes('avatar-img')).toBe(true)
+ expect(customWrapper.find('img').attributes('src')).toBe('/bazinga')
+ expect(customWrapper.find('span').classes('avatar-status')).toBe(true)
+ expect(customWrapper.find('span').classes('bg-danger')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.ts.snap b/packages/coreui-vue/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.ts.snap
new file mode 100644
index 00000000..5166a5f1
--- /dev/null
+++ b/packages/coreui-vue/src/components/avatar/__tests__/__snapshots__/CAvatar.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CAvatar component renders correctly 1`] = `
+"Default slot
+
+
"
+`;
+
+exports[`Loads and display CAvatar component renders correctly 2`] = `""`;
diff --git a/src/components/avatar/index.ts b/packages/coreui-vue/src/components/avatar/index.ts
similarity index 100%
rename from src/components/avatar/index.ts
rename to packages/coreui-vue/src/components/avatar/index.ts
diff --git a/packages/coreui-vue/src/components/backdrop/CBackdrop.ts b/packages/coreui-vue/src/components/backdrop/CBackdrop.ts
new file mode 100644
index 00000000..adea3428
--- /dev/null
+++ b/packages/coreui-vue/src/components/backdrop/CBackdrop.ts
@@ -0,0 +1,35 @@
+import { defineComponent, h, Transition } from 'vue'
+
+const CBackdrop = defineComponent({
+ name: 'CBackdrop',
+ props: {
+ /**
+ * Toggle the visibility of modal component.
+ */
+ visible: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ setup(props) {
+ return () =>
+ h(
+ Transition,
+ {
+ onEnter: (el) => {
+ el.classList.add('show')
+ },
+ onLeave: (el) => {
+ el.classList.remove('show')
+ },
+ },
+ () =>
+ props.visible &&
+ h('div', {
+ class: 'fade',
+ }),
+ )
+ },
+})
+
+export { CBackdrop }
diff --git a/packages/coreui-vue/src/components/backdrop/__tests__/CBackdrop.spec.ts b/packages/coreui-vue/src/components/backdrop/__tests__/CBackdrop.spec.ts
new file mode 100644
index 00000000..016cf75d
--- /dev/null
+++ b/packages/coreui-vue/src/components/backdrop/__tests__/CBackdrop.spec.ts
@@ -0,0 +1,25 @@
+import { mount } from '@vue/test-utils'
+import { CBackdrop as Component } from '../../../index'
+
+const ComponentName = 'CBackdrop'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.find('div').classes('fade')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.ts.snap b/packages/coreui-vue/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.ts.snap
new file mode 100644
index 00000000..2bf4c264
--- /dev/null
+++ b/packages/coreui-vue/src/components/backdrop/__tests__/__snapshots__/CBackdrop.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CBackdrop component renders correctly 1`] = `
+"
+
+ "
+`;
diff --git a/src/components/backdrop/index.ts b/packages/coreui-vue/src/components/backdrop/index.ts
similarity index 100%
rename from src/components/backdrop/index.ts
rename to packages/coreui-vue/src/components/backdrop/index.ts
diff --git a/packages/coreui-vue/src/components/badge/CBadge.ts b/packages/coreui-vue/src/components/badge/CBadge.ts
new file mode 100644
index 00000000..717adac3
--- /dev/null
+++ b/packages/coreui-vue/src/components/badge/CBadge.ts
@@ -0,0 +1,80 @@
+import { defineComponent, h } from 'vue'
+
+import { Color, Shape, TextColor } from '../../props'
+
+const CBadge = defineComponent({
+ name: 'CBadge',
+ props: {
+ /**
+ * Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
+ */
+ color: Color,
+ /**
+ * Component used for the root node. Either a string to use a HTML element or a component.
+ */
+ component: {
+ type: String,
+ default: 'span',
+ },
+ /**
+ * Position badge in one of the corners of a link or button.
+ *
+ * @values 'top-start', 'top-end', 'bottom-end', 'bottom-start'
+ */
+ position: {
+ type: String,
+ validator: (value: string) => {
+ return ['top-start', 'top-end', 'bottom-end', 'bottom-start'].includes(value)
+ },
+ },
+ /**
+ * Select the shape of the component.
+ *
+ * @values 'rounded', 'rounded-top', 'rounded-end', 'rounded-bottom', 'rounded-start', 'rounded-circle', 'rounded-pill', 'rounded-0', 'rounded-1', 'rounded-2', 'rounded-3'
+ */
+ shape: Shape,
+ /**
+ * Size the component small.
+ *
+ * @values 'sm'
+ */
+ size: {
+ type: String,
+ validator: (value: string) => {
+ return value === 'sm'
+ },
+ },
+ /**
+ * Sets the text color of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', 'white', 'muted', 'high-emphasis', 'medium-emphasis', 'disabled', 'high-emphasis-inverse', 'medium-emphasis-inverse', 'disabled-inverse'
+ */
+ textColor: TextColor,
+ },
+ setup(props, { slots }) {
+ return () =>
+ h(
+ props.component,
+ {
+ class: [
+ 'badge',
+ {
+ [`bg-${props.color}`]: props.color,
+ 'position-absolute translate-middle': props.position,
+ 'top-0': props.position && props.position.includes('top'),
+ 'top-100': props.position && props.position.includes('bottom'),
+ 'start-100': props.position && props.position.includes('end'),
+ 'start-0': props.position && props.position.includes('start'),
+ [`badge-${props.size}`]: props.size,
+ [`text-${props.textColor}`]: props.textColor,
+ },
+ props.shape,
+ ],
+ },
+ slots.default && slots.default(),
+ )
+ },
+})
+export { CBadge }
diff --git a/packages/coreui-vue/src/components/badge/__tests__/CBadge.spec.ts b/packages/coreui-vue/src/components/badge/__tests__/CBadge.spec.ts
new file mode 100644
index 00000000..4d132901
--- /dev/null
+++ b/packages/coreui-vue/src/components/badge/__tests__/CBadge.spec.ts
@@ -0,0 +1,39 @@
+import { shallowMount } from '@vue/test-utils'
+import { CBadge as Component } from '../../'
+
+const ComponentName = 'CBadge'
+const wrapper = shallowMount(Component)
+const customWrapper = shallowMount(Component, {
+ props: {
+ color: 'success',
+ },
+ attrs: {
+ class: 'bazinga',
+ },
+ slots: {
+ default: 'Hello World!',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(wrapper.element).toMatchSnapshot()
+ })
+ it('renders correctly with slot', () => {
+ expect(customWrapper.element).toMatchSnapshot()
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('has a prope class names', () => {
+ expect(customWrapper.classes('bazinga')).toBe(true)
+ expect(customWrapper.classes('badge')).toBe(true)
+ expect(customWrapper.classes('bg-success')).toBe(true)
+ })
+ it('default slot contains text', () => {
+ expect(customWrapper.text()).toBe('Hello World!')
+ })
+})
diff --git a/packages/coreui-vue/src/components/badge/__tests__/__snapshots__/CBadge.spec.ts.snap b/packages/coreui-vue/src/components/badge/__tests__/__snapshots__/CBadge.spec.ts.snap
new file mode 100644
index 00000000..249fb4fd
--- /dev/null
+++ b/packages/coreui-vue/src/components/badge/__tests__/__snapshots__/CBadge.spec.ts.snap
@@ -0,0 +1,15 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CBadge component renders correctly 1`] = `
+
+`;
+
+exports[`Loads and display CBadge component renders correctly with slot 1`] = `
+
+ Hello World!
+
+`;
diff --git a/src/components/badge/index.ts b/packages/coreui-vue/src/components/badge/index.ts
similarity index 100%
rename from src/components/badge/index.ts
rename to packages/coreui-vue/src/components/badge/index.ts
diff --git a/src/components/breadcrumb/CBreadcrumb.ts b/packages/coreui-vue/src/components/breadcrumb/CBreadcrumb.ts
similarity index 100%
rename from src/components/breadcrumb/CBreadcrumb.ts
rename to packages/coreui-vue/src/components/breadcrumb/CBreadcrumb.ts
diff --git a/src/components/breadcrumb/CBreadcrumbItem.ts b/packages/coreui-vue/src/components/breadcrumb/CBreadcrumbItem.ts
similarity index 82%
rename from src/components/breadcrumb/CBreadcrumbItem.ts
rename to packages/coreui-vue/src/components/breadcrumb/CBreadcrumbItem.ts
index 3debd8bc..4b5fa4a6 100644
--- a/src/components/breadcrumb/CBreadcrumbItem.ts
+++ b/packages/coreui-vue/src/components/breadcrumb/CBreadcrumbItem.ts
@@ -6,18 +6,11 @@ const CBreadcrumbItem = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* The `href` attribute for the inner link component.
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
},
setup(props, { slots }) {
diff --git a/packages/coreui-vue/src/components/breadcrumb/__tests__/CBreadcrumb.spec.ts b/packages/coreui-vue/src/components/breadcrumb/__tests__/CBreadcrumb.spec.ts
new file mode 100644
index 00000000..28dee35b
--- /dev/null
+++ b/packages/coreui-vue/src/components/breadcrumb/__tests__/CBreadcrumb.spec.ts
@@ -0,0 +1,28 @@
+import { mount } from '@vue/test-utils'
+import { CBreadcrumb as Component } from '../../../index'
+
+const ComponentName = 'CBreadcrumb'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ class: 'bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.find('ol').text()).toContain('Default slot')
+ expect(defaultWrapper.attributes('aria-label')).toBe('breadcrumb')
+ expect(defaultWrapper.find('ol').classes('breadcrumb')).toBe(true)
+ expect(defaultWrapper.find('ol').classes('bazinga')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.ts b/packages/coreui-vue/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.ts
new file mode 100644
index 00000000..39cc7b07
--- /dev/null
+++ b/packages/coreui-vue/src/components/breadcrumb/__tests__/CBreadcrumbItem.spec.ts
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils'
+import { CBreadcrumbItem as Component } from '../../../index'
+
+const ComponentName = 'CBreadcrumbItem'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('breadcrumb-item')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('breadcrumb-item')).toBe(true)
+ expect(customWrapper.attributes('aria-current')).toBe('page')
+ expect(customWrapper.find('a').attributes('href')).toBe('/bazinga')
+ expect(customWrapper.find('a').text()).toContain('Default slot')
+ })
+})
diff --git a/packages/coreui-vue/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.ts.snap b/packages/coreui-vue/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.ts.snap
new file mode 100644
index 00000000..fa56864c
--- /dev/null
+++ b/packages/coreui-vue/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumb.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CBreadcrumb component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
diff --git a/packages/coreui-vue/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.ts.snap b/packages/coreui-vue/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.ts.snap
new file mode 100644
index 00000000..7ffb98a0
--- /dev/null
+++ b/packages/coreui-vue/src/components/breadcrumb/__tests__/__snapshots__/CBreadcrumbItem.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CBreadcrumbItem component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CBreadcrumbItem component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/breadcrumb/index.ts b/packages/coreui-vue/src/components/breadcrumb/index.ts
similarity index 100%
rename from src/components/breadcrumb/index.ts
rename to packages/coreui-vue/src/components/breadcrumb/index.ts
diff --git a/src/components/button-group/CButtonGroup.ts b/packages/coreui-vue/src/components/button-group/CButtonGroup.ts
similarity index 84%
rename from src/components/button-group/CButtonGroup.ts
rename to packages/coreui-vue/src/components/button-group/CButtonGroup.ts
index 8e2c013c..58add3d8 100644
--- a/src/components/button-group/CButtonGroup.ts
+++ b/packages/coreui-vue/src/components/button-group/CButtonGroup.ts
@@ -6,12 +6,10 @@ const CButtonGroup = defineComponent({
/**
* Size the component small or large.
*
- * @type {'sm' | 'lg'}
+ * @values 'sm', 'lg'
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['sm', 'lg'].includes(value)
},
@@ -19,10 +17,7 @@ const CButtonGroup = defineComponent({
/**
* Create a set of buttons that appear vertically stacked rather than horizontally. Split button dropdowns are not supported here.
*/
- vertical: {
- type: Boolean,
- required: false,
- },
+ vertical: Boolean,
},
setup(props, { slots }) {
return () =>
diff --git a/src/components/button-group/CButtonToolbar.ts b/packages/coreui-vue/src/components/button-group/CButtonToolbar.ts
similarity index 100%
rename from src/components/button-group/CButtonToolbar.ts
rename to packages/coreui-vue/src/components/button-group/CButtonToolbar.ts
diff --git a/packages/coreui-vue/src/components/button-group/__tests__/CButtonGroup.spec.ts b/packages/coreui-vue/src/components/button-group/__tests__/CButtonGroup.spec.ts
new file mode 100644
index 00000000..a3b5faca
--- /dev/null
+++ b/packages/coreui-vue/src/components/button-group/__tests__/CButtonGroup.spec.ts
@@ -0,0 +1,48 @@
+import { mount } from '@vue/test-utils'
+import { CButtonGroup as Component } from '../../../index'
+
+const ComponentName = 'CButtonGroup'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ size: 'lg',
+ vertical: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('btn-group')).toBe(true)
+ })
+})
+
+describe(`Custom ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('btn-group-vertical')).toBe(true)
+ expect(customWrapper.classes('btn-group-lg')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/button-group/__tests__/CButtonToolbar.spec.ts b/packages/coreui-vue/src/components/button-group/__tests__/CButtonToolbar.spec.ts
new file mode 100644
index 00000000..e6133737
--- /dev/null
+++ b/packages/coreui-vue/src/components/button-group/__tests__/CButtonToolbar.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CButtonToolbar as Component } from '../../../index'
+
+const ComponentName = 'CButtonToolbar'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('btn-toolbar')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.ts.snap b/packages/coreui-vue/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.ts.snap
new file mode 100644
index 00000000..051888f8
--- /dev/null
+++ b/packages/coreui-vue/src/components/button-group/__tests__/__snapshots__/CButtonGroup.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Custom CButtonGroup component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CButtonGroup component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.ts.snap b/packages/coreui-vue/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.ts.snap
new file mode 100644
index 00000000..70a5ee4e
--- /dev/null
+++ b/packages/coreui-vue/src/components/button-group/__tests__/__snapshots__/CButtonToolbar.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CButtonToolbar component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/button-group/index.ts b/packages/coreui-vue/src/components/button-group/index.ts
similarity index 100%
rename from src/components/button-group/index.ts
rename to packages/coreui-vue/src/components/button-group/index.ts
diff --git a/src/components/button/CButton.ts b/packages/coreui-vue/src/components/button/CButton.ts
similarity index 57%
rename from src/components/button/CButton.ts
rename to packages/coreui-vue/src/components/button/CButton.ts
index 8af96295..d5b2421d 100644
--- a/src/components/button/CButton.ts
+++ b/packages/coreui-vue/src/components/button/CButton.ts
@@ -1,5 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color, Shape } from '../props'
+
+import { Color, Shape } from '../../props'
export const CButton = defineComponent({
name: 'CButton',
@@ -7,13 +8,11 @@ export const CButton = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- default: false,
- required: false,
- },
+ active: Boolean,
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
@@ -22,56 +21,75 @@ export const CButton = defineComponent({
component: {
type: String,
default: 'button',
- required: false,
},
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* The href attribute specifies the URL of the page the link goes to.
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
/**
* Select the shape of the component.
+ *
+ * @values 'rounded', 'rounded-top', 'rounded-end', 'rounded-bottom', 'rounded-start', 'rounded-circle', 'rounded-pill', 'rounded-0', 'rounded-1', 'rounded-2', 'rounded-3'
*/
shape: Shape,
/**
* Size the component small or large.
+ *
+ * @values 'sm', 'lg'
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['sm', 'lg'].includes(value)
},
},
+ /**
+ * Specifies the type of button. Always specify the type attribute for the `` element.
+ * Different browsers may use different default types for the `` element.
+ *
+ * @values 'button', 'submit', 'reset'
+ */
+ type: {
+ type: String,
+ default: 'button',
+ validator: (value: string) => {
+ return ['button', 'submit', 'reset'].includes(value)
+ },
+ },
/**
* Set the button variant to an outlined button or a ghost button.
+ *
+ * @values 'ghost', 'outline'
*/
variant: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['ghost', 'outline'].includes(value)
},
},
},
- setup(props, { slots, attrs }) {
+ emits: [
+ /**
+ * Event called when the user clicks on the button.
+ */
+ 'click',
+ ],
+ setup(props, { emit, slots }) {
+ const handleClick = (event: Event) => {
+ if (props.disabled) {
+ return
+ }
+
+ emit('click', event)
+ }
return () =>
h(
props.component,
{
- ...attrs,
class: [
'btn',
props.variant ? `btn-${props.variant}-${props.color}` : `btn-${props.color}`,
@@ -84,6 +102,9 @@ export const CButton = defineComponent({
],
disabled: props.disabled && props.component !== 'a',
...(props.component === 'a' && props.disabled && { 'aria-disabled': true, tabIndex: -1 }),
+ ...(props.component === 'a' && props.href && { href: props.href }),
+ ...(props.component === 'button' && { type: props.type }),
+ onClick: handleClick,
},
slots.default && slots.default(),
)
diff --git a/packages/coreui-vue/src/components/button/__tests__/CButton.spec.ts b/packages/coreui-vue/src/components/button/__tests__/CButton.spec.ts
new file mode 100644
index 00000000..a739380f
--- /dev/null
+++ b/packages/coreui-vue/src/components/button/__tests__/CButton.spec.ts
@@ -0,0 +1,80 @@
+import { mount } from '@vue/test-utils'
+import { CButton as Component } from '../../../index'
+
+const ComponentName = 'CButton'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ color: 'warning',
+ component: 'div',
+ disabled: true,
+ href: '/bazinga',
+ shape: 'rounded-pill',
+ size: 'lg',
+ variant: 'outline',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ color: 'warning',
+ component: 'a',
+ disabled: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('btn')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('btn-outline-warning')).toBe(true)
+ expect(customWrapper.classes('btn-lg')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.classes('rounded-pill')).toBe(true)
+ expect(customWrapper.classes('btn')).toBe(true)
+ expect(customWrapper.attributes('disabled')).toBe('true')
+ })
+})
+
+describe(`Customize (number two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.text()).toContain('Default slot')
+ expect(customWrapperTwo.classes('disabled')).toBe(true)
+ expect(customWrapperTwo.classes('btn')).toBe(true)
+ expect(customWrapperTwo.attributes('aria-disabled')).toBe('true')
+ expect(customWrapperTwo.attributes('tabindex')).toBe('-1')
+ })
+})
diff --git a/packages/coreui-vue/src/components/button/__tests__/__snapshots__/CButton.spec.ts.snap b/packages/coreui-vue/src/components/button/__tests__/__snapshots__/CButton.spec.ts.snap
new file mode 100644
index 00000000..97172f31
--- /dev/null
+++ b/packages/coreui-vue/src/components/button/__tests__/__snapshots__/CButton.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (number two) CButton component renders correctly 1`] = `"Default slot "`;
+
+exports[`Customize CButton component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CButton component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/button/index.ts b/packages/coreui-vue/src/components/button/index.ts
similarity index 100%
rename from src/components/button/index.ts
rename to packages/coreui-vue/src/components/button/index.ts
diff --git a/src/components/callout/CCallout.ts b/packages/coreui-vue/src/components/callout/CCallout.ts
similarity index 79%
rename from src/components/callout/CCallout.ts
rename to packages/coreui-vue/src/components/callout/CCallout.ts
index 18c5b6f3..04947cf2 100644
--- a/src/components/callout/CCallout.ts
+++ b/packages/coreui-vue/src/components/callout/CCallout.ts
@@ -1,5 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+
+import { Color } from '../../props'
const CCallout = defineComponent({
name: 'CCallout',
@@ -7,7 +8,7 @@ const CCallout = defineComponent({
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
*
- * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
},
diff --git a/packages/coreui-vue/src/components/callout/__tests__/CCallout.spec.ts b/packages/coreui-vue/src/components/callout/__tests__/CCallout.spec.ts
new file mode 100644
index 00000000..df2376dc
--- /dev/null
+++ b/packages/coreui-vue/src/components/callout/__tests__/CCallout.spec.ts
@@ -0,0 +1,47 @@
+import { mount } from '@vue/test-utils'
+import { CCallout as Component } from '../../../index'
+
+const ComponentName = 'CCallout'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('callout')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('callout')).toBe(true)
+ expect(customWrapper.classes('callout-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/callout/__tests__/__snapshots__/CCallout.spec.ts.snap b/packages/coreui-vue/src/components/callout/__tests__/__snapshots__/CCallout.spec.ts.snap
new file mode 100644
index 00000000..07edc5ef
--- /dev/null
+++ b/packages/coreui-vue/src/components/callout/__tests__/__snapshots__/CCallout.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCallout component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CCallout component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/callout/index.ts b/packages/coreui-vue/src/components/callout/index.ts
similarity index 100%
rename from src/components/callout/index.ts
rename to packages/coreui-vue/src/components/callout/index.ts
diff --git a/src/components/card/CCard.ts b/packages/coreui-vue/src/components/card/CCard.ts
similarity index 65%
rename from src/components/card/CCard.ts
rename to packages/coreui-vue/src/components/card/CCard.ts
index c5aa19a7..3b63f8ff 100644
--- a/src/components/card/CCard.ts
+++ b/packages/coreui-vue/src/components/card/CCard.ts
@@ -1,5 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color, TextColor } from '../props'
+
+import { Color, TextColor } from '../../props'
const CCard = defineComponent({
name: 'CCard',
@@ -7,13 +8,13 @@ const CCard = defineComponent({
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
*
- * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* Sets the text color context of the component to one of CoreUI’s themed colors.
*
- * @type 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | 'white' | 'muted' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', 'white', 'muted', 'high-emphasis', 'medium-emphasis', 'disabled', 'high-emphasis-inverse', 'medium-emphasis-inverse', 'disabled-inverse'
*/
textColor: TextColor,
},
diff --git a/src/components/card/CCardBody.ts b/packages/coreui-vue/src/components/card/CCardBody.ts
similarity index 100%
rename from src/components/card/CCardBody.ts
rename to packages/coreui-vue/src/components/card/CCardBody.ts
diff --git a/src/components/card/CCardFooter.ts b/packages/coreui-vue/src/components/card/CCardFooter.ts
similarity index 100%
rename from src/components/card/CCardFooter.ts
rename to packages/coreui-vue/src/components/card/CCardFooter.ts
diff --git a/src/components/card/CCardGroup.ts b/packages/coreui-vue/src/components/card/CCardGroup.ts
similarity index 100%
rename from src/components/card/CCardGroup.ts
rename to packages/coreui-vue/src/components/card/CCardGroup.ts
diff --git a/src/components/card/CCardHeader.ts b/packages/coreui-vue/src/components/card/CCardHeader.ts
similarity index 89%
rename from src/components/card/CCardHeader.ts
rename to packages/coreui-vue/src/components/card/CCardHeader.ts
index ea20302f..722ba187 100644
--- a/src/components/card/CCardHeader.ts
+++ b/packages/coreui-vue/src/components/card/CCardHeader.ts
@@ -5,12 +5,9 @@ const CCardHeader = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'div'
*/
component: {
type: String,
- required: false,
default: 'div',
},
},
diff --git a/src/components/card/CCardImage.ts b/packages/coreui-vue/src/components/card/CCardImage.ts
similarity index 70%
rename from src/components/card/CCardImage.ts
rename to packages/coreui-vue/src/components/card/CCardImage.ts
index 178e2312..ee8695b9 100644
--- a/src/components/card/CCardImage.ts
+++ b/packages/coreui-vue/src/components/card/CCardImage.ts
@@ -5,21 +5,18 @@ const CCardImage = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'img'
*/
component: {
type: String,
- required: false,
default: 'img',
},
/**
- * Optionally orientate the image to the top, bottom, or make it overlaid across the card.
+ * Optionally orientate the image to the top, bottom.
+ *
+ * @values 'top', 'bottom'
*/
orientation: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['top', 'bottom'].includes(value)
},
@@ -30,7 +27,7 @@ const CCardImage = defineComponent({
h(
props.component,
{
- class: [props.orientation ? `card-img-${props.orientation}` : 'card-img'],
+ class: `card-img${props.orientation ? `-${props.orientation}` : ''}`,
},
slots.default && slots.default(),
)
diff --git a/src/components/card/CCardImageOverlay.ts b/packages/coreui-vue/src/components/card/CCardImageOverlay.ts
similarity index 100%
rename from src/components/card/CCardImageOverlay.ts
rename to packages/coreui-vue/src/components/card/CCardImageOverlay.ts
diff --git a/src/components/card/CCardLink.ts b/packages/coreui-vue/src/components/card/CCardLink.ts
similarity index 95%
rename from src/components/card/CCardLink.ts
rename to packages/coreui-vue/src/components/card/CCardLink.ts
index d42a94ea..b80d1865 100644
--- a/src/components/card/CCardLink.ts
+++ b/packages/coreui-vue/src/components/card/CCardLink.ts
@@ -10,7 +10,6 @@ const CCardLink = defineComponent({
href: {
type: String,
default: '#',
- required: false,
},
},
setup(props, { slots }) {
diff --git a/src/components/card/CCardSubtitle.ts b/packages/coreui-vue/src/components/card/CCardSubtitle.ts
similarity index 89%
rename from src/components/card/CCardSubtitle.ts
rename to packages/coreui-vue/src/components/card/CCardSubtitle.ts
index 48309289..5a950776 100644
--- a/src/components/card/CCardSubtitle.ts
+++ b/packages/coreui-vue/src/components/card/CCardSubtitle.ts
@@ -5,12 +5,9 @@ const CCardSubtitle = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'h6'
*/
component: {
type: String,
- required: false,
default: 'h6',
},
},
diff --git a/src/components/card/CCardText.ts b/packages/coreui-vue/src/components/card/CCardText.ts
similarity index 89%
rename from src/components/card/CCardText.ts
rename to packages/coreui-vue/src/components/card/CCardText.ts
index 20c051fe..759ff7e8 100644
--- a/src/components/card/CCardText.ts
+++ b/packages/coreui-vue/src/components/card/CCardText.ts
@@ -5,12 +5,9 @@ const CCardText = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'p'
*/
component: {
type: String,
- required: false,
default: 'p',
},
},
diff --git a/src/components/card/CCardTitle.ts b/packages/coreui-vue/src/components/card/CCardTitle.ts
similarity index 89%
rename from src/components/card/CCardTitle.ts
rename to packages/coreui-vue/src/components/card/CCardTitle.ts
index 5a40e3a6..bc540e15 100644
--- a/src/components/card/CCardTitle.ts
+++ b/packages/coreui-vue/src/components/card/CCardTitle.ts
@@ -5,12 +5,9 @@ const CCardTitle = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'h5'
*/
component: {
type: String,
- required: false,
default: 'h5',
},
},
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCard.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCard.spec.ts
new file mode 100644
index 00000000..5831bd1a
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCard.spec.ts
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils'
+import { CCard as Component } from '../../../index'
+
+const ComponentName = 'CCard'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ textColor: 'info',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('card')).toBe(true)
+ expect(customWrapper.classes('bg-warning')).toBe(true)
+ expect(customWrapper.classes('text-info')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardBody.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardBody.spec.ts
new file mode 100644
index 00000000..92e9b639
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardBody.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CCardBody as Component } from '../../../index'
+
+const ComponentName = 'CCardBody'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-body')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardFooter.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardFooter.spec.ts
new file mode 100644
index 00000000..71d4f9ca
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardFooter.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CCardFooter as Component } from '../../../index'
+
+const ComponentName = 'CCardFooter'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-footer')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardGroup.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardGroup.spec.ts
new file mode 100644
index 00000000..0c9cc4ae
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardGroup.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CCardGroup as Component } from '../../../index'
+
+const ComponentName = 'CCardGroup'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-group')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardHeader.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardHeader.spec.ts
new file mode 100644
index 00000000..ded11542
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardHeader.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CCardHeader as Component } from '../../../index'
+
+const ComponentName = 'CCardHeader'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'span',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-header')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('card-header')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardImage.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardImage.spec.ts
new file mode 100644
index 00000000..da8cf0fb
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardImage.spec.ts
@@ -0,0 +1,44 @@
+import { mount } from '@vue/test-utils'
+import { CCardImage as Component } from '../../../index'
+
+const ComponentName = 'CCardImage'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'a',
+ orientation: 'bottom',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-img')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('card-img-bottom')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardImageOverlay.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardImageOverlay.spec.ts
new file mode 100644
index 00000000..65e7639a
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardImageOverlay.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CCardImageOverlay as Component } from '../../../index'
+
+const ComponentName = 'CCardImageOverlay'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-img-overlay')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardLink.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardLink.spec.ts
new file mode 100644
index 00000000..f6be4bda
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardLink.spec.ts
@@ -0,0 +1,27 @@
+import { mount } from '@vue/test-utils'
+import { CCardLink as Component } from '../../../index'
+
+const ComponentName = 'CCardLink'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-link')).toBe(true)
+ expect(defaultWrapper.attributes('href')).toBe('/bazinga')
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardSubtitle.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardSubtitle.spec.ts
new file mode 100644
index 00000000..ae90329c
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardSubtitle.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CCardSubtitle as Component } from '../../../index'
+
+const ComponentName = 'CCardSubtitle'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'h4',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-subtitle')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('card-subtitle')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardText.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardText.spec.ts
new file mode 100644
index 00000000..b77ce9ff
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardText.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CCardText as Component } from '../../../index'
+
+const ComponentName = 'CCardText'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'h4',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-text')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('card-text')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/CCardTitle.spec.ts b/packages/coreui-vue/src/components/card/__tests__/CCardTitle.spec.ts
new file mode 100644
index 00000000..b6628c9f
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/CCardTitle.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CCardTitle as Component } from '../../../index'
+
+const ComponentName = 'CCardTitle'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'h2',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('card-title')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('card-title')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCard.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCard.spec.ts.snap
new file mode 100644
index 00000000..63e0b00a
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCard.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCard component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CCard component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardBody.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardBody.spec.ts.snap
new file mode 100644
index 00000000..ccbee9e9
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardBody.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCardBody component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardFooter.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardFooter.spec.ts.snap
new file mode 100644
index 00000000..456c0ff1
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardFooter.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCardFooter component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardGroup.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardGroup.spec.ts.snap
new file mode 100644
index 00000000..aee3447b
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardGroup.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCardGroup component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardHeader.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardHeader.spec.ts.snap
new file mode 100644
index 00000000..0efe7610
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardHeader.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCardHeader component renders correctly 1`] = `""`;
+
+exports[`Loads and display CCardHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardImage.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardImage.spec.ts.snap
new file mode 100644
index 00000000..50dcb1c1
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardImage.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCardImage component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CCardImage component renders correctly 1`] = `" "`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.ts.snap
new file mode 100644
index 00000000..22382136
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardImageOverlay.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCardImageOverlay component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardLink.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardLink.spec.ts.snap
new file mode 100644
index 00000000..dbe5ad65
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardLink.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCardLink component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.ts.snap
new file mode 100644
index 00000000..e68a43a3
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardSubtitle.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCardSubtitle component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CCardSubtitle component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardText.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardText.spec.ts.snap
new file mode 100644
index 00000000..99086ae3
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardText.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCardText component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CCardText component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardTitle.spec.ts.snap b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardTitle.spec.ts.snap
new file mode 100644
index 00000000..b3fff67e
--- /dev/null
+++ b/packages/coreui-vue/src/components/card/__tests__/__snapshots__/CCardTitle.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCardTitle component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CCardTitle component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/card/index.ts b/packages/coreui-vue/src/components/card/index.ts
similarity index 100%
rename from src/components/card/index.ts
rename to packages/coreui-vue/src/components/card/index.ts
diff --git a/packages/coreui-vue/src/components/carousel/CCarousel.ts b/packages/coreui-vue/src/components/carousel/CCarousel.ts
new file mode 100644
index 00000000..06809d04
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/CCarousel.ts
@@ -0,0 +1,256 @@
+import {
+ defineComponent,
+ h,
+ ref,
+ VNode,
+ onBeforeMount,
+ onMounted,
+ onUpdated,
+ provide,
+ watch,
+} from 'vue'
+
+import { isInViewport } from '../../utils'
+
+const CCarousel = defineComponent({
+ name: 'CCarousel',
+ props: {
+ /**
+ * Adding in the previous and next controls.
+ */
+ controls: Boolean,
+ /**
+ * Add darker controls, indicators, and captions.
+ */
+ dark: Boolean,
+ /**
+ * index of the active item.
+ */
+ index: {
+ type: Number,
+ default: 0,
+ },
+ /**
+ * Adding indicators at the bottom of the carousel for each item.
+ */
+ indicators: Boolean,
+ /**
+ * The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.
+ */
+ interval: {
+ type: [Boolean, Number],
+ default: 5000,
+ },
+ /**
+ * If set to 'hover', pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it.
+ */
+ pause: {
+ type: [Boolean, String],
+ default: 'hover',
+ validator: (value: boolean | string) => {
+ return typeof value === 'boolean' || value === 'hover'
+ },
+ },
+ /**
+ * Set type of the transition.
+ *
+ * @values 'crossfade', 'slide'
+ */
+ transition: {
+ type: String,
+ default: 'slide',
+ validator: (value: string) => {
+ return ['crossfade', 'slide'].includes(value)
+ },
+ },
+ /**
+ * Set whether the carousel should cycle continuously or have hard stops.
+ */
+ wrap: {
+ type: Boolean,
+ default: true,
+ },
+ },
+ setup(props, { slots }) {
+ const carouselRef = ref()
+
+ const active = ref(props.index)
+ const animating = ref(false)
+ const customInterval = ref(props.interval)
+ const direction = ref('next')
+ const items = ref([])
+ const timeout = ref()
+ const visible = ref()
+
+ const setAnimating = (value: boolean) => {
+ animating.value = value
+ }
+ const setCustomInterval = (value: boolean | number) => {
+ customInterval.value = value
+ }
+
+ provide('setAnimating', setAnimating)
+ provide('setCustomInterval', setCustomInterval)
+
+ const pause = () => timeout.value && clearInterval(timeout.value)
+
+ const cycle = () => {
+ pause()
+ if (typeof props.interval === 'number') {
+ timeout.value = setTimeout(
+ () => nextItemWhenVisible(),
+ typeof customInterval.value === 'number' ? customInterval.value : props.interval,
+ )
+ }
+ }
+
+ const handleControlClick = (_direction: string) => {
+ if (animating.value) {
+ return
+ }
+ direction.value = _direction
+ if (_direction === 'next') {
+ active.value === items.value.length - 1 ? (active.value = 0) : active.value++
+ } else {
+ active.value === 0 ? (active.value = items.value.length - 1) : active.value--
+ }
+ }
+
+ const nextItemWhenVisible = () => {
+ // Don't call next when the page isn't visible
+ // or the carousel or its parent isn't visible
+ if (!document.hidden && carouselRef.value && isInViewport(carouselRef.value)) {
+ handleControlClick('next')
+ }
+ }
+
+ const handleIndicatorClick = (index: number) => {
+ if (active.value === index) {
+ return
+ }
+
+ if (active.value < index) {
+ direction.value = 'next'
+ active.value = index
+ return
+ }
+
+ if (active.value > index) {
+ direction.value = 'prev'
+ active.value = index
+ }
+ }
+
+ const handleScroll = () => {
+ visible.value =
+ !document.hidden && carouselRef.value && isInViewport(carouselRef.value) ? true : false
+ }
+
+ onBeforeMount(() => {
+ if (slots.default) {
+ const children =
+ typeof slots.default()[0].type === 'symbol'
+ ? slots.default()[0].children
+ : slots.default()
+
+ if (children && Array.isArray(children)) {
+ // @ts-expect-error TODO: fix types
+ items.value = children.filter((child) => child.type.name === 'CCarouselItem')
+ }
+ }
+ })
+
+ onMounted(() => {
+ window.addEventListener('scroll', handleScroll)
+ })
+
+ onUpdated(() => {
+ watch(animating, () => {
+ if (props.wrap) {
+ !animating.value && cycle()
+ return
+ }
+
+ if (!props.wrap && active.value < items.value.length - 1) {
+ !animating.value && cycle()
+ }
+ })
+ })
+
+ watch(visible, () => {
+ visible.value && cycle()
+ })
+
+ return () =>
+ h(
+ 'div',
+ {
+ class: [
+ 'carousel slide',
+ props.transition === 'crossfade' && 'carousel-fade',
+ props.dark && 'carousel-dark',
+ ],
+ onmouseover: () => props.pause && pause(),
+ onmouseleave: () => cycle(),
+ ref: carouselRef,
+ },
+ [
+ props.indicators &&
+ h(
+ 'div',
+ {
+ class: 'carousel-indicators',
+ },
+ items.value.map((_, index) => {
+ return h('button', {
+ type: 'button',
+ id: index,
+ 'data-coreui-target': '',
+ ...(active.value === index && { class: 'active' }),
+ onClick: () => handleIndicatorClick(index),
+ })
+ }),
+ ),
+ h(
+ 'div',
+ { class: 'carousel-inner' },
+ items.value.map((item, index) => {
+ return h(item, {
+ active: active.value === index ? true : false,
+ direction: direction.value,
+ })
+ }),
+ ),
+ props.controls && [
+ h(
+ 'button',
+ {
+ type: 'button',
+ class: 'carousel-control-prev',
+ 'data-coreui-target': '',
+ onClick: () => handleControlClick('prev'),
+ },
+ [
+ h('span', { class: 'carousel-control-prev-icon', ariaHidden: 'true' }),
+ h('span', { class: 'visually-hidden' }, 'Previous'),
+ ],
+ ),
+ h(
+ 'button',
+ {
+ type: 'button',
+ class: 'carousel-control-next',
+ 'data-coreui-target': '',
+ onClick: () => handleControlClick('next'),
+ },
+ [
+ h('span', { class: 'carousel-control-next-icon', ariaHidden: 'true' }),
+ h('span', { class: 'visually-hidden' }, 'Next'),
+ ],
+ ),
+ ],
+ ],
+ )
+ },
+})
+export { CCarousel }
diff --git a/src/components/carousel/CCarouselCaption.ts b/packages/coreui-vue/src/components/carousel/CCarouselCaption.ts
similarity index 100%
rename from src/components/carousel/CCarouselCaption.ts
rename to packages/coreui-vue/src/components/carousel/CCarouselCaption.ts
diff --git a/src/components/carousel/CCarouselItem.ts b/packages/coreui-vue/src/components/carousel/CCarouselItem.ts
similarity index 65%
rename from src/components/carousel/CCarouselItem.ts
rename to packages/coreui-vue/src/components/carousel/CCarouselItem.ts
index 334101f2..a83022f6 100644
--- a/src/components/carousel/CCarouselItem.ts
+++ b/packages/coreui-vue/src/components/carousel/CCarouselItem.ts
@@ -1,16 +1,28 @@
-import { defineComponent, h, ref, toRefs, watch } from 'vue'
+import { defineComponent, h, inject, ref, toRefs, watch } from 'vue'
const CCarouselItem = defineComponent({
name: 'CCarouselItem',
props: {
+ /**
+ * @ignore
+ */
active: {
type: Boolean,
default: false,
},
+ /**
+ * @ignore
+ */
direction: {
type: String,
default: 'next',
- required: false,
+ },
+ /**
+ * The amount of time to delay between automatically cycling an item.
+ */
+ interval: {
+ type: [Boolean, Number],
+ default: false,
},
},
setup(props, { slots }) {
@@ -20,18 +32,31 @@ const CCarouselItem = defineComponent({
const orderClassName = ref()
const activeClassName = ref(active.value && 'active')
+ // eslint-disable-next-line no-unused-vars
+ const setAnimating = inject('setAnimating') as (value: boolean) => void
+ // eslint-disable-next-line no-unused-vars
+ const setCustomInterval = inject('setCustomInterval') as (value: boolean | number) => void
+
watch(active, (active, prevActive) => {
+ active && setCustomInterval(props.interval)
if (!prevActive && active) {
orderClassName.value = `carousel-item-${props.direction}`
+ setCustomInterval(props.interval)
}
setTimeout(() => {
if (prevActive && !active) {
activeClassName.value = 'active'
}
directionClassName.value = `carousel-item-${props.direction === 'next' ? 'start' : 'end'}`
- }, 1)
+ }, 0)
+
+ carouselItemRef.value.addEventListener('transitionstart', () => {
+ setAnimating(true)
+ })
carouselItemRef.value.addEventListener('transitionend', () => {
+ setAnimating(false)
+
if (active) {
directionClassName.value = ''
orderClassName.value = ''
diff --git a/packages/coreui-vue/src/components/carousel/__tests__/CCarousel.spec.ts b/packages/coreui-vue/src/components/carousel/__tests__/CCarousel.spec.ts
new file mode 100644
index 00000000..a651b682
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/__tests__/CCarousel.spec.ts
@@ -0,0 +1,50 @@
+import { mount } from '@vue/test-utils'
+import { CCarousel as Component } from '../../../index'
+//import { CCarouselItem } from '../../../index'
+
+// TODO: Add test with CCarouselItem inside CCarousel
+
+const ComponentName = 'CCarousel'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ controls: true,
+ dark: true,
+ index: 1,
+ indicators: true,
+ interval: 3000,
+ transition: 'crossfade',
+ },
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('carousel')).toBe(true)
+ expect(defaultWrapper.classes('slide')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('PreviousNext')
+ expect(customWrapper.classes('carousel')).toBe(true)
+ expect(customWrapper.classes('slide')).toBe(true)
+ expect(customWrapper.classes('carousel-fade')).toBe(true)
+ expect(customWrapper.classes('carousel-dark')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/carousel/__tests__/CCarouselCaption.spec.ts b/packages/coreui-vue/src/components/carousel/__tests__/CCarouselCaption.spec.ts
new file mode 100644
index 00000000..3b360788
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/__tests__/CCarouselCaption.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CCarouselCaption as Component } from '../../../index'
+
+const ComponentName = 'CCarouselCaption'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('carousel-caption')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/carousel/__tests__/CCarouselItem.spec.ts b/packages/coreui-vue/src/components/carousel/__tests__/CCarouselItem.spec.ts
new file mode 100644
index 00000000..6e3b2270
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/__tests__/CCarouselItem.spec.ts
@@ -0,0 +1,78 @@
+import { mount } from '@vue/test-utils'
+import { CCarouselItem as Component } from '../../../index'
+import { nextTick } from 'vue'
+
+const ComponentName = 'CCarouselItem'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ direction: 'prev',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('carousel-item')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('carousel-item')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('carousel-item-end')).toBe(false)
+ expect(customWrapper.classes('carousel-item-prev')).toBe(false)
+ customWrapper.setProps({
+ active: false,
+ })
+ expect(customWrapper.classes('carousel-item')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('carousel-item-end')).toBe(false)
+ expect(customWrapper.classes('carousel-item-prev')).toBe(false)
+ nextTick()
+ setTimeout(() => {
+ expect(customWrapper.classes('carousel-item')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('carousel-item-end')).toBe(true)
+ expect(customWrapper.classes('carousel-item-prev')).toBe(true)
+ }, 2)
+ customWrapper.setProps({
+ active: true,
+ })
+ expect(customWrapper.classes('carousel-item')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('carousel-item-end')).toBe(false)
+ expect(customWrapper.classes('carousel-item-prev')).toBe(false)
+ nextTick()
+ setTimeout(() => {
+ expect(customWrapper.classes('carousel-item')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('carousel-item-end')).toBe(true)
+ expect(customWrapper.classes('carousel-item-prev')).toBe(true)
+ }, 2)
+ //expect(customWrapper.classes('carousel-item-end')).toBe(true)
+ //expect(customWrapper.classes('carousel-item-prev')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.ts.snap b/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.ts.snap
new file mode 100644
index 00000000..4bbd0a71
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarousel.spec.ts.snap
@@ -0,0 +1,16 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCarousel component renders correctly 1`] = `
+""
+`;
+
+exports[`Loads and display CCarousel component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarouselCaption.spec.ts.snap b/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarouselCaption.spec.ts.snap
new file mode 100644
index 00000000..cdb87682
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarouselCaption.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCarouselCaption component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarouselItem.spec.ts.snap b/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarouselItem.spec.ts.snap
new file mode 100644
index 00000000..aa272697
--- /dev/null
+++ b/packages/coreui-vue/src/components/carousel/__tests__/__snapshots__/CCarouselItem.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCarouselItem component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CCarouselItem component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/carousel/index.ts b/packages/coreui-vue/src/components/carousel/index.ts
similarity index 100%
rename from src/components/carousel/index.ts
rename to packages/coreui-vue/src/components/carousel/index.ts
diff --git a/src/components/close-button/CCloseButton.ts b/packages/coreui-vue/src/components/close-button/CCloseButton.ts
similarity index 74%
rename from src/components/close-button/CCloseButton.ts
rename to packages/coreui-vue/src/components/close-button/CCloseButton.ts
index 5d99a2fe..6e329f9e 100644
--- a/src/components/close-button/CCloseButton.ts
+++ b/packages/coreui-vue/src/components/close-button/CCloseButton.ts
@@ -6,25 +6,29 @@ export const CCloseButton = defineComponent({
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* Change the default color to white.
*/
- white: {
- type: Boolean,
- required: false,
- },
+ white: Boolean,
},
- emits: ['click'],
+ emits: [
+ /**
+ * Event called when the user clicks on the component.
+ */
+ 'click',
+ ],
setup(props, { emit }) {
const handleClick = () => {
+ if (props.disabled) {
+ return
+ }
+
emit('click')
}
return () =>
h('button', {
+ type: 'button',
class: [
'btn',
'btn-close',
diff --git a/packages/coreui-vue/src/components/close-button/__tests__/CCloseButton.spec.ts b/packages/coreui-vue/src/components/close-button/__tests__/CCloseButton.spec.ts
new file mode 100644
index 00000000..ea76ee3e
--- /dev/null
+++ b/packages/coreui-vue/src/components/close-button/__tests__/CCloseButton.spec.ts
@@ -0,0 +1,48 @@
+import { mount } from '@vue/test-utils'
+import { CCloseButton as Component } from '../../../index'
+
+const ComponentName = 'CCloseButton'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ disabled: true,
+ white: true,
+ },
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('btn')).toBe(true)
+ expect(defaultWrapper.classes('btn-close')).toBe(true)
+ })
+ it('emit on click', () => {
+ defaultWrapper.trigger('click')
+ const incrementEvent = defaultWrapper.emitted('click')
+ expect(incrementEvent).toHaveLength(1)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('btn')).toBe(true)
+ expect(customWrapper.classes('btn-close')).toBe(true)
+ expect(customWrapper.classes('btn-close-white')).toBe(true)
+ expect(customWrapper.attributes('aria-label')).toBe('Close')
+ expect(customWrapper.attributes('disabled')).toBe('')
+ })
+})
diff --git a/packages/coreui-vue/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.ts.snap b/packages/coreui-vue/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.ts.snap
new file mode 100644
index 00000000..09672fff
--- /dev/null
+++ b/packages/coreui-vue/src/components/close-button/__tests__/__snapshots__/CCloseButton.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCloseButton component renders correctly 1`] = `" "`;
+
+exports[`Loads and display CCloseButton component renders correctly 1`] = `" "`;
diff --git a/src/components/close-button/index.ts b/packages/coreui-vue/src/components/close-button/index.ts
similarity index 100%
rename from src/components/close-button/index.ts
rename to packages/coreui-vue/src/components/close-button/index.ts
diff --git a/packages/coreui-vue/src/components/collapse/CCollapse.ts b/packages/coreui-vue/src/components/collapse/CCollapse.ts
new file mode 100644
index 00000000..c495f147
--- /dev/null
+++ b/packages/coreui-vue/src/components/collapse/CCollapse.ts
@@ -0,0 +1,112 @@
+import { defineComponent, h, Transition, ref, RendererElement, withDirectives } from 'vue'
+
+import { vVisible } from '../../directives/v-c-visible'
+import { executeAfterTransition } from '../../utils/transition'
+
+const CCollapse = defineComponent({
+ name: 'CCollapse',
+ props: {
+ /**
+ * Set horizontal collapsing to transition the width instead of height.
+ */
+ horizontal: Boolean,
+ /**
+ * Toggle the visibility of component.
+ */
+ visible: Boolean,
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { slots, emit }) {
+ const collapsing = ref(false)
+ const show = ref(props.visible)
+
+ const handleBeforeEnter = () => {
+ collapsing.value = true
+ }
+
+ const handleEnter = (el: RendererElement, done: () => void) => {
+ emit('show')
+ // collapsing.value = true
+ setTimeout(() => {
+ executeAfterTransition(() => done(), el as HTMLElement)
+ if (props.horizontal) {
+ el.style.width = `${el.scrollWidth}px`
+ return
+ }
+ el.style.height = `${el.scrollHeight}px`
+ }, 1)
+ }
+
+ const handleAfterEnter = (el: RendererElement) => {
+ show.value = true
+ collapsing.value = false
+ props.horizontal ? el.style.removeProperty('width') : el.style.removeProperty('height')
+ }
+
+ const handleBeforeLeave = (el: RendererElement) => {
+ collapsing.value = true
+ show.value = false
+ if (props.horizontal) {
+ el.style.width = `${el.scrollWidth}px`
+ return
+ }
+ el.style.height = `${el.scrollHeight}px`
+ }
+
+ const handleLeave = (el: RendererElement, done: () => void) => {
+ emit('hide')
+ setTimeout(() => {
+ executeAfterTransition(() => done(), el as HTMLElement)
+ if (props.horizontal) {
+ el.style.width = '0px'
+ return
+ }
+ el.style.height = '0px'
+ }, 1)
+ }
+
+ const handleAfterLeave = (el: RendererElement) => {
+ collapsing.value = false
+ props.horizontal ? el.style.removeProperty('width') : el.style.removeProperty('height')
+ }
+
+ return () =>
+ h(
+ Transition,
+ {
+ css: false,
+ onBeforeEnter: () => handleBeforeEnter(),
+ onEnter: (el, done) => handleEnter(el, done),
+ onAfterEnter: (el) => handleAfterEnter(el),
+ onBeforeLeave: (el) => handleBeforeLeave(el),
+ onLeave: (el, done) => handleLeave(el, done),
+ onAfterLeave: (el) => handleAfterLeave(el),
+ },
+ () =>
+ withDirectives(
+ h(
+ 'div',
+ {
+ class: [
+ collapsing.value ? 'collapsing' : 'collapse',
+ { 'collapse-horizontal': props.horizontal, show: show.value },
+ ],
+ },
+ slots.default && slots.default(),
+ ),
+ [[vVisible, props.visible]],
+ ),
+ )
+ },
+})
+
+export { CCollapse }
diff --git a/packages/coreui-vue/src/components/collapse/__test__/CCollapse.spec.ts b/packages/coreui-vue/src/components/collapse/__test__/CCollapse.spec.ts
new file mode 100644
index 00000000..ddb6f4fe
--- /dev/null
+++ b/packages/coreui-vue/src/components/collapse/__test__/CCollapse.spec.ts
@@ -0,0 +1,44 @@
+import { mount } from '@vue/test-utils'
+import { CCollapse as Component } from '../../../index'
+
+const ComponentName = 'CCollapse'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('div').classes('collapse')).toBe(true)
+ })
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('div').classes('collapse')).toBe(true)
+ expect(customWrapper.find('div').classes('show')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/collapse/__test__/__snapshots__/CCollapse.spec.ts.snap b/packages/coreui-vue/src/components/collapse/__test__/__snapshots__/CCollapse.spec.ts.snap
new file mode 100644
index 00000000..0bab1aef
--- /dev/null
+++ b/packages/coreui-vue/src/components/collapse/__test__/__snapshots__/CCollapse.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CCollapse component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
+
+exports[`Loads and display CCollapse component renders correctly 2`] = `
+"
+ Default slot
+ "
+`;
diff --git a/src/components/collapse/index.ts b/packages/coreui-vue/src/components/collapse/index.ts
similarity index 100%
rename from src/components/collapse/index.ts
rename to packages/coreui-vue/src/components/collapse/index.ts
diff --git a/packages/coreui-vue/src/components/dropdown/CDropdown.ts b/packages/coreui-vue/src/components/dropdown/CDropdown.ts
new file mode 100644
index 00000000..c9b00cf8
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/CDropdown.ts
@@ -0,0 +1,309 @@
+import { defineComponent, h, ref, provide, watch, PropType } from 'vue'
+import type { Placement } from '@popperjs/core'
+
+import { usePopper } from '../../composables'
+import type { Placements, Triggers } from '../../types'
+import { isRTL } from '../../utils'
+
+export type Directions = 'start' | 'end'
+
+export type Breakpoints =
+ | { xs: Directions }
+ | { sm: Directions }
+ | { md: Directions }
+ | { lg: Directions }
+ | { xl: Directions }
+ | { xxl: Directions }
+
+export type Alignments = Directions | Breakpoints
+
+const getPlacement = (
+ placement: Placement,
+ direction: string | undefined,
+ alignment: Alignments | string | undefined,
+ isRTL: boolean,
+): Placements => {
+ let _placement = placement
+
+ if (direction === 'dropup') {
+ _placement = isRTL ? 'top-end' : 'top-start'
+ }
+
+ if (direction === 'dropup-center') {
+ _placement = 'top'
+ }
+
+ if (direction === 'dropend') {
+ _placement = isRTL ? 'left-start' : 'right-start'
+ }
+
+ if (direction === 'dropstart') {
+ _placement = isRTL ? 'right-start' : 'left-start'
+ }
+
+ if (alignment === 'end') {
+ _placement = isRTL ? 'bottom-start' : 'bottom-end'
+ }
+
+ return _placement
+}
+
+const CDropdown = defineComponent({
+ name: 'CDropdown',
+ props: {
+ /**
+ * Set aligment of dropdown menu.
+ *
+ * @values { 'start' | 'end' | { xs: 'start' | 'end' } | { sm: 'start' | 'end' } | { md: 'start' | 'end' } | { lg: 'start' | 'end' } | { xl: 'start' | 'end'} | { xxl: 'start' | 'end'} }
+ */
+ alignment: {
+ type: [String, Object] as PropType,
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ validator: (value: string | any) => {
+ if (value === 'start' || value === 'end') {
+ return true
+ } else {
+ if (value.xs !== undefined && (value.xs === 'start' || value.xs === 'end')) {
+ return true
+ }
+ if (value.sm !== undefined && (value.sm === 'start' || value.sm === 'end')) {
+ return true
+ }
+ if (value.md !== undefined && (value.md === 'start' || value.md === 'end')) {
+ return true
+ }
+ if (value.lg !== undefined && (value.lg === 'start' || value.lg === 'end')) {
+ return true
+ }
+ if (value.xl !== undefined && (value.xl === 'start' || value.xl === 'end')) {
+ return true
+ }
+ if (value.xxl !== undefined && (value.xxl === 'start' || value.xxl === 'end')) {
+ return true
+ }
+ return false
+ }
+ },
+ },
+ /**
+ * Configure the auto close behavior of the dropdown:
+ * - `true` - the dropdown will be closed by clicking outside or inside the dropdown menu.
+ * - `false` - the dropdown will be closed by clicking the toggle button and manually calling hide or toggle method. (Also will not be closed by pressing esc key)
+ * - `'inside'` - the dropdown will be closed (only) by clicking inside the dropdown menu.
+ * - `'outside'` - the dropdown will be closed (only) by clicking outside the dropdown menu.
+ */
+ autoClose: {
+ type: [Boolean, String],
+ default: true,
+ validator: (value: boolean | string) => {
+ return typeof value === 'boolean' || ['inside', 'outside'].includes(value)
+ },
+ },
+ /**
+ * Sets a darker color scheme to match a dark navbar.
+ */
+ dark: Boolean,
+ /**
+ * Sets a specified direction and location of the dropdown menu.
+ *
+ * @values 'center', 'dropup', 'dropup-center', 'dropend', 'dropstart'
+ */
+ direction: {
+ type: String,
+ validator: (value: string) => {
+ return ['center', 'dropup', 'dropup-center', 'dropend', 'dropstart'].includes(value)
+ },
+ },
+ /**
+ * Toggle the disabled state for the component.
+ */
+ disabled: Boolean,
+ /**
+ * Offset of the dropdown menu relative to its target.
+ *
+ * @since 4.9.0
+ */
+ offset: {
+ type: Array,
+ default: () => [0, 2],
+ },
+ /**
+ * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property.
+ *
+ * @values 'auto', 'top-end', 'top', 'top-start', 'bottom-end', 'bottom', 'bottom-start', 'right-start', 'right', 'right-end', 'left-start', 'left', 'left-end'
+ */
+ placement: {
+ type: String as PropType,
+ default: 'bottom-start',
+ },
+ /**
+ * If you want to disable dynamic positioning set this property to `true`.
+ */
+ popper: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them.
+ */
+ trigger: {
+ type: String as PropType,
+ default: 'click',
+ },
+ /**
+ * Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item.
+ *
+ * @values 'btn-group', 'dropdown', 'input-group', 'nav-item'
+ */
+ variant: {
+ type: String,
+ default: 'btn-group',
+ validator: (value: string) => {
+ return ['btn-group', 'dropdown', 'input-group', 'nav-item'].includes(value)
+ },
+ },
+ /**
+ * Toggle the visibility of dropdown menu component.
+ */
+ visible: Boolean,
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { slots, emit }) {
+ const dropdownToggleRef = ref()
+ const dropdownMenuRef = ref()
+ const popper = ref(typeof props.alignment === 'object' ? false : props.popper)
+ const visible = ref(props.visible)
+
+ const { initPopper, destroyPopper } = usePopper()
+
+ const popperConfig = {
+ modifiers: [
+ {
+ name: 'offset',
+ options: {
+ offset: props.offset,
+ },
+ },
+ ],
+ placement: getPlacement(
+ props.placement,
+ props.direction,
+ props.alignment,
+ isRTL(dropdownMenuRef.value),
+ ) as Placement,
+ }
+
+ watch(
+ () => props.visible,
+ () => {
+ visible.value = props.visible
+ },
+ )
+
+ watch(visible, () => {
+ if (visible.value && dropdownToggleRef.value && dropdownMenuRef.value) {
+ popper.value && initPopper(dropdownToggleRef.value, dropdownMenuRef.value, popperConfig)
+ window.addEventListener('mouseup', handleMouseUp)
+ window.addEventListener('keyup', handleKeyup)
+ emit('show')
+ return
+ }
+
+ popper.value && destroyPopper()
+ window.removeEventListener('mouseup', handleMouseUp)
+ window.removeEventListener('keyup', handleKeyup)
+ emit('hide')
+ })
+
+ provide('config', {
+ alignment: props.alignment,
+ dark: props.dark,
+ popper: props.popper,
+ })
+
+ provide('variant', props.variant)
+ provide('visible', visible)
+ provide('dropdownToggleRef', dropdownToggleRef)
+ provide('dropdownMenuRef', dropdownMenuRef)
+
+ const handleKeyup = (event: KeyboardEvent) => {
+ if (props.autoClose === false) {
+ return
+ }
+
+ if (event.key === 'Escape') {
+ setVisible(false)
+ }
+ }
+
+ const handleMouseUp = (event: Event) => {
+ if (!dropdownToggleRef.value || !dropdownMenuRef.value) {
+ return
+ }
+
+ if (dropdownToggleRef.value.contains(event.target as HTMLElement)) {
+ return
+ }
+
+ if (
+ props.autoClose === true ||
+ (props.autoClose === 'inside' &&
+ dropdownMenuRef.value.contains(event.target as HTMLElement)) ||
+ (props.autoClose === 'outside' &&
+ !dropdownMenuRef.value.contains(event.target as HTMLElement))
+ ) {
+ setVisible(false)
+ return
+ }
+ }
+
+ const setVisible = (_visible?: boolean) => {
+ if (props.disabled) {
+ return
+ }
+
+ if (typeof _visible == 'boolean') {
+ visible.value = _visible
+ return
+ }
+
+ if (visible.value === true) {
+ visible.value = false
+ return
+ }
+
+ visible.value = true
+ }
+
+ provide('setVisible', setVisible)
+
+ return () =>
+ props.variant === 'input-group'
+ ? [slots.default && slots.default()]
+ : h(
+ 'div',
+ {
+ class: [
+ props.variant === 'nav-item' ? 'nav-item dropdown' : props.variant,
+ props.direction === 'center'
+ ? 'dropdown-center'
+ : props.direction === 'dropup-center'
+ ? 'dropup dropup-center'
+ : props.direction,
+ ],
+ },
+ slots.default && slots.default(),
+ )
+ },
+})
+
+export { CDropdown }
diff --git a/src/components/dropdown/CDropdownDivider.ts b/packages/coreui-vue/src/components/dropdown/CDropdownDivider.ts
similarity index 100%
rename from src/components/dropdown/CDropdownDivider.ts
rename to packages/coreui-vue/src/components/dropdown/CDropdownDivider.ts
diff --git a/src/components/dropdown/CDropdownHeader.ts b/packages/coreui-vue/src/components/dropdown/CDropdownHeader.ts
similarity index 91%
rename from src/components/dropdown/CDropdownHeader.ts
rename to packages/coreui-vue/src/components/dropdown/CDropdownHeader.ts
index 984443e8..0ee6018e 100644
--- a/src/components/dropdown/CDropdownHeader.ts
+++ b/packages/coreui-vue/src/components/dropdown/CDropdownHeader.ts
@@ -5,13 +5,10 @@ const CDropdownHeader = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'h6'
*/
component: {
type: String,
default: 'h6',
- required: false,
},
},
setup(props, { slots }) {
diff --git a/src/components/dropdown/CDropdownItem.ts b/packages/coreui-vue/src/components/dropdown/CDropdownItem.ts
similarity index 79%
rename from src/components/dropdown/CDropdownItem.ts
rename to packages/coreui-vue/src/components/dropdown/CDropdownItem.ts
index 321c2a32..fdd01393 100644
--- a/src/components/dropdown/CDropdownItem.ts
+++ b/packages/coreui-vue/src/components/dropdown/CDropdownItem.ts
@@ -8,33 +8,22 @@ const CDropdownItem = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Component used for the root node. Either a string to use a HTML element or a component.
*/
component: {
type: String,
default: 'a',
- required: false,
},
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* The href attribute specifies the URL of the page the link goes to.
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
},
setup(props, { slots }) {
return () =>
diff --git a/src/components/dropdown/CDropdownMenu.ts b/packages/coreui-vue/src/components/dropdown/CDropdownMenu.ts
similarity index 66%
rename from src/components/dropdown/CDropdownMenu.ts
rename to packages/coreui-vue/src/components/dropdown/CDropdownMenu.ts
index 49281ebb..43c885e6 100644
--- a/src/components/dropdown/CDropdownMenu.ts
+++ b/packages/coreui-vue/src/components/dropdown/CDropdownMenu.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, inject, toRefs } from 'vue'
+import { defineComponent, h, inject, Ref } from 'vue'
const CDropdownMenu = defineComponent({
name: 'CDropdownMenu',
@@ -11,16 +11,16 @@ const CDropdownMenu = defineComponent({
component: {
type: String,
default: 'div',
- required: false,
},
},
setup(props, { slots }) {
- const dropdownMenuRef = inject('dropdownMenuRef') as any
- const config = inject('config') as any
+ const dropdownMenuRef = inject('dropdownMenuRef') as Ref
+ const config = inject('config') as any // eslint-disable-line @typescript-eslint/no-explicit-any
+ const visible = inject('visible') as Ref
- const { alignment, dark, popper, visible } = toRefs(config)
+ const { alignment, dark, popper } = config
- // eslint-disable-next-line @typescript-eslint/ban-types
+ // eslint-disable-next-line @typescript-eslint/ban-types, unicorn/consistent-function-scoping
const alignmentClassNames = (alignment: object | string) => {
const classNames: string[] = []
if (typeof alignment === 'object') {
@@ -40,10 +40,10 @@ const CDropdownMenu = defineComponent({
{
class: [
'dropdown-menu',
- { 'dropdown-menu-dark': dark.value, show: visible.value },
- alignmentClassNames(alignment.value),
+ { 'dropdown-menu-dark': dark, show: visible.value },
+ alignmentClassNames(alignment),
],
- ...((typeof alignment.value === 'object' || !popper.value) && {
+ ...((typeof alignment === 'object' || !popper) && {
'data-coreui-popper': 'static',
}),
ref: dropdownMenuRef,
diff --git a/packages/coreui-vue/src/components/dropdown/CDropdownToggle.ts b/packages/coreui-vue/src/components/dropdown/CDropdownToggle.ts
new file mode 100644
index 00000000..eb8200fd
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/CDropdownToggle.ts
@@ -0,0 +1,191 @@
+import { cloneVNode, defineComponent, h, inject, onMounted, PropType, Ref, ref } from 'vue'
+
+import { CButton } from '../button'
+
+import { Color, Shape } from '../../props'
+import type { Triggers } from '../../types'
+
+const CDropdownToggle = defineComponent({
+ name: 'CDropdownToggle',
+ props: {
+ /**
+ * Toggle the active state for the component.
+ */
+ active: Boolean,
+ /**
+ * Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
+ */
+ color: Color,
+ /**
+ * Enables pseudo element caret on toggler.
+ */
+ caret: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * Component used for the root node. Either a string to use a HTML element or a component.
+ */
+ component: {
+ type: String,
+ default: 'button',
+ },
+ /**
+ * Create a custom toggler which accepts any content.
+ */
+ custom: Boolean,
+ /**
+ * Toggle the disabled state for the component.
+ */
+ disabled: Boolean,
+ /**
+ * @values 'rounded', 'rounded-top', 'rounded-end', 'rounded-bottom', 'rounded-start', 'rounded-circle', 'rounded-pill', 'rounded-0', 'rounded-1', 'rounded-2', 'rounded-3'
+ */
+ shape: Shape,
+ /**
+ * Size the component small or large.
+ *
+ * @values 'sm', 'lg'
+ */
+ size: {
+ type: String,
+ validator: (value: string) => {
+ return ['sm', 'lg'].includes(value)
+ },
+ },
+ /**
+ * Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` className for proper spacing around the dropdown caret.
+ */
+ split: Boolean,
+ /**
+ * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them.
+ *
+ * @type 'hover' | 'focus' | 'click'
+ */
+ trigger: {
+ type: String as PropType,
+ default: 'click',
+ },
+ /**
+ * Set the button variant to an outlined button or a ghost button.
+ *
+ * @values 'ghost', 'outline'
+ */
+ variant: {
+ type: String,
+ validator: (value: string) => {
+ return ['ghost', 'outline'].includes(value)
+ },
+ },
+ },
+ setup(props, { slots }) {
+ const togglerRef = ref()
+ const dropdownToggleRef = inject('dropdownToggleRef') as Ref
+ const dropdownVariant = inject('variant') as string
+ const visible = inject('visible') as Ref
+ const setVisible = inject('setVisible') as (_visible?: boolean) => void
+
+ const className = [
+ {
+ 'dropdown-toggle': props.caret,
+ 'dropdown-toggle-split': props.split,
+ active: props.active,
+ disabled: props.disabled,
+ },
+ ]
+
+ const triggers = {
+ ...((props.trigger === 'click' || props.trigger.includes('click')) && {
+ onClick: () => {
+ if (props.disabled) {
+ return
+ }
+
+ setVisible()
+ },
+ }),
+ ...((props.trigger === 'focus' || props.trigger.includes('focus')) && {
+ onfocus: () => {
+ if (props.disabled) {
+ return
+ }
+
+ setVisible(true)
+ },
+ onblur: () => {
+ if (props.disabled) {
+ return
+ }
+ setVisible(false)
+ },
+ }),
+ }
+
+ onMounted(() => {
+ if (togglerRef.value) {
+ dropdownToggleRef.value = togglerRef.value.$el
+ }
+ })
+
+ return () =>
+ props.custom
+ ? slots.default &&
+ slots.default().map((slot) =>
+ cloneVNode(slot, {
+ ref: (el) => {
+ togglerRef.value = el
+ },
+ ...triggers,
+ }),
+ )
+ : dropdownVariant === 'nav-item'
+ ? h(
+ 'a',
+ {
+ active: props.active,
+ class: [
+ 'nav-link',
+ className,
+ {
+ show: visible.value,
+ },
+ ],
+ disabled: props.disabled,
+ href: '#',
+ ref: dropdownToggleRef,
+ ...triggers,
+ },
+ { default: () => slots.default && slots.default() },
+ )
+ : h(
+ CButton,
+ {
+ class: [
+ className,
+ {
+ show: visible.value,
+ },
+ ],
+ active: props.active,
+ color: props.color,
+ disabled: props.disabled,
+ ref: (el) => {
+ togglerRef.value = el
+ },
+ shape: props.shape,
+ size: props.size,
+ ...triggers,
+ ...(props.component === 'button' && { type: 'button' }),
+ variant: props.variant,
+ },
+ () =>
+ props.split
+ ? h('span', { class: 'visually-hidden' }, 'Toggle Dropdown')
+ : slots.default && slots.default(),
+ )
+ },
+})
+
+export { CDropdownToggle }
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/CDropdown.spec.ts b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdown.spec.ts
new file mode 100644
index 00000000..a71c136b
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdown.spec.ts
@@ -0,0 +1,70 @@
+import { mount } from '@vue/test-utils'
+import { CDropdown as Component } from '../../../index'
+
+const ComponentName = 'CDropdown'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ alignment: { lg: 'end' },
+ dark: true,
+ direction: 'dropend',
+ disabled: true,
+ placement: 'right-start',
+ popper: false,
+ trigger: 'hover',
+ variant: 'nav-item',
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ variant: 'input-group',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('btn-group')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('nav-item')).toBe(true)
+ expect(customWrapper.classes('dropdown')).toBe(true)
+ })
+})
+
+describe(`Customize (variant number two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.text()).toContain('Default slot')
+ })
+})
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownDivider.spec.ts b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownDivider.spec.ts
new file mode 100644
index 00000000..584b93ca
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownDivider.spec.ts
@@ -0,0 +1,21 @@
+import { mount } from '@vue/test-utils'
+import { CDropdownDivider as Component } from '../../../index'
+
+const ComponentName = 'CDropdownDivider'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('dropdown-divider')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownHeader.spec.ts b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownHeader.spec.ts
new file mode 100644
index 00000000..6ed72559
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownHeader.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CDropdownHeader as Component } from '../../../index'
+
+const ComponentName = 'CDropdownHeader'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'h2',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('dropdown-header')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('dropdown-header')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownItem.spec.ts b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownItem.spec.ts
new file mode 100644
index 00000000..bf153451
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownItem.spec.ts
@@ -0,0 +1,49 @@
+import { mount } from '@vue/test-utils'
+import { CDropdownItem as Component } from '../../../index'
+
+const ComponentName = 'CDropdownItem'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ component: 'div',
+ disabled: true,
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('dropdown-item')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('dropdown-item')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.attributes('href')).toBe('/bazinga')
+ })
+})
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownMenu.spec.ts b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownMenu.spec.ts
new file mode 100644
index 00000000..265388de
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownMenu.spec.ts
@@ -0,0 +1,76 @@
+import { mount } from '@vue/test-utils'
+import { CDropdownMenu as Component } from '../../../index'
+import { ref } from 'vue'
+
+const ComponentName = 'CDropdownMenu'
+
+const config = {
+ alignment: { lg: 'end' },
+ dark: false,
+ popper: true,
+}
+
+const customConfig = {
+ alignment: { lg: 'end' },
+ dark: true,
+ popper: false,
+}
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+ global: {
+ provide: {
+ config: config,
+ dropdownMenuRef: ref(),
+ visible: ref(false),
+ },
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'ul',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+ global: {
+ provide: {
+ config: customConfig,
+ dropdownMenuRef: ref(),
+ visible: ref(true),
+ },
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('dropdown-menu')).toBe(true)
+ expect(defaultWrapper.classes('dropdown-menu-dark')).toBe(false)
+ expect(defaultWrapper.classes('show')).toBe(false)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('li').text()).toContain('Default slot')
+ expect(customWrapper.classes('dropdown-menu')).toBe(true)
+ expect(customWrapper.classes('dropdown-menu-dark')).toBe(true)
+ expect(customWrapper.classes('show')).toBe(true)
+ expect(customWrapper.attributes('data-coreui-popper')).toBe('static')
+ })
+})
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownToggle.spec.ts b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownToggle.spec.ts
new file mode 100644
index 00000000..5af217be
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/CDropdownToggle.spec.ts
@@ -0,0 +1,101 @@
+import { mount } from '@vue/test-utils'
+import { CDropdownToggle as Component } from '../../../index'
+import { ref } from 'vue'
+const ComponentName = 'CDropdownToggle'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ disabled: true,
+ variant: 'outline',
+ color: 'warning',
+ size: 'lg',
+ shape: 'rounded-pill',
+ split: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+ global: {
+ provide: {
+ dropdownToggleRef: ref(),
+ variant: 'input-group',
+ visible: ref(true),
+ toggleMenu: function () {
+ return true
+ },
+ },
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ color: 'warning',
+ caret: false,
+ disabled: true,
+ shape: 'rounded-pill',
+ size: 'lg',
+ split: true,
+ variant: 'outline',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+ global: {
+ provide: {
+ dropdownToggleRef: ref(),
+ variant: 'nav-item',
+ visible: ref(true),
+ toggleMenu: function () {
+ return true
+ },
+ },
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('btn')).toBe(true)
+ expect(defaultWrapper.classes('dropdown-toggle')).toBe(true)
+ expect(defaultWrapper.classes('show')).toBe(true)
+ expect(defaultWrapper.classes('btn-outline-warning')).toBe(true)
+ expect(defaultWrapper.classes('btn-lg')).toBe(true)
+ expect(defaultWrapper.classes('rounded-pill')).toBe(true)
+ expect(defaultWrapper.classes('active')).toBe(true)
+ expect(defaultWrapper.classes('disabled')).toBe(true)
+ expect(defaultWrapper.attributes('disabled')).toBe('')
+ expect(defaultWrapper.find('span').classes('visually-hidden')).toBe(true)
+ expect(defaultWrapper.find('span').text()).toContain('Toggle Dropdown')
+ })
+ /*
+ TODO: Make this click test work
+ it('check on click event', () => {
+ expect(flag).toBe(false)
+ defaultWrapper.trigger('click')
+ expect(flag).toBe(true)
+ })
+ */
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('nav-link')).toBe(true)
+ expect(customWrapper.classes('dropdown-toggle-split')).toBe(true)
+ expect(customWrapper.classes('show')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.attributes('disabled')).toBe('true')
+ expect(customWrapper.attributes('href')).toBe('#')
+ })
+})
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.ts.snap b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.ts.snap
new file mode 100644
index 00000000..9544f410
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdown.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (variant number two) CDropdown component renders correctly 1`] = `"Default slot"`;
+
+exports[`Customize CDropdown component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CDropdown component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.ts.snap b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.ts.snap
new file mode 100644
index 00000000..5df2cb63
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownDivider.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CDropdownDivider component renders correctly 1`] = `" "`;
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.ts.snap b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.ts.snap
new file mode 100644
index 00000000..6ea81ee4
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownHeader.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CDropdownHeader component renders correctly 1`] = `""`;
+
+exports[`Loads and display CDropdownHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.ts.snap b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.ts.snap
new file mode 100644
index 00000000..382f0d56
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownItem.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CDropdownItem component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CDropdownItem component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.ts.snap b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.ts.snap
new file mode 100644
index 00000000..42124bbf
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CDropdownMenu component renders correctly 1`] = `
+""
+`;
+
+exports[`Loads and display CDropdownMenu component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.ts.snap b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.ts.snap
new file mode 100644
index 00000000..9b78d066
--- /dev/null
+++ b/packages/coreui-vue/src/components/dropdown/__tests__/__snapshots__/CDropdownToggle.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CDropdownToggle component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CDropdownToggle component renders correctly 1`] = `"Toggle Dropdown "`;
diff --git a/src/components/dropdown/index.ts b/packages/coreui-vue/src/components/dropdown/index.ts
similarity index 100%
rename from src/components/dropdown/index.ts
rename to packages/coreui-vue/src/components/dropdown/index.ts
diff --git a/src/components/footer/CFooter.ts b/packages/coreui-vue/src/components/footer/CFooter.ts
similarity index 91%
rename from src/components/footer/CFooter.ts
rename to packages/coreui-vue/src/components/footer/CFooter.ts
index 6ecbfb0b..81de0158 100644
--- a/src/components/footer/CFooter.ts
+++ b/packages/coreui-vue/src/components/footer/CFooter.ts
@@ -5,11 +5,11 @@ const CFooter = defineComponent({
props: {
/**
* Place footer in non-static positions.
+ *
+ * @values 'fixed', 'sticky'
*/
position: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['fixed', 'sticky'].includes(value)
},
diff --git a/packages/coreui-vue/src/components/footer/__tests__/CFooter.spec.ts b/packages/coreui-vue/src/components/footer/__tests__/CFooter.spec.ts
new file mode 100644
index 00000000..4a5ba536
--- /dev/null
+++ b/packages/coreui-vue/src/components/footer/__tests__/CFooter.spec.ts
@@ -0,0 +1,44 @@
+import { mount } from '@vue/test-utils'
+import { CFooter as Component } from '../../../index'
+
+const ComponentName = 'CFooter'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ position: 'fixed',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('footer')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('footer')).toBe(true)
+ expect(customWrapper.classes('footer-fixed')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/footer/__tests__/__snapshots__/CFooter.spec.ts.snap b/packages/coreui-vue/src/components/footer/__tests__/__snapshots__/CFooter.spec.ts.snap
new file mode 100644
index 00000000..1cc66859
--- /dev/null
+++ b/packages/coreui-vue/src/components/footer/__tests__/__snapshots__/CFooter.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFooter component renders correctly 1`] = `""`;
+
+exports[`Loads and display CFooter component renders correctly 1`] = `""`;
diff --git a/src/components/footer/index.ts b/packages/coreui-vue/src/components/footer/index.ts
similarity index 100%
rename from src/components/footer/index.ts
rename to packages/coreui-vue/src/components/footer/index.ts
diff --git a/src/components/form/CForm.ts b/packages/coreui-vue/src/components/form/CForm.ts
similarity index 86%
rename from src/components/form/CForm.ts
rename to packages/coreui-vue/src/components/form/CForm.ts
index 6cd172b8..2747caa7 100644
--- a/src/components/form/CForm.ts
+++ b/packages/coreui-vue/src/components/form/CForm.ts
@@ -6,10 +6,7 @@ const CForm = defineComponent({
/**
* Mark a form as validated. If you set it `true`, all validation styles will be applied to the forms component.
*/
- validated: {
- type: Boolean,
- required: false,
- },
+ validated: Boolean,
},
setup(props, { slots }) {
return () =>
diff --git a/packages/coreui-vue/src/components/form/CFormCheck.ts b/packages/coreui-vue/src/components/form/CFormCheck.ts
new file mode 100644
index 00000000..c7ed6edc
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormCheck.ts
@@ -0,0 +1,262 @@
+import { computed, defineComponent, h } from 'vue'
+
+import { CButton } from '../button'
+import { CFormControlValidation } from './CFormControlValidation'
+import { CFormLabel } from './CFormLabel'
+
+const CFormCheck = defineComponent({
+ name: 'CFormCheck',
+ inheritAttrs: false,
+ props: {
+ /**
+ * Create button-like checkboxes and radio buttons.
+ *
+ * @see http://coreui.io/vue/docs/components/button.html
+ */
+ button: Object,
+ /**
+ * Use in conjunction with the v-model directive to specify the value that should be assigned to the bound variable when the checkbox is in the `false` state.
+ *
+ * @since 4.10.0
+ */
+ falseValue: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedback: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedbackInvalid: String,
+ /**
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ feedbackValid: String,
+ /**
+ * Sets hit area to the full area of the component.
+ */
+ hitArea: {
+ type: String,
+ validator: (value: string): boolean => {
+ // The value must match one of these strings
+ return ['full'].includes(value)
+ },
+ },
+ /**
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
+ */
+ id: String,
+ /**
+ * Input Checkbox indeterminate Property
+ */
+ indeterminate: Boolean,
+ /**
+ * Group checkboxes or radios on the same horizontal row by adding.
+ */
+ inline: Boolean,
+ /**
+ * Set component validation state to invalid.
+ */
+ invalid: Boolean,
+ /**
+ * The element represents a caption for a component.
+ */
+ label: String,
+ /**
+ * The default name for a value passed using v-model.
+ */
+ modelValue: {
+ type: [Array, Boolean, String],
+ value: undefined,
+ },
+ /**
+ * Put checkboxes or radios on the opposite side.
+ *
+ * @since 4.8.0
+ */
+ reverse: Boolean,
+ /**
+ * Display validation feedback in a styled tooltip.
+ *
+ * @since 4.3.0
+ */
+ tooltipFeedback: Boolean,
+ /**
+ * Use in conjunction with the v-model directive to specify the value that should be assigned to the bound variable when the checkbox is in the `true` state.
+ *
+ * @since 4.10.0
+ */
+ trueValue: String,
+ /**
+ * Specifies the type of component.
+ *
+ * @values 'checkbox', 'radio'
+ */
+ type: {
+ type: String,
+ default: 'checkbox',
+ },
+ /**
+ * Set component validation state to valid.
+ */
+ valid: Boolean,
+ /**
+ * The value attribute of component.
+ */
+ value: String,
+ },
+ emits: [
+ /**
+ * Event occurs when the checked value has been changed.
+ */
+ 'change',
+ /**
+ * Emit the new value whenever there’s a change event.
+ */
+ 'update:modelValue',
+ ],
+ setup(props, { attrs, emit, slots }) {
+ const handleChange = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('change', event)
+
+ if (props.falseValue && props.trueValue) {
+ emit('update:modelValue', target.checked ? props.trueValue : props.falseValue)
+ return
+ }
+
+ if (props.value && Array.isArray(props.modelValue)) {
+ if (props.modelValue.includes(props.value)) {
+ emit(
+ 'update:modelValue',
+ props.modelValue.filter((value) => value !== props.value),
+ )
+ } else {
+ emit('update:modelValue', [...props.modelValue, props.value])
+ }
+
+ return
+ }
+
+ if (props.value === undefined) {
+ emit('update:modelValue', target.checked)
+ return
+ }
+
+ if (props.value && (props.modelValue === undefined || typeof props.modelValue === 'string')) {
+ emit('update:modelValue', target.checked ? props.value : undefined)
+ }
+ }
+
+ const className = [
+ 'form-check',
+ {
+ 'form-check-inline': props.inline,
+ 'form-check-reverse': props.reverse,
+ 'is-invalid': props.invalid,
+ 'is-valid': props.valid,
+ },
+ attrs.class,
+ ]
+
+ const inputClassName = [
+ props.button ? 'btn-check' : 'form-check-input',
+ {
+ 'is-invalid': props.invalid,
+ 'is-valid': props.valid,
+ 'me-2': props.hitArea,
+ },
+ ]
+
+ const isChecked = computed(() => {
+ if (Array.isArray(props.modelValue)) {
+ return props.modelValue.includes(props.value)
+ }
+
+ if (typeof props.modelValue === 'string') {
+ return props.modelValue === props.value
+ }
+
+ return props.modelValue
+ })
+
+ const formControl = () => {
+ return h('input', {
+ ...attrs,
+ ...((props.modelValue || props.value) && { checked: isChecked.value }),
+ class: inputClassName,
+ id: props.id,
+ indeterminate: props.indeterminate,
+ onChange: (event: InputEvent) => handleChange(event),
+ type: props.type,
+ value: props.value,
+ })
+ }
+
+ const formLabel = () =>
+ props.button
+ ? h(
+ CButton,
+ {
+ component: 'label',
+ ...props.button,
+ ...(props.id && { for: props.id }),
+ },
+ {
+ default: () => (slots.label && slots.label()) || props.label,
+ },
+ )
+ : h(
+ CFormLabel,
+ { class: 'form-check-label', ...(props.id && { for: props.id }) },
+ {
+ default: () => (slots.label && slots.label()) || props.label,
+ },
+ )
+
+ const formValidation = () => {
+ return h(CFormControlValidation, {
+ describedby: attrs['aria-describedby'] as string,
+ feedback: props.feedback,
+ feedbackInvalid: props.feedbackInvalid,
+ feedbackValid: props.feedbackValid,
+ invalid: props.invalid,
+ tooltipFeedback: props.tooltipFeedback,
+ valid: props.valid,
+ })
+ }
+
+ return () =>
+ props.button
+ ? [formControl(), (slots.label || props.label) && formLabel(), formValidation()]
+ : props.label
+ ? props.hitArea
+ ? [
+ h(
+ CFormLabel,
+ {
+ customClassName: className,
+ ...(props.id && { for: props.id }),
+ },
+ [formControl(), props.label],
+ ),
+ formValidation(),
+ ]
+ : h(
+ 'div',
+ {
+ class: className,
+ },
+ [formControl(), props.label && formLabel(), formValidation()],
+ )
+ : formControl()
+ },
+})
+
+export { CFormCheck }
diff --git a/packages/coreui-vue/src/components/form/CFormControlValidation.ts b/packages/coreui-vue/src/components/form/CFormControlValidation.ts
new file mode 100644
index 00000000..e8723aa7
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormControlValidation.ts
@@ -0,0 +1,89 @@
+import { defineComponent, h } from 'vue'
+import { CFormFeedback } from './CFormFeedback'
+
+const CFormControlValidation = defineComponent({
+ name: 'CFormControlValidation',
+ inheritAttrs: false,
+ props: {
+ /**
+ * @ignore
+ */
+ describedby: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedback: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedbackInvalid: String,
+ /**
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ feedbackValid: String,
+ /**
+ * Set component validation state to invalid.
+ */
+ invalid: Boolean,
+ /**
+ * Display validation feedback in a styled tooltip.
+ *
+ * @since 4.3.0
+ */
+ tooltipFeedback: Boolean,
+ /**
+ * Set component validation state to valid.
+ */
+ valid: Boolean,
+ },
+ setup(props, { slots }) {
+ return () => [
+ props.feedback &&
+ (props.valid || props.invalid) &&
+ h(
+ CFormFeedback,
+ {
+ ...(props.invalid && { id: props.describedby }),
+ invalid: props.invalid,
+ tooltip: props.tooltipFeedback,
+ valid: props.valid,
+ },
+ {
+ default: () => (slots.feedback && slots.feedback()) || props.feedback,
+ },
+ ),
+ (props.feedbackInvalid || slots.feedbackInvalid) &&
+ h(
+ CFormFeedback,
+ {
+ id: props.describedby,
+ invalid: true,
+ tooltip: props.tooltipFeedback,
+ },
+ {
+ default: () =>
+ (slots.feedbackInvalid && slots.feedbackInvalid()) || props.feedbackInvalid,
+ },
+ ),
+ (props.feedbackValid || slots.feedbackValid) &&
+ h(
+ CFormFeedback,
+ {
+ tooltip: props.tooltipFeedback,
+ valid: true,
+ },
+ {
+ default: () => (slots.feedbackValid && slots.feedbackValid()) || props.feedbackValid,
+ },
+ ),
+ ]
+ },
+})
+
+export { CFormControlValidation }
diff --git a/packages/coreui-vue/src/components/form/CFormControlWrapper.ts b/packages/coreui-vue/src/components/form/CFormControlWrapper.ts
new file mode 100644
index 00000000..e4aee290
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormControlWrapper.ts
@@ -0,0 +1,112 @@
+import { defineComponent, h } from 'vue'
+import { CFormControlValidation } from './CFormControlValidation'
+import { CFormFloating } from './CFormFloating'
+import { CFormLabel } from './CFormLabel'
+import { CFormText } from './CFormText'
+
+const CFormControlWrapper = defineComponent({
+ name: 'CFormControlWrapper',
+ inheritAttrs: false,
+ props: {
+ ...CFormControlValidation.props,
+ /**
+ * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ floatingLabel: String,
+ /**
+ * @ignore
+ */
+ id: String,
+ /**
+ * Add a caption for a component.
+ *
+ * @since 4.3.0
+ */
+ label: String,
+ /**
+ * Add helper text to the component.
+ *
+ * @since 4.3.0
+ */
+ text: String,
+ },
+ setup(props, { slots }) {
+ const formControlValidation = () =>
+ h(
+ CFormControlValidation,
+ {
+ describedby: props.describedby,
+ feedback: props.feedback,
+ feedbackInvalid: props.feedbackInvalid,
+ feedbackValid: props.feedbackValid,
+ floatingLabel: props.floatingLabel,
+ invalid: props.invalid,
+ tooltipFeedback: props.tooltipFeedback,
+ valid: props.valid,
+ },
+ {
+ ...(slots.feedback && { feedback: () => slots.feedback && slots.feedback() }),
+ ...(slots.feedbackInvalid && {
+ feedbackInvalid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.feedbackValid && {
+ feedbackValid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ },
+ )
+
+ return () =>
+ props.floatingLabel
+ ? h(CFormFloating, () => [
+ slots.default && slots.default(),
+ h(
+ CFormLabel,
+ {
+ for: props.id,
+ },
+ {
+ default: () => (slots.label && slots.label()) || props.label || props.floatingLabel,
+ },
+ ),
+ (props.text || slots.text) &&
+ h(
+ CFormText,
+ {
+ id: props.describedby,
+ },
+ {
+ default: () => (slots.text && slots.text()) || props.text,
+ },
+ ),
+ formControlValidation(),
+ ])
+ : [
+ (props.label || slots.label) &&
+ h(
+ CFormLabel,
+ {
+ for: props.id,
+ },
+ {
+ default: () => (slots.label && slots.label()) || props.label,
+ },
+ ),
+ slots.default && slots.default(),
+ (props.text || slots.text) &&
+ h(
+ CFormText,
+ {
+ id: props.describedby,
+ },
+ {
+ default: () => (slots.text && slots.text()) || props.text,
+ },
+ ),
+ formControlValidation(),
+ ]
+ },
+})
+
+export { CFormControlWrapper }
diff --git a/src/components/form/CFormFeedback.ts b/packages/coreui-vue/src/components/form/CFormFeedback.ts
similarity index 95%
rename from src/components/form/CFormFeedback.ts
rename to packages/coreui-vue/src/components/form/CFormFeedback.ts
index 88ba31c3..3a7d9a16 100644
--- a/src/components/form/CFormFeedback.ts
+++ b/packages/coreui-vue/src/components/form/CFormFeedback.ts
@@ -5,12 +5,9 @@ const CFormFeedback = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'div'
*/
component: {
type: String,
- required: false,
default: 'div',
},
/**
diff --git a/src/components/form/CFormFloating.ts b/packages/coreui-vue/src/components/form/CFormFloating.ts
similarity index 100%
rename from src/components/form/CFormFloating.ts
rename to packages/coreui-vue/src/components/form/CFormFloating.ts
diff --git a/packages/coreui-vue/src/components/form/CFormInput.ts b/packages/coreui-vue/src/components/form/CFormInput.ts
new file mode 100644
index 00000000..68746233
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormInput.ts
@@ -0,0 +1,185 @@
+import { defineComponent, h } from 'vue'
+import { CFormControlWrapper } from './CFormControlWrapper'
+
+export const File = typeof window === 'undefined' ? class File extends Object {} : window.File
+
+const CFormInput = defineComponent({
+ name: 'CFormInput',
+ props: {
+ /**
+ * Toggle the disabled state for the component.
+ */
+ disabled: Boolean,
+
+ // Inherited Props from CFormControlWrapper
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedback: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedbackInvalid: String,
+ /**
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ feedbackValid: String,
+ /**
+ * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ floatingLabel: String,
+ /**
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
+ */
+ id: String,
+ /**
+ * Set component validation state to invalid.
+ */
+ invalid: Boolean,
+ /**
+ * Add a caption for a component.
+ *
+ * @since 4.3.0
+ */
+ label: String,
+ /**
+ * The default name for a value passed using v-model.
+ */
+ modelValue: [File, Number, String],
+ /**
+ * Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`.
+ */
+ plainText: Boolean,
+ /**
+ * Toggle the readonly state for the component.
+ */
+ readonly: Boolean,
+ /**
+ * Size the component small or large.
+ *
+ * @values 'sm' | 'lg'
+ */
+ size: {
+ type: String,
+ validator: (value: string) => {
+ return ['sm', 'lg'].includes(value)
+ },
+ },
+ /**
+ * Add helper text to the component.
+ *
+ * @since 4.3.0
+ */
+ text: String,
+ /**
+ * Display validation feedback in a styled tooltip.
+ *
+ * @since 4.3.0
+ */
+ tooltipFeedback: Boolean,
+ /**
+ * Specifies the type of component.
+ *
+ * @values 'color' | 'file' | 'text' | string
+ */
+ type: {
+ type: String,
+ default: 'text',
+ },
+ /**
+ * Set component validation state to valid.
+ */
+ valid: Boolean,
+ },
+ emits: [
+ /**
+ * Event occurs when the element loses focus, after the content has been changed.
+ */
+ 'change',
+ /**
+ * Event occurs immediately after the value of a component has changed.
+ */
+ 'input',
+ /**
+ * Emit the new value whenever there’s an input or change event.
+ */
+ 'update:modelValue',
+ ],
+ setup(props, { attrs, emit, slots }) {
+ const handleChange = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('change', event)
+ emit('update:modelValue', target.value)
+ }
+
+ const handleInput = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('input', event)
+ emit('update:modelValue', target.value)
+ }
+
+ return () =>
+ h(
+ CFormControlWrapper,
+ {
+ describedby: attrs['aria-describedby'],
+ feedback: props.feedback,
+ feedbackInvalid: props.feedbackInvalid,
+ feedbackValid: props.feedbackValid,
+ floatingLabel: props.floatingLabel,
+ id: props.id,
+ invalid: props.invalid,
+ label: props.label,
+ text: props.text,
+ tooltipFeedback: props.tooltipFeedback,
+ valid: props.valid,
+ },
+ {
+ default: () =>
+ h(
+ 'input',
+ {
+ id: props.id,
+ ...attrs,
+ class: [
+ props.plainText ? 'form-control-plaintext' : 'form-control',
+ {
+ 'form-control-color': props.type === 'color',
+ [`form-control-${props.size}`]: props.size,
+ 'is-invalid': props.invalid,
+ 'is-valid': props.valid,
+ },
+ attrs.class,
+ ],
+ disabled: props.disabled,
+ onChange: (event: InputEvent) => handleChange(event),
+ onInput: (event: InputEvent) => handleInput(event),
+ readonly: props.readonly,
+ type: props.type,
+ ...((props.modelValue || props.modelValue === 0) && { value: props.modelValue }),
+ },
+ slots.default && slots.default(),
+ ),
+ ...(slots.feedback && { feedback: () => slots.feedback && slots.feedback() }),
+ ...(slots.feedbackInvalid && {
+ feedbackInvalid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.feedbackValid && {
+ feedbackValid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.label && { label: () => slots.label && slots.label() }),
+ ...(slots.text && { text: () => slots.text && slots.text() }),
+ },
+ )
+ },
+})
+
+export { CFormInput }
diff --git a/src/components/form/CFormLabel.ts b/packages/coreui-vue/src/components/form/CFormLabel.ts
similarity index 61%
rename from src/components/form/CFormLabel.ts
rename to packages/coreui-vue/src/components/form/CFormLabel.ts
index 758bf0a3..4b98127c 100644
--- a/src/components/form/CFormLabel.ts
+++ b/packages/coreui-vue/src/components/form/CFormLabel.ts
@@ -6,19 +6,14 @@ const CFormLabel = defineComponent({
/**
* A string of all className you want to be applied to the component, and override standard className value.
*/
- customClassName: {
- type: [Array, String],
- default: undefined,
- required: false,
- },
+ customClassName: [Array, String],
},
- setup(props, { attrs, slots }) {
+ setup(props, { slots }) {
return () =>
h(
'label',
{
- ...attrs,
- class: props.customClassName ? props.customClassName : 'form-label',
+ class: props.customClassName ?? 'form-label',
},
slots.default && slots.default(),
)
diff --git a/packages/coreui-vue/src/components/form/CFormRange.ts b/packages/coreui-vue/src/components/form/CFormRange.ts
new file mode 100644
index 00000000..fcefa832
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormRange.ts
@@ -0,0 +1,92 @@
+import { defineComponent, h } from 'vue'
+import { CFormLabel } from './CFormLabel'
+
+const CFormRange = defineComponent({
+ name: 'CFormRange',
+ props: {
+ /**
+ * Toggle the disabled state for the component.
+ */
+ disabled: Boolean,
+ /**
+ * Add a caption for a component.
+ *
+ * @since 4.3.0
+ */
+ label: String,
+ /**
+ * Specifies the maximum value for the component.
+ */
+ max: Number,
+ /**
+ * Specifies the minimum value for the component.
+ */
+ min: Number,
+ /**
+ * The default name for a value passed using v-model.
+ */
+ modelValue: String,
+ /**
+ * Toggle the readonly state for the component.
+ */
+ readonly: Boolean,
+ /**
+ * Specifies the interval between legal numbers in the component.
+ */
+ steps: Number,
+ /**
+ * The `value` attribute of component.
+ *
+ * @controllable onChange
+ * */
+ value: Number,
+ },
+ emits: [
+ /**
+ * Event occurs when the value has been changed.
+ */
+ 'change',
+ /**
+ * Emit the new value whenever there’s a change event.
+ */
+ 'update:modelValue',
+ ],
+ setup(props, { attrs, emit, slots }) {
+ const handleChange = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('change', event)
+ emit('update:modelValue', target.value)
+ }
+
+ return () => [
+ props.label &&
+ h(
+ CFormLabel,
+ {
+ for: attrs.id,
+ },
+ {
+ default: () => (slots.label && slots.label()) || props.label,
+ },
+ ),
+ h(
+ 'input',
+ {
+ ...attrs,
+ class: 'form-range',
+ disabled: props.disabled,
+ max: props.max,
+ min: props.min,
+ onChange: (event: InputEvent) => handleChange(event),
+ readonly: props.readonly,
+ steps: props.steps,
+ type: 'range',
+ value: props.modelValue,
+ },
+ slots.default && slots.default(),
+ ),
+ ]
+ },
+})
+
+export { CFormRange }
diff --git a/packages/coreui-vue/src/components/form/CFormSelect.ts b/packages/coreui-vue/src/components/form/CFormSelect.ts
new file mode 100644
index 00000000..b3086b60
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormSelect.ts
@@ -0,0 +1,190 @@
+import { defineComponent, h, PropType } from 'vue'
+import { CFormControlWrapper } from './CFormControlWrapper'
+
+type Option = {
+ disabled?: boolean
+ label?: string
+ selected?: boolean
+ value?: string
+}
+
+const CFormSelect = defineComponent({
+ name: 'CFormSelect',
+ props: {
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedback: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedbackInvalid: String,
+ /**
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ feedbackValid: String,
+ /**
+ * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ floatingLabel: String,
+ /**
+ * Specifies the number of visible options in a drop-down list.
+ */
+ htmlSize: Number,
+ /**
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
+ */
+ id: String,
+ /**
+ * Set component validation state to invalid.
+ */
+ invalid: Boolean,
+ /**
+ * Add a caption for a component.
+ *
+ * @since 4.3.0
+ */
+ label: String,
+ /**
+ * The default name for a value passed using v-model.
+ */
+ modelValue: {
+ type: [String, Array] as PropType,
+ },
+ multiple: Boolean,
+ /**
+ * Options list of the select component. Available keys: `label`, `value`, `disabled`.
+ * Examples:
+ * - `:options="[{ value: 'js', label: 'JavaScript' }, { value: 'html', label: 'HTML', disabled: true }]"`
+ * - `:options="['js', 'html']"`
+ */
+ options: Array as PropType,
+ /**
+ * Size the component small or large.
+ *
+ * @values 'sm' | 'lg'
+ */
+ size: {
+ type: String,
+ validator: (value: string) => {
+ return ['sm', 'lg'].includes(value)
+ },
+ },
+ /**
+ * Add helper text to the component.
+ *
+ * @since 4.3.0
+ */
+ text: String,
+ /**
+ * Display validation feedback in a styled tooltip.
+ *
+ * @since 4.3.0
+ */
+ tooltipFeedback: Boolean,
+ /**
+ * Set component validation state to valid.
+ */
+ valid: Boolean,
+ },
+ emits: [
+ /**
+ * Event occurs when when a user changes the selected option of a `` element.
+ */
+ 'change',
+ /**
+ * Emit the new value whenever there’s a change event.
+ */
+ 'update:modelValue',
+ ],
+ setup(props, { attrs, emit, slots }) {
+ const handleChange = (event: InputEvent) => {
+ const target = event.target as HTMLSelectElement
+ const selected = Array.from(target.options)
+ .filter((option) => option.selected)
+ .map((option) => option.value)
+ emit('change', event)
+ emit('update:modelValue', target.multiple ? selected : selected[0])
+ }
+
+ return () =>
+ h(
+ CFormControlWrapper,
+ {
+ describedby: attrs['aria-describedby'],
+ feedback: props.feedback,
+ feedbackInvalid: props.feedbackInvalid,
+ feedbackValid: props.feedbackValid,
+ floatingLabel: props.floatingLabel,
+ id: props.id,
+ invalid: props.invalid,
+ label: props.label,
+ text: props.text,
+ tooltipFeedback: props.tooltipFeedback,
+ valid: props.valid,
+ },
+ {
+ default: () =>
+ h(
+ 'select',
+ {
+ id: props.id,
+ ...attrs,
+ class: [
+ 'form-select',
+ {
+ [`form-select-${props.size}`]: props.size,
+ 'is-invalid': props.invalid,
+ 'is-valid': props.valid,
+ },
+ attrs.class,
+ ],
+ multiple: props.multiple,
+ onChange: (event: InputEvent) => handleChange(event),
+ size: props.htmlSize,
+ ...(props.modelValue && !props.multiple && { value: props.modelValue }),
+ },
+ props.options
+ ? props.options.map((option: Option | string) => {
+ return h(
+ 'option',
+ {
+ ...(typeof option === 'object' && {
+ ...(option.disabled && { disabled: option.disabled }),
+ ...(option.selected && { selected: option.selected }),
+ ...(option.value !== undefined && {
+ value: option.value,
+ ...(props.modelValue &&
+ props.multiple &&
+ props.modelValue.includes(option.value) && { selected: true }),
+ }),
+ }),
+ },
+ typeof option === 'string' ? option : option.label,
+ )
+ })
+ : slots.default && slots.default(),
+ ),
+ ...(slots.feedback && { feedback: () => slots.feedback && slots.feedback() }),
+ ...(slots.feedbackInvalid && {
+ feedbackInvalid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.feedbackValid && {
+ feedbackValid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.label && { label: () => slots.label && slots.label() }),
+ ...(slots.text && { text: () => slots.text && slots.text() }),
+ },
+ )
+ },
+})
+
+export { CFormSelect }
diff --git a/src/components/form/CFormSwitch.ts b/packages/coreui-vue/src/components/form/CFormSwitch.ts
similarity index 66%
rename from src/components/form/CFormSwitch.ts
rename to packages/coreui-vue/src/components/form/CFormSwitch.ts
index 0c5c3fef..a1c54a1e 100644
--- a/src/components/form/CFormSwitch.ts
+++ b/packages/coreui-vue/src/components/form/CFormSwitch.ts
@@ -4,30 +4,30 @@ import { CFormLabel } from './CFormLabel'
const CFormSwitch = defineComponent({
name: 'CFormSwitch',
+ inheritAttrs: false,
props: {
/**
* The id global attribute defines an identifier (ID) that must be unique in the whole document
*/
- id: {
- type: String,
- default: undefined,
- required: false,
- },
+ id: String,
/**
* Set component validation state to invalid.
*/
- invalid: {
- type: Boolean,
- required: false,
- },
+ invalid: Boolean,
/**
* The element represents a caption for a component.
*/
- label: {
- type: String,
- default: undefined,
- required: false,
- },
+ label: String,
+ /**
+ * The default name for a value passed using v-model.
+ */
+ modelValue: [Boolean, String],
+ /**
+ * Put checkboxes or radios on the opposite side.
+ *
+ * @since 4.8.0
+ */
+ reverse: Boolean,
/**
* Size the component large or extra large. Works only with `switch`.
*
@@ -35,8 +35,6 @@ const CFormSwitch = defineComponent({
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['lg', 'xl'].includes(value)
},
@@ -45,22 +43,33 @@ const CFormSwitch = defineComponent({
* Specifies the type of component.
*
* @values 'checkbox', 'radio'
- * @default 'checkbox'
*/
type: {
type: String,
default: 'checkbox',
- required: false,
},
/**
* Set component validation state to valid.
*/
- valid: {
- type: Boolean,
- required: false,
- },
+ valid: Boolean,
},
- setup(props, { attrs }) {
+ emits: [
+ /**
+ * Event occurs when the checked value has been changed.
+ */
+ 'change',
+ /**
+ * Emit the new value whenever there’s a change event.
+ */
+ 'update:modelValue',
+ ],
+ setup(props, { attrs, emit }) {
+ const handleChange = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('change', event)
+ emit('update:modelValue', target.checked)
+ }
+
return () =>
h(
'div',
@@ -68,6 +77,7 @@ const CFormSwitch = defineComponent({
class: [
'form-check form-switch',
{
+ 'form-check-reverse': props.reverse,
[`form-switch-${props.size}`]: props.size,
'is-invalid': props.invalid,
'is-valid': props.valid,
@@ -77,8 +87,7 @@ const CFormSwitch = defineComponent({
[
h('input', {
...attrs,
- id: props.id,
- type: props.type,
+ ...(props.modelValue && { checked: props.modelValue }),
class: [
'form-check-input',
{
@@ -86,6 +95,9 @@ const CFormSwitch = defineComponent({
'is-valid': props.valid,
},
],
+ id: props.id,
+ onChange: (event: InputEvent) => handleChange(event),
+ type: props.type,
}),
props.label &&
h(
diff --git a/src/components/form/CFormText.ts b/packages/coreui-vue/src/components/form/CFormText.ts
similarity index 89%
rename from src/components/form/CFormText.ts
rename to packages/coreui-vue/src/components/form/CFormText.ts
index f46e15a8..13b47ada 100644
--- a/src/components/form/CFormText.ts
+++ b/packages/coreui-vue/src/components/form/CFormText.ts
@@ -5,12 +5,9 @@ const CFormText = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'div'
*/
component: {
type: String,
- required: false,
default: 'div',
},
},
diff --git a/packages/coreui-vue/src/components/form/CFormTextarea.ts b/packages/coreui-vue/src/components/form/CFormTextarea.ts
new file mode 100644
index 00000000..21fb3596
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/CFormTextarea.ts
@@ -0,0 +1,157 @@
+import { defineComponent, h } from 'vue'
+import { CFormControlWrapper } from './CFormControlWrapper'
+
+const CFormTextarea = defineComponent({
+ name: 'CFormTextarea',
+ props: {
+ /**
+ * Toggle the disabled state for the component.
+ */
+ disabled: Boolean,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedback: String,
+ /**
+ * Provide valuable, actionable feedback.
+ *
+ * @since 4.3.0
+ */
+ feedbackInvalid: String,
+ /**
+ * Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ feedbackValid: String,
+ /**
+ * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`.
+ *
+ * @since 4.3.0
+ */
+ floatingLabel: String,
+ /**
+ * The id global attribute defines an identifier (ID) that must be unique in the whole document.
+ */
+ id: String,
+ /**
+ * Set component validation state to invalid.
+ */
+ invalid: Boolean,
+ /**
+ * Add a caption for a component.
+ *
+ * @since 4.3.0
+ */
+ label: String,
+ /**
+ * The default name for a value passed using v-model.
+ */
+ modelValue: String,
+ /**
+ * Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`.
+ */
+ plainText: Boolean,
+ /**
+ * Toggle the readonly state for the component.
+ */
+ readonly: Boolean,
+ /**
+ * Add helper text to the component.
+ *
+ * @since 4.3.0
+ */
+ text: String,
+ /**
+ * Display validation feedback in a styled tooltip.
+ *
+ * @since 4.3.0
+ */
+ tooltipFeedback: Boolean,
+ /**
+ * Set component validation state to valid.
+ */
+ valid: Boolean,
+ },
+ emits: [
+ /**
+ * Event occurs when the element loses focus, after the content has been changed.
+ */
+ 'change',
+ /**
+ * Event occurs immediately after the value of a component has changed.
+ */
+ 'input',
+ /**
+ * Emit the new value whenever there’s an input or change event.
+ */
+ 'update:modelValue',
+ ],
+ setup(props, { attrs, emit, slots }) {
+ const handleChange = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('change', event)
+ emit('update:modelValue', target.value)
+ }
+
+ const handleInput = (event: InputEvent) => {
+ const target = event.target as HTMLInputElement
+ emit('input', event)
+ emit('update:modelValue', target.value)
+ }
+
+ return () =>
+ h(
+ CFormControlWrapper,
+ {
+ describedby: attrs['aria-describedby'],
+ feedback: props.feedback,
+ feedbackInvalid: props.feedbackInvalid,
+ feedbackValid: props.feedbackValid,
+ floatingLabel: props.floatingLabel,
+ id: props.id,
+ invalid: props.invalid,
+ label: props.label,
+ text: props.text,
+ tooltipFeedback: props.tooltipFeedback,
+ valid: props.valid,
+ },
+ {
+ default: () =>
+ h(
+ 'textarea',
+ {
+ id: props.id,
+ ...attrs,
+ disabled: props.disabled,
+ readonly: props.readonly,
+ class: [
+ props.plainText ? 'form-control-plaintext' : 'form-control',
+ {
+ 'is-invalid': props.invalid,
+ 'is-valid': props.valid,
+ },
+ ],
+ onChange: (event: InputEvent) => handleChange(event),
+ onInput: (event: InputEvent) => handleInput(event),
+ ...(props.modelValue && { value: props.modelValue }),
+ },
+ slots.default && slots.default(),
+ ),
+ ...(slots.feedback && { feedback: () => slots.feedback && slots.feedback() }),
+ ...(slots.feedbackInvalid && {
+ feedbackInvalid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.feedbackValid && {
+ feedbackValid: () => slots.feedbackInvalid && slots.feedbackInvalid(),
+ }),
+ ...(slots.label && { label: () => slots.label && slots.label() }),
+ ...(slots.text && { text: () => slots.text && slots.text() }),
+ },
+ )
+ },
+})
+
+export { CFormTextarea }
diff --git a/src/components/form/CInputGroup.ts b/packages/coreui-vue/src/components/form/CInputGroup.ts
similarity index 89%
rename from src/components/form/CInputGroup.ts
rename to packages/coreui-vue/src/components/form/CInputGroup.ts
index f8ef27d7..56a8418c 100644
--- a/src/components/form/CInputGroup.ts
+++ b/packages/coreui-vue/src/components/form/CInputGroup.ts
@@ -6,12 +6,10 @@ const CInputGroup = defineComponent({
/**
* Size the component small or large.
*
- * @type 'sm' | 'lg'
+ * @values 'sm', 'lg'
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['sm', 'lg'].includes(value)
},
diff --git a/src/components/form/CInputGroupText.ts b/packages/coreui-vue/src/components/form/CInputGroupText.ts
similarity index 89%
rename from src/components/form/CInputGroupText.ts
rename to packages/coreui-vue/src/components/form/CInputGroupText.ts
index c366fa29..92717357 100644
--- a/src/components/form/CInputGroupText.ts
+++ b/packages/coreui-vue/src/components/form/CInputGroupText.ts
@@ -5,12 +5,9 @@ const CInputGroupText = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'span'
*/
component: {
type: String,
- required: false,
default: 'span',
},
},
diff --git a/packages/coreui-vue/src/components/form/__tests__/CForm.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CForm.spec.ts
new file mode 100644
index 00000000..b09a6349
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CForm.spec.ts
@@ -0,0 +1,42 @@
+import { mount } from '@vue/test-utils'
+import { CForm as Component } from '../../../index'
+
+const ComponentName = 'CForm'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ validated: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('was-validated')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormCheck.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormCheck.spec.ts
new file mode 100644
index 00000000..2bfd92f0
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormCheck.spec.ts
@@ -0,0 +1,98 @@
+import { mount } from '@vue/test-utils'
+import { CFormCheck as Component } from '../../../index'
+
+const ComponentName = 'CFormCheck'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customLabelWrapper = mount(Component, {
+ propsData: {
+ label: 'some label',
+ button: {
+ color: 'warning',
+ shape: 'rounded-circle',
+ size: 'lg',
+ variant: 'outline',
+ },
+ id: 'uniqueid',
+ inline: true,
+ invalid: true,
+ type: 'checkbox', // TODO: test other type
+ valid: true,
+ },
+ slots: {},
+})
+
+const customLabelInSlotWrapper = mount(Component, {
+ propsData: {
+ button: {
+ color: 'warning',
+ shape: 'rounded-circle',
+ size: 'lg',
+ variant: 'outline',
+ },
+ id: 'uniqueid',
+ inline: true,
+ invalid: true,
+ type: 'checkbox', // TODO: test other type
+ valid: true,
+ },
+ slots: {
+ label: 'some label',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('form-check-input')).toBe(true)
+ })
+})
+
+describe(`Customize with label - ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customLabelWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customLabelWrapper.find('label').text()).toContain('some label')
+ expect(customLabelWrapper.find('input').classes('btn-check')).toBe(true)
+ expect(customLabelWrapper.find('input').classes('is-invalid')).toBe(true)
+ expect(customLabelWrapper.find('input').classes('is-valid')).toBe(true)
+ expect(customLabelWrapper.find('input').attributes('id')).toBe('uniqueid')
+ expect(customLabelWrapper.find('input').attributes('type')).toBe('checkbox')
+
+ expect(customLabelWrapper.find('label').classes('btn')).toBe(true)
+ expect(customLabelWrapper.find('label').classes('btn-outline-warning')).toBe(true)
+ expect(customLabelWrapper.find('label').classes('btn-lg')).toBe(true)
+ expect(customLabelWrapper.find('label').classes('rounded-circle')).toBe(true)
+ expect(customLabelWrapper.find('label').attributes('for')).toBe('uniqueid')
+ })
+})
+
+describe(`Customize with label in slot - ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customLabelInSlotWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customLabelInSlotWrapper.find('label').text()).toContain('some label')
+ expect(customLabelInSlotWrapper.find('input').classes('btn-check')).toBe(true)
+ expect(customLabelInSlotWrapper.find('input').classes('is-invalid')).toBe(true)
+ expect(customLabelInSlotWrapper.find('input').classes('is-valid')).toBe(true)
+ expect(customLabelInSlotWrapper.find('input').attributes('id')).toBe('uniqueid')
+ expect(customLabelInSlotWrapper.find('input').attributes('type')).toBe('checkbox')
+
+ expect(customLabelInSlotWrapper.find('label').classes('btn')).toBe(true)
+ expect(customLabelInSlotWrapper.find('label').classes('btn-outline-warning')).toBe(true)
+ expect(customLabelInSlotWrapper.find('label').classes('btn-lg')).toBe(true)
+ expect(customLabelInSlotWrapper.find('label').classes('rounded-circle')).toBe(true)
+ expect(customLabelInSlotWrapper.find('label').attributes('for')).toBe('uniqueid')
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormFeedback.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormFeedback.spec.ts
new file mode 100644
index 00000000..86349ea2
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormFeedback.spec.ts
@@ -0,0 +1,69 @@
+import { mount } from '@vue/test-utils'
+import { CFormFeedback as Component } from '../../../index'
+
+const ComponentName = 'CFormFeedback'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'h2',
+ invalid: true,
+ tooltip: true,
+ valid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ component: 'h2',
+ invalid: true,
+ tooltip: false,
+ valid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('invalid-tooltip')).toBe(true)
+ expect(customWrapper.classes('valid-tooltip')).toBe(true)
+ })
+})
+
+describe(`Customize (two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.text()).toContain('Default slot')
+ expect(customWrapperTwo.classes('invalid-feedback')).toBe(true)
+ expect(customWrapperTwo.classes('valid-feedback')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormFloating.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormFloating.spec.ts
new file mode 100644
index 00000000..972df01f
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormFloating.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CFormFloating as Component } from '../../../index'
+
+const ComponentName = 'CFormFloating'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('form-floating')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormInput.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormInput.spec.ts
new file mode 100644
index 00000000..eaac7a9f
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormInput.spec.ts
@@ -0,0 +1,82 @@
+import { mount } from '@vue/test-utils'
+import { CFormInput as Component } from '../../../index'
+
+const ComponentName = 'CFormInput'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ disabled: true,
+ invalid: true,
+ plainText: true,
+ readonly: true,
+ size: 'lg',
+ type: 'color',
+ valid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ disabled: true,
+ invalid: true,
+ plainText: false,
+ readonly: true,
+ size: 'lg',
+ type: 'color',
+ valid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('input').classes('form-control')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('input').classes('form-control-plaintext')).toBe(true)
+ expect(customWrapper.find('input').classes('form-control-color')).toBe(true)
+ expect(customWrapper.find('input').classes('form-control-lg')).toBe(true)
+ expect(customWrapper.find('input').classes('is-invalid')).toBe(true)
+ expect(customWrapper.find('input').classes('is-valid')).toBe(true)
+ })
+})
+
+describe(`Customize (two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.text()).toContain('Default slot')
+ expect(customWrapperTwo.find('input').classes('form-control')).toBe(true)
+ expect(customWrapper.find('input').classes('form-control-color')).toBe(true)
+ expect(customWrapper.find('input').classes('form-control-lg')).toBe(true)
+ expect(customWrapper.find('input').classes('is-invalid')).toBe(true)
+ expect(customWrapper.find('input').classes('is-valid')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormLabel.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormLabel.spec.ts
new file mode 100644
index 00000000..3d99c265
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormLabel.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CFormLabel as Component } from '../../../index'
+
+const ComponentName = 'CFormLabel'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ customClassName: 'bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('form-label')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('bazinga')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormRange.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormRange.spec.ts
new file mode 100644
index 00000000..5d537e93
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormRange.spec.ts
@@ -0,0 +1,55 @@
+import { mount } from '@vue/test-utils'
+import { CFormRange as Component } from '../../../index'
+
+const ComponentName = 'CFormRange'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ disabled: true,
+ max: 400,
+ min: 50,
+ readonly: true,
+ steps: 10,
+ value: 250,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('input').classes('form-range')).toBe(true)
+ expect(defaultWrapper.find('input').attributes('type')).toBe('range')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('input').classes('form-range')).toBe(true)
+ expect(customWrapper.find('input').attributes('type')).toBe('range')
+ expect(customWrapper.find('input').attributes('disabled')).toBe('')
+ expect(customWrapper.find('input').attributes('max')).toBe('400')
+ expect(customWrapper.find('input').attributes('min')).toBe('50')
+ expect(customWrapper.find('input').attributes('readonly')).toBe('')
+ expect(customWrapper.find('input').attributes('steps')).toBe('10')
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormSelect.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormSelect.spec.ts
new file mode 100644
index 00000000..0324a2df
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormSelect.spec.ts
@@ -0,0 +1,48 @@
+import { mount } from '@vue/test-utils'
+import { CFormSelect as Component } from '../../../index'
+
+const ComponentName = 'CFormSelect'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ htmlSize: 200,
+ invalid: true,
+ size: 'lg',
+ valid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('select').classes('form-select')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('select').classes('form-select')).toBe(true)
+ expect(customWrapper.find('select').classes('form-select-lg')).toBe(true)
+ expect(customWrapper.find('select').attributes('size')).toBe('200')
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormSwitch.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormSwitch.spec.ts
new file mode 100644
index 00000000..c328b9a3
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormSwitch.spec.ts
@@ -0,0 +1,59 @@
+import { mount } from '@vue/test-utils'
+import { CFormSwitch as Component } from '../../../index'
+
+const ComponentName = 'CFormSwitch'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ id: 'uniqueid',
+ invalid: true,
+ label: 'some label',
+ size: 'lg',
+ type: 'radio',
+ valid: true,
+ },
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('form-check')).toBe(true)
+ expect(defaultWrapper.classes('form-switch')).toBe(true)
+ expect(defaultWrapper.find('input').classes('form-check-input')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('form-check')).toBe(true)
+ expect(customWrapper.classes('form-switch')).toBe(true)
+ expect(customWrapper.classes('form-switch-lg')).toBe(true)
+ expect(customWrapper.classes('is-invalid')).toBe(true)
+ expect(customWrapper.classes('is-valid')).toBe(true)
+
+ expect(customWrapper.find('input').classes('form-check-input')).toBe(true)
+ expect(customWrapper.find('input').classes('is-invalid')).toBe(true)
+ expect(customWrapper.find('input').classes('is-valid')).toBe(true)
+ expect(customWrapper.find('input').attributes('type')).toBe('radio')
+ expect(customWrapper.find('input').attributes('id')).toBe('uniqueid')
+
+ expect(customWrapper.find('label').classes('form-check-label')).toBe(true)
+ expect(customWrapper.find('label').attributes('for')).toBe('uniqueid')
+
+ expect(customWrapper.find('label').text()).toContain('some label')
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormText.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormText.spec.ts
new file mode 100644
index 00000000..224ad547
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormText.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CFormText as Component } from '../../../index'
+
+const ComponentName = 'CFormText'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'p',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('form-text')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('form-text')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CFormTextarea.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CFormTextarea.spec.ts
new file mode 100644
index 00000000..a105920e
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CFormTextarea.spec.ts
@@ -0,0 +1,49 @@
+import { mount } from '@vue/test-utils'
+import { CFormTextarea as Component } from '../../../index'
+
+const ComponentName = 'CFormTextarea'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ disabled: true,
+ invalid: true,
+ plainText: true,
+ readonly: true,
+ valid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('textarea').classes('form-control')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('textarea').classes('form-control-plaintext')).toBe(true)
+ expect(customWrapper.find('textarea').classes('is-invalid')).toBe(true)
+ expect(customWrapper.find('textarea').classes('is-valid')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CInputGroup.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CInputGroup.spec.ts
new file mode 100644
index 00000000..752066ac
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CInputGroup.spec.ts
@@ -0,0 +1,44 @@
+import { mount } from '@vue/test-utils'
+import { CInputGroup as Component } from '../../../index'
+
+const ComponentName = 'CInputGroup'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ size: 'lg',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('input-group')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('input-group')).toBe(true)
+ expect(customWrapper.classes('input-group-lg')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/CInputGroupText.spec.ts b/packages/coreui-vue/src/components/form/__tests__/CInputGroupText.spec.ts
new file mode 100644
index 00000000..2ba2af6d
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/CInputGroupText.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CInputGroupText as Component } from '../../../index'
+
+const ComponentName = 'CInputGroupText'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('input-group-text')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('input-group-text')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CForm.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CForm.spec.ts.snap
new file mode 100644
index 00000000..644015b8
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CForm.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CForm component renders correctly 1`] = `""`;
+
+exports[`Loads and display CForm component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormCheck.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormCheck.spec.ts.snap
new file mode 100644
index 00000000..c864ba71
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormCheck.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize with label - CFormCheck component renders correctly 1`] = `
+"
+some label "
+`;
+
+exports[`Customize with label in slot - CFormCheck component renders correctly 1`] = `
+"
+some label "
+`;
+
+exports[`Loads and display CFormCheck component renders correctly 1`] = `" "`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.ts.snap
new file mode 100644
index 00000000..94a0f78d
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormFeedback.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (two) CFormFeedback component renders correctly 1`] = `"Default slot "`;
+
+exports[`Customize CFormFeedback component renders correctly 1`] = `""`;
+
+exports[`Loads and display CFormFeedback component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormFloating.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormFloating.spec.ts.snap
new file mode 100644
index 00000000..8011db77
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormFloating.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CFormFloating component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormInput.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormInput.spec.ts.snap
new file mode 100644
index 00000000..2e7649fe
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormInput.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (two) CFormInput component renders correctly 1`] = `" "`;
+
+exports[`Customize CFormInput component renders correctly 1`] = `" "`;
+
+exports[`Loads and display CFormInput component renders correctly 1`] = `" "`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormLabel.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormLabel.spec.ts.snap
new file mode 100644
index 00000000..4bd5e697
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormLabel.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFormLabel component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CFormLabel component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormRange.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormRange.spec.ts.snap
new file mode 100644
index 00000000..3af8cac0
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormRange.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFormRange component renders correctly 1`] = `" "`;
+
+exports[`Loads and display CFormRange component renders correctly 1`] = `" "`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormSelect.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormSelect.spec.ts.snap
new file mode 100644
index 00000000..d6dc9c70
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormSelect.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFormSelect component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CFormSelect component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.ts.snap
new file mode 100644
index 00000000..2a1c6bbd
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormSwitch.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFormSwitch component renders correctly 1`] = `"some label
"`;
+
+exports[`Loads and display CFormSwitch component renders correctly 1`] = `
+"
+
+
"
+`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormText.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormText.spec.ts.snap
new file mode 100644
index 00000000..f2b0b034
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormText.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFormText component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CFormText component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.ts.snap
new file mode 100644
index 00000000..a797c34d
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CFormTextarea.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CFormTextarea component renders correctly 1`] = `""`;
+
+exports[`Loads and display CFormTextarea component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CInputGroup.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CInputGroup.spec.ts.snap
new file mode 100644
index 00000000..a6f5d78b
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CInputGroup.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CInputGroup component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CInputGroup component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.ts.snap b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.ts.snap
new file mode 100644
index 00000000..37737ec9
--- /dev/null
+++ b/packages/coreui-vue/src/components/form/__tests__/__snapshots__/CInputGroupText.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CInputGroupText component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CInputGroupText component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/form/index.ts b/packages/coreui-vue/src/components/form/index.ts
similarity index 100%
rename from src/components/form/index.ts
rename to packages/coreui-vue/src/components/form/index.ts
diff --git a/src/components/grid/CCol.ts b/packages/coreui-vue/src/components/grid/CCol.ts
similarity index 81%
rename from src/components/grid/CCol.ts
rename to packages/coreui-vue/src/components/grid/CCol.ts
index 50e4ee87..d630b9b2 100644
--- a/src/components/grid/CCol.ts
+++ b/packages/coreui-vue/src/components/grid/CCol.ts
@@ -29,8 +29,6 @@ const CCol = defineComponent({
*/
xs: {
type: [Boolean, Number, String, Object] as PropType ,
- default: undefined,
- require: false,
},
/**
* The number of columns/offset/order on small devices (<768px).
@@ -39,8 +37,6 @@ const CCol = defineComponent({
*/
sm: {
type: [Boolean, Number, String, Object] as PropType ,
- default: undefined,
- require: false,
},
/**
* The number of columns/offset/order on medium devices (<992px).
@@ -49,8 +45,6 @@ const CCol = defineComponent({
*/
md: {
type: [Boolean, Number, String, Object] as PropType ,
- default: undefined,
- require: false,
},
/**
* The number of columns/offset/order on large devices (<1200px).
@@ -59,8 +53,6 @@ const CCol = defineComponent({
*/
lg: {
type: [Boolean, Number, String, Object] as PropType ,
- default: undefined,
- require: false,
},
/**
* The number of columns/offset/order on X-Large devices (<1400px).
@@ -69,8 +61,6 @@ const CCol = defineComponent({
*/
xl: {
type: [Boolean, Number, String, Object] as PropType ,
- default: undefined,
- require: false,
},
/**
* The number of columns/offset/order on XX-Large devices (≥1400px).
@@ -79,12 +69,10 @@ const CCol = defineComponent({
*/
xxl: {
type: [Boolean, Number, String, Object] as PropType ,
- default: undefined,
- require: false,
},
},
setup(props, { slots }) {
- const repsonsiveCLassNames: string[] = []
+ const repsonsiveClassNames: string[] = []
BREAKPOINTS.forEach((bp) => {
const breakpoint = props[bp]
@@ -93,29 +81,29 @@ const CCol = defineComponent({
if (breakpoint) {
if (typeof breakpoint === 'number' || typeof breakpoint === 'string') {
- repsonsiveCLassNames.push(`col${infix}-${breakpoint}`)
+ repsonsiveClassNames.push(`col${infix}-${breakpoint}`)
}
if (typeof breakpoint === 'boolean') {
- repsonsiveCLassNames.push(`col${infix}`)
+ repsonsiveClassNames.push(`col${infix}`)
}
}
if (breakpoint && typeof breakpoint === 'object') {
if (typeof breakpoint.span === 'number' || typeof breakpoint.span === 'string') {
- repsonsiveCLassNames.push(`col${infix}-${breakpoint.span}`)
+ repsonsiveClassNames.push(`col${infix}-${breakpoint.span}`)
}
if (typeof breakpoint.span === 'boolean') {
- repsonsiveCLassNames.push(`col${infix}`)
+ repsonsiveClassNames.push(`col${infix}`)
}
if (typeof breakpoint.order === 'number' || typeof breakpoint.order === 'string') {
- repsonsiveCLassNames.push(`order${infix}-${breakpoint.order}`)
+ repsonsiveClassNames.push(`order${infix}-${breakpoint.order}`)
}
if (typeof breakpoint.offset === 'number') {
- repsonsiveCLassNames.push(`offset${infix}-${breakpoint.offset}`)
+ repsonsiveClassNames.push(`offset${infix}-${breakpoint.offset}`)
}
}
})
@@ -124,7 +112,7 @@ const CCol = defineComponent({
h(
'div',
{
- class: [repsonsiveCLassNames.length ? repsonsiveCLassNames : 'col'],
+ class: [repsonsiveClassNames.length > 0 ? repsonsiveClassNames : 'col'],
},
slots.default && slots.default(),
)
diff --git a/src/components/grid/CContainer.ts b/packages/coreui-vue/src/components/grid/CContainer.ts
similarity index 62%
rename from src/components/grid/CContainer.ts
rename to packages/coreui-vue/src/components/grid/CContainer.ts
index 07eeabfe..77f7a4f2 100644
--- a/src/components/grid/CContainer.ts
+++ b/packages/coreui-vue/src/components/grid/CContainer.ts
@@ -15,59 +15,41 @@ const CContainer = defineComponent({
/**
* Set container 100% wide until small breakpoint.
*/
- sm: {
- type: Boolean,
- required: false,
- },
+ sm: Boolean,
/**
* Set container 100% wide until medium breakpoint.
*/
- md: {
- type: Boolean,
- required: false,
- },
+ md: Boolean,
/**
* Set container 100% wide until large breakpoint.
*/
- lg: {
- type: Boolean,
- required: false,
- },
+ lg: Boolean,
/**
* Set container 100% wide until X-large breakpoint.
*/
- xl: {
- type: Boolean,
- required: false,
- },
+ xl: Boolean,
/**
* Set container 100% wide until XX-large breakpoint.
*/
- xxl: {
- type: Boolean,
- required: false,
- },
+ xxl: Boolean,
/**
* Set container 100% wide, spanning the entire width of the viewport.
*/
- fluid: {
- type: Boolean,
- required: false,
- },
+ fluid: Boolean,
},
setup(props, { slots }) {
- const repsonsiveCLassNames: string[] = []
+ const repsonsiveClassNames: string[] = []
BREAKPOINTS.forEach((bp) => {
const breakpoint = props[bp]
- breakpoint && repsonsiveCLassNames.push(`container-${bp}`)
+ breakpoint && repsonsiveClassNames.push(`container-${bp}`)
})
return () =>
h(
'div',
{
- class: [repsonsiveCLassNames.length ? repsonsiveCLassNames : 'container'],
+ class: [repsonsiveClassNames.length > 0 ? repsonsiveClassNames : 'container'],
},
slots.default && slots.default(),
)
diff --git a/src/components/grid/CRow.ts b/packages/coreui-vue/src/components/grid/CRow.ts
similarity index 64%
rename from src/components/grid/CRow.ts
rename to packages/coreui-vue/src/components/grid/CRow.ts
index 4809e7c4..4501cffd 100644
--- a/src/components/grid/CRow.ts
+++ b/packages/coreui-vue/src/components/grid/CRow.ts
@@ -24,64 +24,40 @@ const CRow = defineComponent({
*
* @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
*/
- xs: {
- type: Object as () => BPObject,
- default: undefined,
- required: false,
- },
+ xs: Object as () => BPObject,
/**
* The number of columns/offset/order on small devices (<768px).
*
* @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
*/
- sm: {
- type: Object as () => BPObject,
- default: undefined,
- required: false,
- /**
- * The number of columns/offset/order on medium devices (<992px).
- *
- * @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
- */
- },
- md: {
- type: Object as () => BPObject,
- default: undefined,
- required: false,
- },
+ sm: Object as () => BPObject,
+ /**
+ * The number of columns/offset/order on medium devices (<992px).
+ *
+ * @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
+ */
+ md: Object as () => BPObject,
/**
* The number of columns/offset/order on large devices (<1200px).
*
* @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
*/
- lg: {
- type: Object as () => BPObject,
- default: undefined,
- required: false,
- },
+ lg: Object as () => BPObject,
/**
* The number of columns/offset/order on X-Large devices (<1400px).
*
* @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
*/
- xl: {
- type: Object as () => BPObject,
- default: undefined,
- required: false,
- },
+ xl: Object as () => BPObject,
/**
* The number of columns/offset/order on XX-Large devices (≥1400px).
*
* @values { cols: 'auto' | number | string } | { gutter: number | string } | { gutterX: number | string } | { gutterY: number | string }
*/
- xxl: {
- type: Object as () => BPObject,
- default: undefined,
- required: false,
- },
+ xxl: Object as () => BPObject,
},
setup(props, { slots }) {
- const repsonsiveCLassNames: string[] = []
+ const repsonsiveClassNames: string[] = []
BREAKPOINTS.forEach((bp) => {
const breakpoint = props[bp]
@@ -89,16 +65,16 @@ const CRow = defineComponent({
if (typeof breakpoint === 'object') {
if (breakpoint.cols) {
- repsonsiveCLassNames.push(`row-cols${infix}-${breakpoint.cols}`)
+ repsonsiveClassNames.push(`row-cols${infix}-${breakpoint.cols}`)
}
if (typeof breakpoint.gutter === 'number') {
- repsonsiveCLassNames.push(`g${infix}-${breakpoint.gutter}`)
+ repsonsiveClassNames.push(`g${infix}-${breakpoint.gutter}`)
}
if (typeof breakpoint.gutterX === 'number') {
- repsonsiveCLassNames.push(`gx${infix}-${breakpoint.gutterX}`)
+ repsonsiveClassNames.push(`gx${infix}-${breakpoint.gutterX}`)
}
if (typeof breakpoint.gutterY === 'number') {
- repsonsiveCLassNames.push(`gy${infix}-${breakpoint.gutterY}`)
+ repsonsiveClassNames.push(`gy${infix}-${breakpoint.gutterY}`)
}
}
})
@@ -107,7 +83,7 @@ const CRow = defineComponent({
h(
'div',
{
- class: ['row', repsonsiveCLassNames],
+ class: ['row', repsonsiveClassNames],
},
slots.default && slots.default(),
)
diff --git a/packages/coreui-vue/src/components/grid/__tests__/CCol.spec.ts b/packages/coreui-vue/src/components/grid/__tests__/CCol.spec.ts
new file mode 100644
index 00000000..6166cb4f
--- /dev/null
+++ b/packages/coreui-vue/src/components/grid/__tests__/CCol.spec.ts
@@ -0,0 +1,53 @@
+import { mount } from '@vue/test-utils'
+import { CCol as Component } from '../../../index'
+
+const ComponentName = 'CCol'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ md: {
+ span: 'auto',
+ offset: 3,
+ order: 'last',
+ },
+ lg: 4,
+ xl: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('col')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('col-md-auto')).toBe(true)
+ expect(customWrapper.classes('offset-md-3')).toBe(true)
+ expect(customWrapper.classes('order-md-last')).toBe(true)
+ expect(customWrapper.classes('col-lg-4')).toBe(true)
+ expect(customWrapper.classes('col-xl')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/grid/__tests__/CContainer.spec.ts b/packages/coreui-vue/src/components/grid/__tests__/CContainer.spec.ts
new file mode 100644
index 00000000..8d220fc9
--- /dev/null
+++ b/packages/coreui-vue/src/components/grid/__tests__/CContainer.spec.ts
@@ -0,0 +1,47 @@
+import { mount } from '@vue/test-utils'
+import { CContainer as Component } from '../../../index'
+
+const ComponentName = 'CContainer'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ md: true,
+ xl: true,
+ fluid: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('container')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('container-md')).toBe(true)
+ expect(customWrapper.classes('container-xl')).toBe(true)
+ expect(customWrapper.classes('container-fluid')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/grid/__tests__/CRow.spec.ts b/packages/coreui-vue/src/components/grid/__tests__/CRow.spec.ts
new file mode 100644
index 00000000..9658ab3e
--- /dev/null
+++ b/packages/coreui-vue/src/components/grid/__tests__/CRow.spec.ts
@@ -0,0 +1,52 @@
+import { mount } from '@vue/test-utils'
+import { CRow as Component } from '../../../index'
+
+const ComponentName = 'CRow'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ md: {
+ cols: 4,
+ gutter: 10,
+ gutterX: 11,
+ gutterY: 12,
+ },
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('row')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('row')).toBe(true)
+ expect(customWrapper.classes('row-cols-md-4')).toBe(true)
+ expect(customWrapper.classes('g-md-10')).toBe(true)
+ expect(customWrapper.classes('gx-md-11')).toBe(true)
+ expect(customWrapper.classes('gy-md-12')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CCol.spec.ts.snap b/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CCol.spec.ts.snap
new file mode 100644
index 00000000..60bb0dec
--- /dev/null
+++ b/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CCol.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CCol component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CCol component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CContainer.spec.ts.snap b/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CContainer.spec.ts.snap
new file mode 100644
index 00000000..15d92143
--- /dev/null
+++ b/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CContainer.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CContainer component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CContainer component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CRow.spec.ts.snap b/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CRow.spec.ts.snap
new file mode 100644
index 00000000..686e7491
--- /dev/null
+++ b/packages/coreui-vue/src/components/grid/__tests__/__snapshots__/CRow.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CRow component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CRow component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/grid/index.ts b/packages/coreui-vue/src/components/grid/index.ts
similarity index 100%
rename from src/components/grid/index.ts
rename to packages/coreui-vue/src/components/grid/index.ts
diff --git a/src/components/header/CHeader.ts b/packages/coreui-vue/src/components/header/CHeader.ts
similarity index 79%
rename from src/components/header/CHeader.ts
rename to packages/coreui-vue/src/components/header/CHeader.ts
index 1a417731..32ab0bf5 100644
--- a/src/components/header/CHeader.ts
+++ b/packages/coreui-vue/src/components/header/CHeader.ts
@@ -6,12 +6,10 @@ const CHeader = defineComponent({
/**
* Defines optional container wrapping children elements.
*
- * @values boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl' | 'fluid'
+ * @values boolean, 'sm', 'md', 'lg', 'xl', 'xxl', 'fluid'
*/
container: {
type: [Boolean, String],
- default: undefined,
- required: false,
validator: (value: boolean | string) => {
return (
typeof value === 'boolean' || ['sm', 'md', 'lg', 'xl', 'xxl', 'fluid'].includes(value)
@@ -20,11 +18,11 @@ const CHeader = defineComponent({
},
/**
* Place header in non-static positions.
+ *
+ * @values 'fixed', 'sticky'
*/
position: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['fixed', 'sticky'].includes(value)
},
@@ -38,7 +36,7 @@ const CHeader = defineComponent({
props.container
? h(
'div',
- { class: `container${props.container !== true ? '-' + props.container : ''}` },
+ { class: `container${props.container === true ? '' : '-' + props.container}` },
slots.default && slots.default(),
)
: slots.default && slots.default(),
diff --git a/src/components/header/CHeaderBrand.ts b/packages/coreui-vue/src/components/header/CHeaderBrand.ts
similarity index 90%
rename from src/components/header/CHeaderBrand.ts
rename to packages/coreui-vue/src/components/header/CHeaderBrand.ts
index 1cf2e8a9..97ee9581 100644
--- a/src/components/header/CHeaderBrand.ts
+++ b/packages/coreui-vue/src/components/header/CHeaderBrand.ts
@@ -5,12 +5,9 @@ const CHeaderBrand = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'a'
*/
component: {
type: String,
- required: false,
default: 'a',
},
},
diff --git a/src/components/header/CHeaderDivider.ts b/packages/coreui-vue/src/components/header/CHeaderDivider.ts
similarity index 100%
rename from src/components/header/CHeaderDivider.ts
rename to packages/coreui-vue/src/components/header/CHeaderDivider.ts
diff --git a/src/components/header/CHeaderNav.ts b/packages/coreui-vue/src/components/header/CHeaderNav.ts
similarity index 91%
rename from src/components/header/CHeaderNav.ts
rename to packages/coreui-vue/src/components/header/CHeaderNav.ts
index 673df5cf..1fa1e7c7 100644
--- a/src/components/header/CHeaderNav.ts
+++ b/packages/coreui-vue/src/components/header/CHeaderNav.ts
@@ -5,12 +5,9 @@ const CHeaderNav = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'ul'
*/
component: {
type: String,
- required: false,
default: 'ul',
},
},
diff --git a/src/components/header/CHeaderText.ts b/packages/coreui-vue/src/components/header/CHeaderText.ts
similarity index 100%
rename from src/components/header/CHeaderText.ts
rename to packages/coreui-vue/src/components/header/CHeaderText.ts
diff --git a/src/components/header/CHeaderToggler.ts b/packages/coreui-vue/src/components/header/CHeaderToggler.ts
similarity index 100%
rename from src/components/header/CHeaderToggler.ts
rename to packages/coreui-vue/src/components/header/CHeaderToggler.ts
diff --git a/packages/coreui-vue/src/components/header/__tests__/CHeader.spec.ts b/packages/coreui-vue/src/components/header/__tests__/CHeader.spec.ts
new file mode 100644
index 00000000..2bb30916
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/CHeader.spec.ts
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils'
+import { CHeader as Component } from '../../../index'
+
+const ComponentName = 'CHeader'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ container: 'lg',
+ position: 'fixed',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('header')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('header')).toBe(true)
+ expect(customWrapper.classes('header-fixed')).toBe(true)
+ expect(customWrapper.find('.container-lg').classes('container-lg')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/header/__tests__/CHeaderBrand.spec.ts b/packages/coreui-vue/src/components/header/__tests__/CHeaderBrand.spec.ts
new file mode 100644
index 00000000..10df823a
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/CHeaderBrand.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CHeaderBrand as Component } from '../../../index'
+
+const ComponentName = 'CHeaderBrand'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('header-brand')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('header-brand')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/header/__tests__/CHeaderDivider.spec.ts b/packages/coreui-vue/src/components/header/__tests__/CHeaderDivider.spec.ts
new file mode 100644
index 00000000..0f6a83c4
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/CHeaderDivider.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CHeaderDivider as Component } from '../../../index'
+
+const ComponentName = 'CHeaderDivider'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('header-divider')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/header/__tests__/CHeaderNav.spec.ts b/packages/coreui-vue/src/components/header/__tests__/CHeaderNav.spec.ts
new file mode 100644
index 00000000..13867aaa
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/CHeaderNav.spec.ts
@@ -0,0 +1,45 @@
+import { mount } from '@vue/test-utils'
+import { CHeaderNav as Component } from '../../../index'
+
+const ComponentName = 'CHeaderNav'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('header-nav')).toBe(true)
+ expect(defaultWrapper.attributes('role')).toBe('navigation')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('header-nav')).toBe(true)
+ expect(customWrapper.attributes('role')).toBe('navigation')
+ })
+})
diff --git a/packages/coreui-vue/src/components/header/__tests__/CHeaderText.spec.ts b/packages/coreui-vue/src/components/header/__tests__/CHeaderText.spec.ts
new file mode 100644
index 00000000..48638b5b
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/CHeaderText.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CHeaderText as Component } from '../../../index'
+
+const ComponentName = 'CHeaderText'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('header-text')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/header/__tests__/CHeaderToggler.spec.ts b/packages/coreui-vue/src/components/header/__tests__/CHeaderToggler.spec.ts
new file mode 100644
index 00000000..35c6f4bf
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/CHeaderToggler.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CHeaderToggler as Component } from '../../../index'
+
+const ComponentName = 'CHeaderToggler'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('header-toggler')).toBe(true)
+ expect(defaultWrapper.attributes('type')).toBe('button')
+ expect(defaultWrapper.attributes('aria-label')).toBe('Toggle navigation')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('header-toggler')).toBe(true)
+ expect(customWrapper.attributes('type')).toBe('button')
+ expect(customWrapper.attributes('aria-label')).toBe('Toggle navigation')
+ expect(customWrapper.find('span').classes('header-toggler-icon')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeader.spec.ts.snap b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeader.spec.ts.snap
new file mode 100644
index 00000000..565c875c
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeader.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CHeader component renders correctly 1`] = `
+""
+`;
+
+exports[`Loads and display CHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.ts.snap b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.ts.snap
new file mode 100644
index 00000000..a2b61995
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderBrand.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CHeaderBrand component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CHeaderBrand component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.ts.snap b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.ts.snap
new file mode 100644
index 00000000..36376c1f
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderDivider.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CHeaderDivider component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.ts.snap b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.ts.snap
new file mode 100644
index 00000000..0e33b9b4
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderNav.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CHeaderNav component renders correctly 1`] = `""`;
+
+exports[`Loads and display CHeaderNav component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderText.spec.ts.snap b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderText.spec.ts.snap
new file mode 100644
index 00000000..c9a6a8f4
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderText.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CHeaderText component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.ts.snap b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.ts.snap
new file mode 100644
index 00000000..c0da6cf0
--- /dev/null
+++ b/packages/coreui-vue/src/components/header/__tests__/__snapshots__/CHeaderToggler.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CHeaderToggler component renders correctly 1`] = `""`;
+
+exports[`Loads and display CHeaderToggler component renders correctly 1`] = `""`;
diff --git a/src/components/header/index.ts b/packages/coreui-vue/src/components/header/index.ts
similarity index 100%
rename from src/components/header/index.ts
rename to packages/coreui-vue/src/components/header/index.ts
diff --git a/src/components/image/CImage.ts b/packages/coreui-vue/src/components/image/CImage.ts
similarity index 79%
rename from src/components/image/CImage.ts
rename to packages/coreui-vue/src/components/image/CImage.ts
index 7bae46c3..9d122ee3 100644
--- a/src/components/image/CImage.ts
+++ b/packages/coreui-vue/src/components/image/CImage.ts
@@ -10,8 +10,6 @@ const CImage = defineComponent({
*/
align: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['start', 'center', 'end'].includes(value)
},
@@ -19,24 +17,15 @@ const CImage = defineComponent({
/**
* Make image responsive.
*/
- fluid: {
- type: Boolean,
- required: false,
- },
+ fluid: Boolean,
/**
* Make image rounded.
*/
- rounded: {
- type: Boolean,
- required: false,
- },
+ rounded: Boolean,
/**
* Give an image a rounded 1px border appearance.
*/
- thumbnail: {
- type: Boolean,
- required: false,
- },
+ thumbnail: Boolean,
},
setup(props) {
return () =>
diff --git a/packages/coreui-vue/src/components/image/__tests__/CImage.spec.ts b/packages/coreui-vue/src/components/image/__tests__/CImage.spec.ts
new file mode 100644
index 00000000..c7c18545
--- /dev/null
+++ b/packages/coreui-vue/src/components/image/__tests__/CImage.spec.ts
@@ -0,0 +1,57 @@
+import { mount } from '@vue/test-utils'
+import { CImage as Component } from '../../../index'
+
+const ComponentName = 'CImage'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ align: 'end',
+ fluid: true,
+ rounded: true,
+ thumbnail: true,
+ },
+ slots: {},
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ align: 'center',
+ },
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('float-end')).toBe(true)
+ expect(customWrapper.classes('img-fluid')).toBe(true)
+ expect(customWrapper.classes('rounded')).toBe(true)
+ expect(customWrapper.classes('img-thumbnail')).toBe(true)
+ })
+})
+
+describe(`Customize (two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.classes('d-block')).toBe(true)
+ expect(customWrapperTwo.classes('mx-auto')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/image/__tests__/__snapshots__/CImage.spec.ts.snap b/packages/coreui-vue/src/components/image/__tests__/__snapshots__/CImage.spec.ts.snap
new file mode 100644
index 00000000..808f6428
--- /dev/null
+++ b/packages/coreui-vue/src/components/image/__tests__/__snapshots__/CImage.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (two) CImage component renders correctly 1`] = `" "`;
+
+exports[`Customize CImage component renders correctly 1`] = `" "`;
+
+exports[`Loads and display CImage component renders correctly 1`] = `" "`;
diff --git a/src/components/image/index.ts b/packages/coreui-vue/src/components/image/index.ts
similarity index 100%
rename from src/components/image/index.ts
rename to packages/coreui-vue/src/components/image/index.ts
diff --git a/src/components/index.ts b/packages/coreui-vue/src/components/index.ts
similarity index 91%
rename from src/components/index.ts
rename to packages/coreui-vue/src/components/index.ts
index 04c2c355..0d3dae9e 100644
--- a/src/components/index.ts
+++ b/packages/coreui-vue/src/components/index.ts
@@ -24,10 +24,13 @@ export * from './nav'
export * from './navbar'
export * from './offcanvas'
export * from './pagination'
+export * from './placeholder'
export * from './progress'
+export * from './popover'
export * from './sidebar'
export * from './spinner'
export * from './table'
export * from './tabs'
export * from './toast'
+export * from './tooltip'
export * from './widgets'
diff --git a/src/components/link/CLink.ts b/packages/coreui-vue/src/components/link/CLink.ts
similarity index 81%
rename from src/components/link/CLink.ts
rename to packages/coreui-vue/src/components/link/CLink.ts
index 81f43d4b..63766e56 100644
--- a/src/components/link/CLink.ts
+++ b/packages/coreui-vue/src/components/link/CLink.ts
@@ -6,35 +6,29 @@ const CLink = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Component used for the root node. Either a string to use a HTML element or a component.
*/
component: {
type: String,
- required: false,
default: 'a',
},
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* The href attribute specifies the URL of the page the link goes to.
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
},
- emits: ['click'],
+ emits: [
+ /**
+ * Event called when the user clicks on the component.
+ */
+ 'click',
+ ],
setup(props, { slots, emit }) {
const handleClick = () => {
emit('click', props.href)
diff --git a/packages/coreui-vue/src/components/link/__tests__/CLink.spec.ts b/packages/coreui-vue/src/components/link/__tests__/CLink.spec.ts
new file mode 100644
index 00000000..f3c8c7dd
--- /dev/null
+++ b/packages/coreui-vue/src/components/link/__tests__/CLink.spec.ts
@@ -0,0 +1,57 @@
+import { mount } from '@vue/test-utils'
+import { CLink as Component } from '../../../index'
+
+const ComponentName = 'CLink'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ disabled: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ component: 'div',
+ disabled: true,
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.attributes('aria-disabled')).toBe('true')
+ expect(defaultWrapper.attributes('tabindex')).toBe('-1')
+ })
+ it('emit event on click', () => {
+ defaultWrapper.trigger('click')
+ const incrementEvent = defaultWrapper.emitted('click')
+ expect(incrementEvent).toHaveLength(1)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.attributes('aria-current')).toBe('page')
+ expect(customWrapper.attributes('href')).toBe('/bazinga')
+ })
+})
diff --git a/packages/coreui-vue/src/components/link/__tests__/__snapshots__/CLink.spec.ts.snap b/packages/coreui-vue/src/components/link/__tests__/__snapshots__/CLink.spec.ts.snap
new file mode 100644
index 00000000..ab1d8241
--- /dev/null
+++ b/packages/coreui-vue/src/components/link/__tests__/__snapshots__/CLink.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CLink component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CLink component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/link/index.ts b/packages/coreui-vue/src/components/link/index.ts
similarity index 100%
rename from src/components/link/index.ts
rename to packages/coreui-vue/src/components/link/index.ts
diff --git a/src/components/list-group/CListGroup.ts b/packages/coreui-vue/src/components/list-group/CListGroup.ts
similarity index 80%
rename from src/components/list-group/CListGroup.ts
rename to packages/coreui-vue/src/components/list-group/CListGroup.ts
index 5edae637..57003be4 100644
--- a/src/components/list-group/CListGroup.ts
+++ b/packages/coreui-vue/src/components/list-group/CListGroup.ts
@@ -5,30 +5,22 @@ const CListGroup = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'ul'
*/
component: {
type: String,
- required: false,
default: 'ul',
},
/**
* Remove some borders and rounded corners to render list group items edge-to-edge in a parent component (e.g., ``)
*/
- flush: {
- type: Boolean,
- required: false,
- },
+ flush: Boolean,
/**
* Specify a layout type.
*
- * @value 'horizontal', 'horizontal-sm', 'horizontal-md', 'horizontal-lg', 'horizontal-xl', 'horizontal-xxl',
+ * @values 'horizontal', 'horizontal-sm', 'horizontal-md', 'horizontal-lg', 'horizontal-xl', 'horizontal-xxl',
*/
layout: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return [
'horizontal',
diff --git a/src/components/list-group/CListGroupItem.ts b/packages/coreui-vue/src/components/list-group/CListGroupItem.ts
similarity index 87%
rename from src/components/list-group/CListGroupItem.ts
rename to packages/coreui-vue/src/components/list-group/CListGroupItem.ts
index c6e4f1ba..0342f1fe 100644
--- a/src/components/list-group/CListGroupItem.ts
+++ b/packages/coreui-vue/src/components/list-group/CListGroupItem.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CListGroupItem = defineComponent({
name: 'CListGroupItem',
@@ -8,10 +8,7 @@ const CListGroupItem = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
*
@@ -21,18 +18,12 @@ const CListGroupItem = defineComponent({
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'li'
*/
component: {
type: String,
- required: false,
default: 'li',
},
},
diff --git a/packages/coreui-vue/src/components/list-group/__tests__/CListGroup.spec.ts b/packages/coreui-vue/src/components/list-group/__tests__/CListGroup.spec.ts
new file mode 100644
index 00000000..092d62c2
--- /dev/null
+++ b/packages/coreui-vue/src/components/list-group/__tests__/CListGroup.spec.ts
@@ -0,0 +1,47 @@
+import { mount } from '@vue/test-utils'
+import { CListGroup as Component } from '../../../index'
+
+const ComponentName = 'CListGroup'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ flush: true,
+ layout: 'horizontal-lg',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('list-group')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('list-group')).toBe(true)
+ expect(customWrapper.classes('list-group-flush')).toBe(true)
+ expect(customWrapper.classes('list-group-horizontal-lg')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/list-group/__tests__/CListGroupItem.spec.ts b/packages/coreui-vue/src/components/list-group/__tests__/CListGroupItem.spec.ts
new file mode 100644
index 00000000..41e9def2
--- /dev/null
+++ b/packages/coreui-vue/src/components/list-group/__tests__/CListGroupItem.spec.ts
@@ -0,0 +1,75 @@
+import { mount } from '@vue/test-utils'
+import { CListGroupItem as Component } from '../../../index'
+
+const ComponentName = 'CListGroupItem'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ color: 'warning',
+ disabled: true,
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ component: 'button',
+ active: true,
+ disabled: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('list-group-item')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('list-group-item')).toBe(true)
+ expect(customWrapper.classes('list-group-item-warning')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.attributes('aria-current')).toBe('true')
+ expect(customWrapper.attributes('aria-disabled')).toBe('true')
+ })
+})
+
+describe(`Customize (two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.text()).toContain('Default slot')
+ expect(customWrapperTwo.classes('list-group-item')).toBe(true)
+ expect(customWrapperTwo.classes('list-group-item-action')).toBe(true)
+ expect(customWrapperTwo.attributes('active')).toBe('true')
+ expect(customWrapperTwo.attributes('disabled')).toBe('')
+ })
+})
diff --git a/packages/coreui-vue/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.ts.snap b/packages/coreui-vue/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.ts.snap
new file mode 100644
index 00000000..dca65991
--- /dev/null
+++ b/packages/coreui-vue/src/components/list-group/__tests__/__snapshots__/CListGroup.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CListGroup component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CListGroup component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.ts.snap b/packages/coreui-vue/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.ts.snap
new file mode 100644
index 00000000..198cf490
--- /dev/null
+++ b/packages/coreui-vue/src/components/list-group/__tests__/__snapshots__/CListGroupItem.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (two) CListGroupItem component renders correctly 1`] = `"Default slot "`;
+
+exports[`Customize CListGroupItem component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CListGroupItem component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/list-group/index.ts b/packages/coreui-vue/src/components/list-group/index.ts
similarity index 100%
rename from src/components/list-group/index.ts
rename to packages/coreui-vue/src/components/list-group/index.ts
diff --git a/src/components/modal/CModal.ts b/packages/coreui-vue/src/components/modal/CModal.ts
similarity index 54%
rename from src/components/modal/CModal.ts
rename to packages/coreui-vue/src/components/modal/CModal.ts
index 32014eca..ff9805a8 100644
--- a/src/components/modal/CModal.ts
+++ b/packages/coreui-vue/src/components/modal/CModal.ts
@@ -1,19 +1,30 @@
-import { defineComponent, h, ref, RendererElement, Transition } from 'vue'
+import {
+ defineComponent,
+ h,
+ provide,
+ ref,
+ RendererElement,
+ Transition,
+ vShow,
+ watch,
+ withDirectives,
+} from 'vue'
-import { CBackdrop } from './../backdrop/CBackdrop'
+import { CBackdrop } from '../backdrop/CBackdrop'
+
+import { executeAfterTransition } from '../../utils/transition'
const CModal = defineComponent({
name: 'CModal',
+ inheritAttrs: false,
props: {
/**
* Align the modal in the center or top of the screen.
*
- * @default 'top'
* @values 'top', 'center'
*/
alignment: {
default: 'top',
- required: false,
validator: (value: string) => {
return ['top', 'center'].includes(value)
},
@@ -21,23 +32,25 @@ const CModal = defineComponent({
/**
* Apply a backdrop on body while offcanvas is open.
*
- * @default true
- * @values boolean, 'static'
+ * @values boolean | 'static'
*/
backdrop: {
type: [Boolean, String],
default: true,
- require: false,
+ validator: (value: boolean | string) => {
+ if (typeof value == 'string') {
+ return ['static'].includes(value)
+ }
+ if (typeof value == 'boolean') {
+ return true
+ }
+ return false
+ },
},
/**
* A string of all className you want applied to the modal content component.
- * TODO: Consider if we should change this prop name to describe better its role.
*/
- className: {
- type: String,
- default: undefined,
- required: false,
- },
+ contentClassName: String,
/**
* Set modal to covers the entire user viewport
*
@@ -45,8 +58,6 @@ const CModal = defineComponent({
*/
fullscreen: {
type: [Boolean, String],
- default: undefined,
- required: false,
validator: (value: boolean | string) => {
if (typeof value == 'string') {
return ['sm', 'md', 'lg', 'xl', 'xxl'].includes(value)
@@ -59,29 +70,15 @@ const CModal = defineComponent({
},
/**
* Closes the modal when escape key is pressed.
- *
- * @default true
*/
keyboard: {
type: Boolean,
default: true,
- required: false,
- },
- /**
- * Does the modal dialog itself scroll, or does the whole dialog scroll within the window.
- */
- dismiss: {
- type: Boolean,
- default: false,
- required: false,
},
/**
* Create a scrollable modal that allows scrolling the modal body.
*/
- scrollable: {
- type: Boolean,
- required: false,
- },
+ scrollable: Boolean,
/**
* Size the component small, large, or extra large.
*
@@ -89,8 +86,6 @@ const CModal = defineComponent({
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['sm', 'lg', 'xl'].includes(value)
},
@@ -101,54 +96,84 @@ const CModal = defineComponent({
transition: {
type: Boolean,
default: true,
- required: false,
},
/**
- * Toggle the visibility of alert component.
+ * By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false.
*/
- visible: {
+ unmountOnClose: {
type: Boolean,
- required: false,
+ default: true,
},
+ /**
+ * Toggle the visibility of alert component.
+ */
+ visible: Boolean,
},
emits: [
/**
- * Event called before the dissmiss animation has started.
+ * Callback fired when the component requests to be closed.
*/
- 'dismiss',
+ 'close',
+ /**
+ * Callback fired when the component requests to be closed.
+ */
+ 'close-prevented',
+ /**
+ * Callback fired when the modal is shown, its backdrop is static and a click outside the modal or an escape key press is performed with the keyboard option set to false.
+ */
+ 'show',
],
setup(props, { slots, attrs, emit }) {
const modalRef = ref()
const modalContentRef = ref()
+ const visible = ref(props.visible)
+
+ watch(
+ () => props.visible,
+ () => {
+ visible.value = props.visible
+ },
+ )
+
const handleEnter = (el: RendererElement, done: () => void) => {
- el.addEventListener('transitionend', () => {
- done()
- })
+ executeAfterTransition(() => done(), el as HTMLElement)
document.body.classList.add('modal-open')
+ document.body.style.overflow = 'hidden'
+ document.body.style.paddingRight = '0px'
el.style.display = 'block'
setTimeout(() => {
el.classList.add('show')
}, 1)
+ emit('show')
}
+
const handleAfterEnter = () => {
- window.addEventListener('click', handleClickOutside)
+ window.addEventListener('mousedown', handleMouseDown)
window.addEventListener('keyup', handleKeyUp)
}
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
const handleLeave = (el: RendererElement, done: () => void) => {
- el.addEventListener('transitionend', () => {
- done()
- })
+ executeAfterTransition(() => done(), el as HTMLElement)
document.body.classList.remove('modal-open')
+ document.body.style.removeProperty('overflow')
+ document.body.style.removeProperty('padding-right')
+ if (document.body.className === '') {
+ document.body.removeAttribute('class')
+ }
+
el.classList.remove('show')
}
+
const handleAfterLeave = (el: RendererElement) => {
- window.removeEventListener('click', handleClickOutside)
+ window.removeEventListener('mousedown', handleMouseDown)
window.removeEventListener('keyup', handleKeyUp)
el.style.display = 'none'
}
const handleDismiss = () => {
- emit('dismiss')
+ emit('close')
+ visible.value = false
}
const handleKeyUp = (event: KeyboardEvent) => {
@@ -156,19 +181,27 @@ const CModal = defineComponent({
if (props.backdrop !== 'static' && event.key === 'Escape' && props.keyboard) {
handleDismiss()
}
+
if (props.backdrop === 'static') {
modalRef.value.classList.add('modal-static')
+ emit('close-prevented')
setTimeout(() => {
modalRef.value.classList.remove('modal-static')
}, 300)
}
}
}
- const handleClickOutside = (event: Event) => {
+
+ const handleMouseDown = (event: Event) => {
+ window.addEventListener('mouseup', () => handleMouseUp(event), { once: true })
+ }
+
+ const handleMouseUp = (event: Event) => {
if (modalContentRef.value && !modalContentRef.value.contains(event.target as HTMLElement)) {
if (props.backdrop !== 'static') {
handleDismiss()
}
+
if (props.backdrop === 'static') {
modalRef.value.classList.add('modal-static')
setTimeout(() => {
@@ -178,56 +211,64 @@ const CModal = defineComponent({
}
}
+ provide('handleDismiss', handleDismiss)
+
+ const modal = () =>
+ h(
+ 'div',
+ {
+ class: [
+ 'modal',
+ {
+ ['fade']: props.transition,
+ },
+ attrs.class,
+ ],
+ ref: modalRef,
+ },
+ h(
+ 'div',
+ {
+ class: [
+ 'modal-dialog',
+ {
+ 'modal-dialog-centered': props.alignment === 'center',
+ [`modal-fullscreen-${props.fullscreen}-down`]:
+ props.fullscreen && typeof props.fullscreen === 'string',
+ 'modal-fullscreen': props.fullscreen && typeof props.fullscreen === 'boolean',
+ ['modal-dialog-scrollable']: props.scrollable,
+ [`modal-${props.size}`]: props.size,
+ },
+ ],
+ role: 'dialog',
+ },
+ h(
+ 'div',
+ { class: ['modal-content', props.contentClassName], ref: modalContentRef },
+ slots.default && slots.default(),
+ ),
+ ),
+ )
+
return () => [
h(
Transition,
{
+ css: false,
onEnter: (el, done) => handleEnter(el, done),
onAfterEnter: () => handleAfterEnter(),
onLeave: (el, done) => handleLeave(el, done),
onAfterLeave: (el) => handleAfterLeave(el),
},
() =>
- props.visible &&
- h(
- 'div',
- {
- class: [
- 'modal',
- {
- ['fade']: props.transition,
- },
- attrs.class,
- ],
- ref: modalRef,
- },
- h(
- 'div',
- {
- class: [
- 'modal-dialog',
- {
- 'modal-dialog-centered': props.alignment === 'center',
- [`modal-fullscreen-${props.fullscreen}-down`]:
- props.fullscreen && typeof props.fullscreen === 'string',
- 'modal-fullscreen': props.fullscreen && typeof props.fullscreen === 'boolean',
- ['modal-dialog-scrollable']: props.scrollable,
- [`modal-${props.size}`]: props.size,
- },
- ],
- },
- h(
- 'div',
- { class: ['modal-content', props.className], ref: modalContentRef },
- slots.default && slots.default(),
- ),
- ),
- ),
+ props.unmountOnClose
+ ? visible.value && modal()
+ : withDirectives(modal(), [[vShow, visible.value]]),
),
props.backdrop &&
h(CBackdrop, {
class: 'modal-backdrop',
- visible: props.visible,
+ visible: visible.value,
}),
]
},
diff --git a/src/components/modal/CModalBody.ts b/packages/coreui-vue/src/components/modal/CModalBody.ts
similarity index 100%
rename from src/components/modal/CModalBody.ts
rename to packages/coreui-vue/src/components/modal/CModalBody.ts
diff --git a/src/components/modal/CModalFooter.ts b/packages/coreui-vue/src/components/modal/CModalFooter.ts
similarity index 100%
rename from src/components/modal/CModalFooter.ts
rename to packages/coreui-vue/src/components/modal/CModalFooter.ts
diff --git a/packages/coreui-vue/src/components/modal/CModalHeader.ts b/packages/coreui-vue/src/components/modal/CModalHeader.ts
new file mode 100644
index 00000000..108a8ff2
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/CModalHeader.ts
@@ -0,0 +1,26 @@
+import { defineComponent, h, inject } from 'vue'
+
+import { CCloseButton } from '../close-button/CCloseButton'
+
+const CModalHeader = defineComponent({
+ name: 'CModalHeader',
+ props: {
+ /**
+ * Add a close button component to the header.
+ */
+ closeButton: {
+ type: Boolean,
+ default: true,
+ },
+ },
+ setup(props, { slots }) {
+ const handleDismiss = inject('handleDismiss') as () => void
+ return () =>
+ h('span', { class: 'modal-header' }, [
+ slots.default && slots.default(),
+ props.closeButton && h(CCloseButton, { onClick: () => handleDismiss() }, ''),
+ ])
+ },
+})
+
+export { CModalHeader }
diff --git a/src/components/modal/CModalTitle.ts b/packages/coreui-vue/src/components/modal/CModalTitle.ts
similarity index 89%
rename from src/components/modal/CModalTitle.ts
rename to packages/coreui-vue/src/components/modal/CModalTitle.ts
index eacb1061..ea970c09 100644
--- a/src/components/modal/CModalTitle.ts
+++ b/packages/coreui-vue/src/components/modal/CModalTitle.ts
@@ -5,13 +5,10 @@ const CModalTitle = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'h5'
*/
component: {
type: String,
default: 'h5',
- required: false,
},
},
setup(props, { slots }) {
diff --git a/packages/coreui-vue/src/components/modal/__tests__/CModal.spec.ts b/packages/coreui-vue/src/components/modal/__tests__/CModal.spec.ts
new file mode 100644
index 00000000..93f86be3
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/CModal.spec.ts
@@ -0,0 +1,86 @@
+import { mount } from '@vue/test-utils'
+import { CModal as Component } from '../../../index'
+
+const ComponentName = 'CModal'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ fullscreen: true,
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ alignment: 'center',
+ backdrop: false,
+ contentClassName: 'bazinga',
+ fullscreen: 'lg',
+ keyboard: true,
+ scrollable: true,
+ size: 'lg',
+ transition: false,
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('.modal').classes('modal')).toBe(true)
+ expect(defaultWrapper.find('.modal').classes('fade')).toBe(true)
+ expect(defaultWrapper.find('.modal-dialog').classes('modal-dialog')).toBe(true)
+ expect(defaultWrapper.find('.modal-dialog').classes('modal-fullscreen')).toBe(true)
+ expect(defaultWrapper.find('.modal-content').classes('modal-content')).toBe(true)
+ expect(defaultWrapper.find('.modal-backdrop').classes('modal-backdrop')).toBe(true)
+ })
+ /*
+ it('event on click backdrop', async () => {
+ await defaultWrapper.find('.modal-backdrop').trigger('click')
+ const incrementEvent = defaultWrapper.emitted('dismiss')
+ expect(incrementEvent).toHaveLength(1)
+ })
+ */
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('.modal').classes('modal')).toBe(true)
+ expect(customWrapper.find('.modal-dialog').classes('modal-dialog')).toBe(true)
+ expect(customWrapper.find('.modal-dialog').classes('modal-dialog-centered')).toBe(true)
+ expect(customWrapper.find('.modal-dialog').classes('modal-fullscreen-lg-down')).toBe(true)
+ expect(customWrapper.find('.modal-dialog').classes('modal-dialog-scrollable')).toBe(true)
+ expect(customWrapper.find('.modal-dialog').classes('modal-lg')).toBe(true)
+ expect(customWrapper.find('.modal-content').classes('modal-content')).toBe(true)
+ expect(customWrapper.find('.modal-content').classes('bazinga')).toBe(true)
+ })
+ /*
+
+ TODO: Test keyup and click on backdrop (events are init on transition onAfterEnter)
+
+ it('event on keyup', async () => {
+ await nextTick()
+ await customWrapper.trigger('keyup', {
+ keyCode: 27
+ })
+ const incrementEvent = customWrapper.emitted('dismiss')
+ expect(incrementEvent).toHaveLength(1)
+ })
+ */
+})
diff --git a/packages/coreui-vue/src/components/modal/__tests__/CModalBody.spec.ts b/packages/coreui-vue/src/components/modal/__tests__/CModalBody.spec.ts
new file mode 100644
index 00000000..18e96d7c
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/CModalBody.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CModalBody as Component } from '../../../index'
+
+const ComponentName = 'CModalBody'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('modal-body')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/modal/__tests__/CModalFooter.spec.ts b/packages/coreui-vue/src/components/modal/__tests__/CModalFooter.spec.ts
new file mode 100644
index 00000000..7be6fb79
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/CModalFooter.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CModalFooter as Component } from '../../../index'
+
+const ComponentName = 'CModalFooter'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('modal-footer')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/modal/__tests__/CModalHeader.spec.ts b/packages/coreui-vue/src/components/modal/__tests__/CModalHeader.spec.ts
new file mode 100644
index 00000000..6a2cba15
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/CModalHeader.spec.ts
@@ -0,0 +1,45 @@
+import { mount } from '@vue/test-utils'
+import { CModalHeader as Component } from '../../../index'
+
+const ComponentName = 'CModalHeader'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ closeButton: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('modal-header')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('modal-header')).toBe(true)
+ expect(customWrapper.find('button').classes('btn')).toBe(true)
+ expect(customWrapper.find('button').classes('btn-close')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/modal/__tests__/CModalTitle.spec.ts b/packages/coreui-vue/src/components/modal/__tests__/CModalTitle.spec.ts
new file mode 100644
index 00000000..28df672b
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/CModalTitle.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { CModalTitle as Component } from '../../../index'
+
+const ComponentName = 'CModalTitle'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('modal-title')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('modal-title')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModal.spec.ts.snap b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModal.spec.ts.snap
new file mode 100644
index 00000000..81cb267c
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModal.spec.ts.snap
@@ -0,0 +1,24 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CModal component renders correctly 1`] = `
+"
+
+ "
+`;
+
+exports[`Loads and display CModal component renders correctly 1`] = `
+"
+
+
+
+
+ "
+`;
diff --git a/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalBody.spec.ts.snap b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalBody.spec.ts.snap
new file mode 100644
index 00000000..b3bcb34c
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalBody.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CModalBody component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.ts.snap b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.ts.snap
new file mode 100644
index 00000000..a87577d0
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalFooter.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CModalFooter component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.ts.snap b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.ts.snap
new file mode 100644
index 00000000..abeb2a67
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalHeader.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CModalHeader component renders correctly 1`] = `""`;
+
+exports[`Loads and display CModalHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.ts.snap b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.ts.snap
new file mode 100644
index 00000000..fe60a9b6
--- /dev/null
+++ b/packages/coreui-vue/src/components/modal/__tests__/__snapshots__/CModalTitle.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CModalTitle component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CModalTitle component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/modal/index.ts b/packages/coreui-vue/src/components/modal/index.ts
similarity index 100%
rename from src/components/modal/index.ts
rename to packages/coreui-vue/src/components/modal/index.ts
diff --git a/src/components/nav/CNav.ts b/packages/coreui-vue/src/components/nav/CNav.ts
similarity index 88%
rename from src/components/nav/CNav.ts
rename to packages/coreui-vue/src/components/nav/CNav.ts
index 73f87e2c..add7ef70 100644
--- a/src/components/nav/CNav.ts
+++ b/packages/coreui-vue/src/components/nav/CNav.ts
@@ -5,12 +5,9 @@ const CNav = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'ul'
*/
component: {
type: String,
- required: false,
default: 'ul',
},
/**
@@ -20,8 +17,6 @@ const CNav = defineComponent({
*/
layout: {
type: String,
- required: false,
- default: undefined,
validator: (value: string) => {
return ['fill', 'justified'].includes(value)
},
@@ -33,8 +28,6 @@ const CNav = defineComponent({
*/
variant: {
type: String,
- required: false,
- default: undefined,
validator: (value: string) => {
return ['tabs', 'pills'].includes(value)
},
diff --git a/src/components/nav/CNavGroup.ts b/packages/coreui-vue/src/components/nav/CNavGroup.ts
similarity index 80%
rename from src/components/nav/CNavGroup.ts
rename to packages/coreui-vue/src/components/nav/CNavGroup.ts
index 3037e94c..a0e8815f 100644
--- a/src/components/nav/CNavGroup.ts
+++ b/packages/coreui-vue/src/components/nav/CNavGroup.ts
@@ -1,4 +1,6 @@
-import { defineComponent, h, onMounted, onUpdated, ref, RendererElement, Transition } from 'vue'
+import { defineComponent, h, onMounted, ref, RendererElement, Transition, watch } from 'vue'
+
+import { executeAfterTransition } from '../../utils/transition'
const CNavGroup = defineComponent({
name: 'CNavGroup',
@@ -14,9 +16,8 @@ const CNavGroup = defineComponent({
},
emits: ['visible-change'],
setup(props, { slots, emit }) {
- const visible = ref(props.visible)
+ const visible = ref()
const navGroupRef = ref()
-
const visibleGroup = ref()
const handleVisibleChange = (visible: boolean, index: number) => {
@@ -32,46 +33,60 @@ const CNavGroup = defineComponent({
const isVisible = (index: number) => Boolean(visibleGroup.value === index)
onMounted(() => {
+ visible.value = props.visible
props.visible && navGroupRef.value.classList.add('show')
emit('visible-change', visible.value)
})
- onUpdated(() => {
- visible.value = props.visible
+ watch(
+ () => props.visible,
+ () => {
+ visible.value = props.visible
- if (visible.value === false) {
- visibleGroup.value = undefined
- }
+ if (visible.value === false) {
+ visibleGroup.value = undefined
+ }
+ },
+ )
+
+ watch(visible, () => {
+ emit('visible-change', visible.value)
})
- const handleTogglerClick = function () {
+ const handleTogglerClick = () => {
visible.value = !visible.value
emit('visible-change', visible.value)
}
+
const handleBeforeEnter = (el: RendererElement) => {
el.style.height = '0px'
navGroupRef.value.classList.add('show')
}
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
const handleEnter = (el: RendererElement, done: () => void) => {
- el.addEventListener('transitionend', () => {
- done()
- })
+ executeAfterTransition(() => done(), el as HTMLElement)
el.style.height = `${el.scrollHeight}px`
}
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
const handleAfterEnter = (el: RendererElement) => {
el.style.height = 'auto'
}
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
const handleBeforeLeave = (el: RendererElement) => {
el.style.height = `${el.scrollHeight}px`
}
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
const handleLeave = (el: RendererElement, done: () => void) => {
- el.addEventListener('transitionend', () => {
- done()
- })
+ executeAfterTransition(() => done(), el as HTMLElement)
setTimeout(() => {
el.style.height = '0px'
}, 1)
}
+
const handleAfterLeave = () => {
navGroupRef.value.classList.remove('show')
}
diff --git a/src/components/nav/CNavGroupItems.ts b/packages/coreui-vue/src/components/nav/CNavGroupItems.ts
similarity index 83%
rename from src/components/nav/CNavGroupItems.ts
rename to packages/coreui-vue/src/components/nav/CNavGroupItems.ts
index cafce0f3..3988b260 100644
--- a/src/components/nav/CNavGroupItems.ts
+++ b/packages/coreui-vue/src/components/nav/CNavGroupItems.ts
@@ -1,5 +1,3 @@
-// TODO: Consider whether this component is needed
-
import { defineComponent, h } from 'vue'
const CNavGroupItems = defineComponent({
diff --git a/src/components/nav/CNavItem.ts b/packages/coreui-vue/src/components/nav/CNavItem.ts
similarity index 100%
rename from src/components/nav/CNavItem.ts
rename to packages/coreui-vue/src/components/nav/CNavItem.ts
diff --git a/src/components/nav/CNavLink.ts b/packages/coreui-vue/src/components/nav/CNavLink.ts
similarity index 76%
rename from src/components/nav/CNavLink.ts
rename to packages/coreui-vue/src/components/nav/CNavLink.ts
index 03ff832a..db5c183d 100644
--- a/src/components/nav/CNavLink.ts
+++ b/packages/coreui-vue/src/components/nav/CNavLink.ts
@@ -8,35 +8,22 @@ const CNavLink = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'a'
*/
component: {
type: String,
- required: false,
default: 'a',
},
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* @ignore
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
},
setup(props, { slots }) {
return () =>
diff --git a/src/components/nav/CNavTitle.ts b/packages/coreui-vue/src/components/nav/CNavTitle.ts
similarity index 100%
rename from src/components/nav/CNavTitle.ts
rename to packages/coreui-vue/src/components/nav/CNavTitle.ts
diff --git a/packages/coreui-vue/src/components/nav/__tests__/CNav.spec.ts b/packages/coreui-vue/src/components/nav/__tests__/CNav.spec.ts
new file mode 100644
index 00000000..59ea597d
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/CNav.spec.ts
@@ -0,0 +1,49 @@
+import { mount } from '@vue/test-utils'
+import { CNav as Component } from '../../../index'
+
+const ComponentName = 'CNav'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ layout: 'fill',
+ variant: 'pills',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('nav')).toBe(true)
+ expect(defaultWrapper.attributes('role')).toBe('navigation')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('nav')).toBe(true)
+ expect(customWrapper.classes('nav-fill')).toBe(true)
+ expect(customWrapper.classes('nav-pills')).toBe(true)
+ expect(customWrapper.attributes('role')).toBe('navigation')
+ })
+})
diff --git a/packages/coreui-vue/src/components/nav/__tests__/CNavGroup.spec.ts b/packages/coreui-vue/src/components/nav/__tests__/CNavGroup.spec.ts
new file mode 100644
index 00000000..8bf3cda9
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/CNavGroup.spec.ts
@@ -0,0 +1,51 @@
+import { mount } from '@vue/test-utils'
+import { CNavGroup as Component } from '../../../index'
+
+const ComponentName = 'CNavGroup'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ compact: true,
+ visible: true,
+ },
+ slots: {
+ togglerContent: 'togglerContent',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('nav-group')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.find('a').text()).toContain('togglerContent')
+ expect(customWrapper.find('a').classes('nav-link')).toBe(true)
+ expect(customWrapper.find('a').classes('nav-group-toggle')).toBe(true)
+ expect(customWrapper.find('ul').classes('nav-group-items')).toBe(true)
+ expect(customWrapper.find('ul').classes('compact')).toBe(true)
+ expect(customWrapper.classes('nav-group')).toBe(true)
+ })
+ it('emit event visible-change on click nav-group-toggle', () => {
+ let incrementEvent = customWrapper.emitted('visible-change')
+ customWrapper.find('.nav-group-toggle').trigger('click')
+ incrementEvent = customWrapper.emitted('visible-change')
+ expect(incrementEvent).toHaveLength(3)
+ })
+})
diff --git a/packages/coreui-vue/src/components/nav/__tests__/CNavGroupItems.spec.ts b/packages/coreui-vue/src/components/nav/__tests__/CNavGroupItems.spec.ts
new file mode 100644
index 00000000..2e593021
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/CNavGroupItems.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CNavGroupItems as Component } from '../../../index'
+
+const ComponentName = 'CNavGroupItems'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('nav-group-items')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/nav/__tests__/CNavItem.spec.ts b/packages/coreui-vue/src/components/nav/__tests__/CNavItem.spec.ts
new file mode 100644
index 00000000..f7bee164
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/CNavItem.spec.ts
@@ -0,0 +1,51 @@
+import { mount } from '@vue/test-utils'
+import { CNavItem as Component } from '../../../index'
+
+const ComponentName = 'CNavItem'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ href: '/bazinga',
+ active: true,
+ component: 'div',
+ disabled: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('nav-item')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.find('div').text()).toContain('Default slot')
+ expect(customWrapper.classes('nav-item')).toBe(true)
+ expect(customWrapper.find('div').classes('nav-link')).toBe(true)
+ expect(customWrapper.find('div').classes('active')).toBe(true)
+ expect(customWrapper.find('div').classes('disabled')).toBe(true)
+ expect(customWrapper.find('div').attributes('href')).toBe('/bazinga')
+ expect(customWrapper.find('div').attributes('aria-current')).toBe('page')
+ })
+})
diff --git a/packages/coreui-vue/src/components/nav/__tests__/CNavLink.spec.ts b/packages/coreui-vue/src/components/nav/__tests__/CNavLink.spec.ts
new file mode 100644
index 00000000..9b334d44
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/CNavLink.spec.ts
@@ -0,0 +1,50 @@
+import { mount } from '@vue/test-utils'
+import { CNavLink as Component } from '../../../index'
+
+const ComponentName = 'CNavLink'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ href: '/bazinga',
+ active: true,
+ component: 'div',
+ disabled: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('nav-link')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('nav-link')).toBe(true)
+ expect(customWrapper.classes('active')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.attributes('href')).toBe('/bazinga')
+ expect(customWrapper.attributes('aria-current')).toBe('page')
+ })
+})
diff --git a/packages/coreui-vue/src/components/nav/__tests__/CNavTitle.spec.ts b/packages/coreui-vue/src/components/nav/__tests__/CNavTitle.spec.ts
new file mode 100644
index 00000000..36c84be9
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/CNavTitle.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CNavTitle as Component } from '../../../index'
+
+const ComponentName = 'CNavTitle'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('nav-title')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNav.spec.ts.snap b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNav.spec.ts.snap
new file mode 100644
index 00000000..4d306a7d
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNav.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNav component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CNav component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.ts.snap b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.ts.snap
new file mode 100644
index 00000000..78b1e4cb
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavGroup.spec.ts.snap
@@ -0,0 +1,18 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNavGroup component renders correctly 1`] = `
+"togglerContent
+
+
+
+ "
+`;
+
+exports[`Loads and display CNavGroup component renders correctly 1`] = `
+"
+
+
+
+
+ "
+`;
diff --git a/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.ts.snap b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.ts.snap
new file mode 100644
index 00000000..7e5bd579
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavGroupItems.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CNavGroupItems component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavItem.spec.ts.snap b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavItem.spec.ts.snap
new file mode 100644
index 00000000..7147ee44
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavItem.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNavItem component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
+
+exports[`Loads and display CNavItem component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavLink.spec.ts.snap b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavLink.spec.ts.snap
new file mode 100644
index 00000000..343e8754
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavLink.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNavLink component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CNavLink component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.ts.snap b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.ts.snap
new file mode 100644
index 00000000..44eee351
--- /dev/null
+++ b/packages/coreui-vue/src/components/nav/__tests__/__snapshots__/CNavTitle.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CNavTitle component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/nav/index.ts b/packages/coreui-vue/src/components/nav/index.ts
similarity index 100%
rename from src/components/nav/index.ts
rename to packages/coreui-vue/src/components/nav/index.ts
diff --git a/src/components/navbar/CNavbar.ts b/packages/coreui-vue/src/components/navbar/CNavbar.ts
similarity index 85%
rename from src/components/navbar/CNavbar.ts
rename to packages/coreui-vue/src/components/navbar/CNavbar.ts
index b40e620e..a58486b8 100644
--- a/src/components/navbar/CNavbar.ts
+++ b/packages/coreui-vue/src/components/navbar/CNavbar.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CNavbar = defineComponent({
name: 'CNavbar',
@@ -18,21 +18,16 @@ const CNavbar = defineComponent({
*/
colorScheme: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['dark', 'light'].includes(value)
},
},
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'nav'
*/
component: {
type: String,
default: 'nav',
- required: false,
},
/**
* Defines optional container wrapping children elements.
@@ -41,8 +36,6 @@ const CNavbar = defineComponent({
*/
container: {
type: [Boolean, String],
- default: undefined,
- required: false,
validator: (value: boolean | string) => {
return (
typeof value === 'boolean' || ['sm', 'md', 'lg', 'xl', 'xxl', 'fluid'].includes(value)
@@ -56,8 +49,6 @@ const CNavbar = defineComponent({
*/
expand: {
type: [Boolean, String],
- default: undefined,
- required: false,
validator: (value: boolean | string) => {
return typeof value === 'boolean' || ['sm', 'md', 'lg', 'xl', 'xxl'].includes(value)
},
@@ -69,9 +60,7 @@ const CNavbar = defineComponent({
*/
placement: {
type: String,
- default: undefined,
- required: false,
- validator: (value: string) =>{
+ validator: (value: string) => {
return ['fixed-top', 'fixed-bottom', 'sticky-top'].includes(value)
},
},
@@ -96,7 +85,7 @@ const CNavbar = defineComponent({
props.container
? h(
'div',
- { class: [`container${props.container !== true ? '-' + props.container : ''}`] },
+ { class: [`container${props.container === true ? '' : '-' + props.container}`] },
slots.default && slots.default(),
)
: slots.default && slots.default(),
diff --git a/src/components/navbar/CNavbarBrand.ts b/packages/coreui-vue/src/components/navbar/CNavbarBrand.ts
similarity index 72%
rename from src/components/navbar/CNavbarBrand.ts
rename to packages/coreui-vue/src/components/navbar/CNavbarBrand.ts
index e5c67540..bd8e5211 100644
--- a/src/components/navbar/CNavbarBrand.ts
+++ b/packages/coreui-vue/src/components/navbar/CNavbarBrand.ts
@@ -10,23 +10,18 @@ const CNavbarBrand = defineComponent({
component: {
type: String,
default: 'a',
- required: false,
},
/**
* The href attribute specifies the URL of the page the link goes to.
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
},
setup(props, { slots }) {
return () =>
h(
- props.component ? props.component : props.href ? 'a' : 'span',
+ props.component ?? (props.href ? 'a' : 'span'),
{
- class: 'header-brand',
+ class: 'navbar-brand',
href: props.href,
},
slots.default && slots.default(),
diff --git a/src/components/navbar/CNavbarNav.ts b/packages/coreui-vue/src/components/navbar/CNavbarNav.ts
similarity index 91%
rename from src/components/navbar/CNavbarNav.ts
rename to packages/coreui-vue/src/components/navbar/CNavbarNav.ts
index fccc1b8d..7a36931f 100644
--- a/src/components/navbar/CNavbarNav.ts
+++ b/packages/coreui-vue/src/components/navbar/CNavbarNav.ts
@@ -5,12 +5,9 @@ const CNavbarNav = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'ul'
*/
component: {
type: String,
- required: false,
default: 'ul',
},
},
diff --git a/src/components/navbar/CNavbarText.ts b/packages/coreui-vue/src/components/navbar/CNavbarText.ts
similarity index 100%
rename from src/components/navbar/CNavbarText.ts
rename to packages/coreui-vue/src/components/navbar/CNavbarText.ts
diff --git a/src/components/navbar/CNavbarToggler.ts b/packages/coreui-vue/src/components/navbar/CNavbarToggler.ts
similarity index 100%
rename from src/components/navbar/CNavbarToggler.ts
rename to packages/coreui-vue/src/components/navbar/CNavbarToggler.ts
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/CNavbar.spec.ts b/packages/coreui-vue/src/components/navbar/__tests__/CNavbar.spec.ts
new file mode 100644
index 00000000..aa081f28
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/CNavbar.spec.ts
@@ -0,0 +1,53 @@
+import { mount } from '@vue/test-utils'
+import { CNavbar as Component } from '../../../index'
+
+const ComponentName = 'CNavbar'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ colorScheme: 'light',
+ component: 'div',
+ container: 'lg',
+ expand: 'xl',
+ placement: 'fixed-bottom',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('navbar')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('navbar')).toBe(true)
+ expect(customWrapper.classes('bg-warning')).toBe(true)
+ expect(customWrapper.classes('navbar-light')).toBe(true)
+ expect(customWrapper.classes('navbar-expand-xl')).toBe(true)
+ expect(customWrapper.classes('fixed-bottom')).toBe(true)
+ expect(customWrapper.find('.container-lg').classes('container-lg')).toBe(true)
+ expect(customWrapper.find('.container-lg').text()).toContain('Default slot')
+ })
+})
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/CNavbarBrand.spec.ts b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarBrand.spec.ts
new file mode 100644
index 00000000..f4b1c5d1
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarBrand.spec.ts
@@ -0,0 +1,65 @@
+import { mount } from '@vue/test-utils'
+import { CNavbarBrand as Component } from '../../../index'
+
+const ComponentName = 'CNavbarBrand'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapperTwo = mount(Component, {
+ propsData: {
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('navbar-brand')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('navbar-brand')).toBe(true)
+ expect(customWrapper.attributes('href')).toBe('/bazinga')
+ })
+})
+
+describe(`Customize (two) ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapperTwo.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapperTwo.text()).toContain('Default slot')
+ expect(customWrapperTwo.classes('navbar-brand')).toBe(true)
+ expect(customWrapperTwo.attributes('href')).toBe('/bazinga')
+ })
+})
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/CNavbarNav.spec.ts b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarNav.spec.ts
new file mode 100644
index 00000000..74db8a76
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarNav.spec.ts
@@ -0,0 +1,45 @@
+import { mount } from '@vue/test-utils'
+import { CNavbarNav as Component } from '../../../index'
+
+const ComponentName = 'CNavbarNav'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('navbar-nav')).toBe(true)
+ expect(defaultWrapper.attributes('role')).toBe('navigation')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('navbar-nav')).toBe(true)
+ expect(customWrapper.attributes('role')).toBe('navigation')
+ })
+})
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/CNavbarText.spec.ts b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarText.spec.ts
new file mode 100644
index 00000000..f8532a99
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarText.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CNavbarText as Component } from '../../../index'
+
+const ComponentName = 'CNavbarText'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('navbar-text')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/CNavbarToggler.spec.ts b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarToggler.spec.ts
new file mode 100644
index 00000000..2633bf2c
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/CNavbarToggler.spec.ts
@@ -0,0 +1,39 @@
+import { mount } from '@vue/test-utils'
+import { CNavbarToggler as Component } from '../../../index'
+
+const ComponentName = 'CNavbarToggler'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+const customWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('navbar-toggler')).toBe(true)
+ expect(defaultWrapper.find('span').classes('navbar-toggler-icon')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('navbar-toggler')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.ts.snap b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.ts.snap
new file mode 100644
index 00000000..ff0e3509
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbar.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNavbar component renders correctly 1`] = `
+""
+`;
+
+exports[`Loads and display CNavbar component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.ts.snap b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.ts.snap
new file mode 100644
index 00000000..0ddb600e
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarBrand.spec.ts.snap
@@ -0,0 +1,7 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize (two) CNavbarBrand component renders correctly 1`] = `"Default slot "`;
+
+exports[`Customize CNavbarBrand component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CNavbarBrand component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.ts.snap b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.ts.snap
new file mode 100644
index 00000000..d2e23afd
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarNav.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNavbarNav component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CNavbarNav component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.ts.snap b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.ts.snap
new file mode 100644
index 00000000..24487886
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarText.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CNavbarText component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.ts.snap b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.ts.snap
new file mode 100644
index 00000000..7054937b
--- /dev/null
+++ b/packages/coreui-vue/src/components/navbar/__tests__/__snapshots__/CNavbarToggler.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CNavbarToggler component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CNavbarToggler component renders correctly 1`] = `" "`;
diff --git a/src/components/navbar/index.ts b/packages/coreui-vue/src/components/navbar/index.ts
similarity index 100%
rename from src/components/navbar/index.ts
rename to packages/coreui-vue/src/components/navbar/index.ts
diff --git a/packages/coreui-vue/src/components/offcanvas/COffcanvas.ts b/packages/coreui-vue/src/components/offcanvas/COffcanvas.ts
new file mode 100644
index 00000000..aca98dbe
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/COffcanvas.ts
@@ -0,0 +1,204 @@
+import { defineComponent, h, ref, RendererElement, Transition, watch, withDirectives } from 'vue'
+
+import { CBackdrop } from '../backdrop'
+
+import { vVisible } from '../../directives/v-c-visible'
+import { executeAfterTransition } from '../../utils/transition'
+
+const COffcanvas = defineComponent({
+ name: 'COffcanvas',
+ inheritAttrs: false,
+ props: {
+ /**
+ * Apply a backdrop on body while offcanvas is open.
+ *
+ * @values boolean | 'static'
+ */
+ backdrop: {
+ type: [Boolean, String],
+ default: true,
+ validator: (value: boolean | string) => {
+ if (typeof value === 'string') {
+ return ['static'].includes(value)
+ }
+ if (typeof value === 'boolean') {
+ return true
+ }
+ return false
+ },
+ },
+ /**
+ * Closes the offcanvas when escape key is pressed.
+ */
+ keyboard: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * Components placement, there’s no default placement.
+ *
+ * @values 'start', 'end', 'top', 'bottom'
+ */
+ placement: {
+ type: String,
+ require: true,
+ validator: (value: string) => {
+ return ['start', 'end', 'top', 'bottom'].includes(value)
+ },
+ },
+ /**
+ * Responsive offcanvas property hide content outside the viewport from a specified breakpoint and down.
+ *
+ * @values boolean | 'sm' | 'md' | 'lg' | 'xl' | 'xxl'
+ * @since 4.7.0
+ */
+ responsive: {
+ type: [Boolean, String],
+ default: true,
+ validator: (value: boolean | string) => {
+ if (typeof value === 'string') {
+ return ['sm', 'md', 'lg', 'xl', 'xxl'].includes(value)
+ }
+ if (typeof value === 'boolean') {
+ return true
+ }
+ return false
+ },
+ },
+ /**
+ * Allow body scrolling while offcanvas is open
+ */
+ scroll: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
+ * Toggle the visibility of offcanvas component.
+ */
+ visible: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { attrs, emit, slots }) {
+ const offcanvasRef = ref()
+ const visible = ref(props.visible)
+
+ watch(
+ () => props.visible,
+ () => {
+ visible.value = props.visible
+ },
+ )
+
+ watch(visible, () => {
+ if (visible.value && !props.scroll) {
+ document.body.style.overflow = 'hidden'
+ document.body.style.paddingRight = '0px'
+
+ return
+ }
+
+ if (!props.scroll) {
+ document.body.style.removeProperty('overflow')
+ document.body.style.removeProperty('padding-right')
+ }
+ })
+
+ const handleEnter = (el: RendererElement, done: () => void) => {
+ emit('show')
+ executeAfterTransition(() => done(), el as HTMLElement)
+ setTimeout(() => {
+ el.classList.add('show')
+ }, 1)
+ }
+
+ const handleAfterEnter = () => {
+ offcanvasRef.value.focus()
+ }
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
+ const handleLeave = (el: RendererElement, done: () => void) => {
+ executeAfterTransition(() => done(), el as HTMLElement)
+ el.classList.add('hiding')
+ }
+
+ // eslint-disable-next-line unicorn/consistent-function-scoping
+ const handleAfterLeave = (el: RendererElement) => {
+ el.classList.remove('show', 'hiding')
+ }
+
+ const handleDismiss = () => {
+ visible.value = false
+ emit('hide')
+ }
+
+ const handleBackdropDismiss = () => {
+ if (props.backdrop !== 'static') {
+ handleDismiss()
+ }
+ }
+
+ const handleKeyDown = (event: KeyboardEvent) => {
+ if (event.key === 'Escape' && props.keyboard) {
+ handleDismiss()
+ }
+ }
+
+ return () => [
+ h(
+ Transition,
+ {
+ css: false,
+ onEnter: (el, done) => handleEnter(el, done),
+ onAfterEnter: () => handleAfterEnter(),
+ onLeave: (el, done) => handleLeave(el, done),
+ onAfterLeave: (el) => handleAfterLeave(el),
+ },
+ () =>
+ withDirectives(
+ h(
+ 'div',
+ {
+ ...attrs,
+ class: [
+ {
+ [`offcanvas${
+ typeof props.responsive === 'boolean' ? '' : '-' + props.responsive
+ }`]: props.responsive,
+ [`offcanvas-${props.placement}`]: props.placement,
+ },
+ attrs.class,
+ ],
+ onKeydown: (event: KeyboardEvent) => handleKeyDown(event),
+ ref: offcanvasRef,
+ role: 'dialog',
+ tabindex: -1,
+ },
+ slots.default && slots.default(),
+ ),
+ [[vVisible, props.visible]],
+ ),
+ ),
+ props.backdrop &&
+ h(CBackdrop, {
+ class: 'offcanvas-backdrop',
+ onClick: handleBackdropDismiss,
+ visible: visible.value,
+ }),
+ ]
+ },
+})
+
+export { COffcanvas }
diff --git a/src/components/offcanvas/COffcanvasBody.ts b/packages/coreui-vue/src/components/offcanvas/COffcanvasBody.ts
similarity index 100%
rename from src/components/offcanvas/COffcanvasBody.ts
rename to packages/coreui-vue/src/components/offcanvas/COffcanvasBody.ts
diff --git a/src/components/offcanvas/COffcanvasHeader.ts b/packages/coreui-vue/src/components/offcanvas/COffcanvasHeader.ts
similarity index 100%
rename from src/components/offcanvas/COffcanvasHeader.ts
rename to packages/coreui-vue/src/components/offcanvas/COffcanvasHeader.ts
diff --git a/src/components/offcanvas/COffcanvasTitle.ts b/packages/coreui-vue/src/components/offcanvas/COffcanvasTitle.ts
similarity index 90%
rename from src/components/offcanvas/COffcanvasTitle.ts
rename to packages/coreui-vue/src/components/offcanvas/COffcanvasTitle.ts
index af5c0aec..0ea9f496 100644
--- a/src/components/offcanvas/COffcanvasTitle.ts
+++ b/packages/coreui-vue/src/components/offcanvas/COffcanvasTitle.ts
@@ -5,12 +5,9 @@ const COffcanvasTitle = defineComponent({
props: {
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'h5'
*/
component: {
type: String,
- required: false,
default: 'h5',
},
},
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvas.spec.ts b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvas.spec.ts
new file mode 100644
index 00000000..c7bb8e12
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvas.spec.ts
@@ -0,0 +1,52 @@
+import { mount } from '@vue/test-utils'
+import { COffcanvas as Component } from '../../../index'
+
+const ComponentName = 'COffcanvas'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ visible: true,
+ placement: 'end',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ backdrop: true,
+ keyboard: true,
+ placement: 'bottom',
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('div').classes('offcanvas')).toBe(true)
+ expect(defaultWrapper.find('div').classes('offcanvas-end')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('div').classes('offcanvas')).toBe(true)
+ expect(customWrapper.find('div').classes('offcanvas-bottom')).toBe(true)
+ expect(customWrapper.find('.offcanvas-backdrop').classes('offcanvas-backdrop')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasBody.spec.ts b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasBody.spec.ts
new file mode 100644
index 00000000..ae5dca6c
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasBody.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { COffcanvasBody as Component } from '../../../index'
+
+const ComponentName = 'COffcanvasBody'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('offcanvas-body')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasHeader.spec.ts b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasHeader.spec.ts
new file mode 100644
index 00000000..e19de432
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasHeader.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { COffcanvasHeader as Component } from '../../../index'
+
+const ComponentName = 'COffcanvasHeader'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('offcanvas-header')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasTitle.spec.ts b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasTitle.spec.ts
new file mode 100644
index 00000000..c41d76eb
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/COffcanvasTitle.spec.ts
@@ -0,0 +1,43 @@
+import { mount } from '@vue/test-utils'
+import { COffcanvasTitle as Component } from '../../../index'
+
+const ComponentName = 'COffcanvasTitle'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: 'div',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('offcanvas-title')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('offcanvas-title')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.ts.snap b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.ts.snap
new file mode 100644
index 00000000..d74a3bcb
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvas.spec.ts.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize COffcanvas component renders correctly 1`] = `
+"
+ Default slot
+
+
+
+ "
+`;
+
+exports[`Loads and display COffcanvas component renders correctly 1`] = `
+"
+ Default slot
+
+
+
+ "
+`;
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.ts.snap b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.ts.snap
new file mode 100644
index 00000000..86cbd126
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasBody.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display COffcanvasBody component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.ts.snap b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.ts.snap
new file mode 100644
index 00000000..f3a255fc
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasHeader.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display COffcanvasHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.ts.snap b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.ts.snap
new file mode 100644
index 00000000..52e231f8
--- /dev/null
+++ b/packages/coreui-vue/src/components/offcanvas/__tests__/__snapshots__/COffcanvasTitle.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize COffcanvasTitle component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display COffcanvasTitle component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/offcanvas/index.ts b/packages/coreui-vue/src/components/offcanvas/index.ts
similarity index 100%
rename from src/components/offcanvas/index.ts
rename to packages/coreui-vue/src/components/offcanvas/index.ts
diff --git a/src/components/pagination/CPagination.ts b/packages/coreui-vue/src/components/pagination/CPagination.ts
similarity index 51%
rename from src/components/pagination/CPagination.ts
rename to packages/coreui-vue/src/components/pagination/CPagination.ts
index 0987a89b..9f0bc7c4 100644
--- a/src/components/pagination/CPagination.ts
+++ b/packages/coreui-vue/src/components/pagination/CPagination.ts
@@ -3,6 +3,17 @@ import { defineComponent, h } from 'vue'
const CPagination = defineComponent({
name: 'CPagination',
props: {
+ /**
+ * Set the alignment of pagination components.
+ *
+ * @values 'start', 'center', 'end'
+ */
+ align: {
+ type: String,
+ validator: (value: string) => {
+ return ['start', 'center', 'end'].includes(value)
+ },
+ },
/**
* Size the component small or large.
*
@@ -10,8 +21,6 @@ const CPagination = defineComponent({
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['sm', 'lg'].includes(value)
},
@@ -24,7 +33,15 @@ const CPagination = defineComponent({
{},
h(
'ul',
- { class: ['pagination', { [`pagination-${props.size}`]: props.size }] },
+ {
+ class: [
+ 'pagination',
+ {
+ [`justify-content-${props.align}`]: props.align,
+ [`pagination-${props.size}`]: props.size,
+ },
+ ],
+ },
slots.default && slots.default(),
),
)
diff --git a/src/components/pagination/CPaginationItem.ts b/packages/coreui-vue/src/components/pagination/CPaginationItem.ts
similarity index 76%
rename from src/components/pagination/CPaginationItem.ts
rename to packages/coreui-vue/src/components/pagination/CPaginationItem.ts
index d2242c96..92475524 100644
--- a/src/components/pagination/CPaginationItem.ts
+++ b/packages/coreui-vue/src/components/pagination/CPaginationItem.ts
@@ -8,37 +8,23 @@ const CPaginationItem = defineComponent({
/**
* Toggle the active state for the component.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Component used for the root node. Either a string to use a HTML element or a component.
*/
- component: {
- type: String,
- default: undefined,
- required: false,
- },
+ component: String,
/**
* Toggle the disabled state for the component.
*/
- disabled: {
- type: Boolean,
- required: false,
- },
+ disabled: Boolean,
/**
* The href attribute specifies the URL of the page the link goes to.
*/
- href: {
- type: String,
- default: undefined,
- required: false,
- },
+ href: String,
},
setup(props, { slots }) {
return () => {
- const component = props.component ? props.component : props.active ? 'span' : 'a'
+ const component = props.component ?? (props.active ? 'span' : 'a')
return h(
'li',
{
diff --git a/packages/coreui-vue/src/components/pagination/__tests__/CPagination.spec.ts b/packages/coreui-vue/src/components/pagination/__tests__/CPagination.spec.ts
new file mode 100644
index 00000000..1bd9ee7b
--- /dev/null
+++ b/packages/coreui-vue/src/components/pagination/__tests__/CPagination.spec.ts
@@ -0,0 +1,44 @@
+import { mount } from '@vue/test-utils'
+import { CPagination as Component } from '../../../index'
+
+const ComponentName = 'CPagination'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ size: 'lg',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.find('ul').text()).toContain('Default slot')
+ expect(defaultWrapper.find('ul').classes('pagination')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.find('ul').text()).toContain('Default slot')
+ expect(customWrapper.find('ul').classes('pagination')).toBe(true)
+ expect(customWrapper.find('ul').classes('pagination-lg')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/pagination/__tests__/CPaginationItem.spec.ts b/packages/coreui-vue/src/components/pagination/__tests__/CPaginationItem.spec.ts
new file mode 100644
index 00000000..e4d6015e
--- /dev/null
+++ b/packages/coreui-vue/src/components/pagination/__tests__/CPaginationItem.spec.ts
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils'
+import { CPaginationItem as Component } from '../../../index'
+
+const ComponentName = 'CPaginationItem'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ disabled: true,
+ href: '/bazinga',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.find('.page-link').text()).toContain('Default slot')
+ expect(defaultWrapper.classes('page-item')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.find('.page-link').text()).toContain('Default slot')
+ expect(customWrapper.classes('page-item')).toBe(true)
+ expect(customWrapper.classes('disabled')).toBe(true)
+ expect(customWrapper.find('.page-link').attributes('href')).toContain('bazinga') // TODO: It must be working!
+ })
+})
diff --git a/packages/coreui-vue/src/components/pagination/__tests__/__snapshots__/CPagination.spec.ts.snap b/packages/coreui-vue/src/components/pagination/__tests__/__snapshots__/CPagination.spec.ts.snap
new file mode 100644
index 00000000..df7177ab
--- /dev/null
+++ b/packages/coreui-vue/src/components/pagination/__tests__/__snapshots__/CPagination.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CPagination component renders correctly 1`] = `
+"
+
+ "
+`;
+
+exports[`Loads and display CPagination component renders correctly 1`] = `
+"
+
+ "
+`;
diff --git a/packages/coreui-vue/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.ts.snap b/packages/coreui-vue/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.ts.snap
new file mode 100644
index 00000000..440c37db
--- /dev/null
+++ b/packages/coreui-vue/src/components/pagination/__tests__/__snapshots__/CPaginationItem.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CPaginationItem component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CPaginationItem component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/pagination/index.ts b/packages/coreui-vue/src/components/pagination/index.ts
similarity index 100%
rename from src/components/pagination/index.ts
rename to packages/coreui-vue/src/components/pagination/index.ts
diff --git a/packages/coreui-vue/src/components/placeholder/CPlaceholder.ts b/packages/coreui-vue/src/components/placeholder/CPlaceholder.ts
new file mode 100644
index 00000000..99b69a20
--- /dev/null
+++ b/packages/coreui-vue/src/components/placeholder/CPlaceholder.ts
@@ -0,0 +1,110 @@
+import { defineComponent, h } from 'vue'
+
+import { Color } from '../../props'
+
+const BREAKPOINTS = [
+ 'xxl' as const,
+ 'xl' as const,
+ 'lg' as const,
+ 'md' as const,
+ 'sm' as const,
+ 'xs' as const,
+]
+
+export const CPlaceholder = defineComponent({
+ name: 'CPlaceholder',
+ props: {
+ /**
+ * Set animation type to better convey the perception of something being actively loaded.
+ *
+ * @values 'glow', 'wave'
+ */
+ animation: {
+ type: String,
+ validator: (value: string) => {
+ return ['glow', 'wave'].includes(value)
+ },
+ },
+ /**
+ * Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
+ */
+ color: Color,
+ /**
+ * Component used for the root node. Either a string to use a HTML element or a component.
+ */
+ component: {
+ type: String,
+ default: 'span',
+ },
+ /**
+ * Size the component extra small, small, or large.
+ *
+ * @values 'xs', 'sm', 'lg'
+ */
+ size: {
+ type: String,
+ validator: (value: string) => {
+ return ['xs', 'sm', 'lg'].includes(value)
+ },
+ },
+ /**
+ * The number of columns on extra small devices (<576px).
+ */
+ xs: Number,
+ /**
+ * The number of columns on small devices (<768px).
+ */
+ sm: Number,
+ /**
+ * The number of columns on medium devices (<992px).
+ */
+ md: Number,
+ /**
+ * The number of columns on large devices (<1200px).
+ */
+ lg: Number,
+ /**
+ * The number of columns on X-Large devices (<1400px).
+ */
+ xl: Number,
+ /**
+ * The number of columns on XX-Large devices (≥1400px).
+ */
+ xxl: Number,
+ },
+ setup(props, { slots }) {
+ const repsonsiveClassNames: string[] = []
+
+ BREAKPOINTS.forEach((bp) => {
+ const breakpoint = props[bp]
+
+ const infix = bp === 'xs' ? '' : `-${bp}`
+
+ if (typeof breakpoint === 'number') {
+ repsonsiveClassNames.push(`col${infix}-${breakpoint}`)
+ }
+
+ if (typeof breakpoint === 'boolean') {
+ repsonsiveClassNames.push(`col${infix}`)
+ }
+ })
+
+ return () =>
+ h(
+ props.component,
+ {
+ class: [
+ props.animation ? `placeholder-${props.animation}` : 'placeholder',
+ {
+ [`bg-${props.color}`]: props.color,
+ [`placeholder-${props.size}`]: props.size,
+ },
+ repsonsiveClassNames,
+ ],
+ },
+ slots.default && slots.default(),
+ )
+ },
+})
diff --git a/packages/coreui-vue/src/components/placeholder/__tests__/CPlaceholder.spec.ts b/packages/coreui-vue/src/components/placeholder/__tests__/CPlaceholder.spec.ts
new file mode 100644
index 00000000..2f3cff8f
--- /dev/null
+++ b/packages/coreui-vue/src/components/placeholder/__tests__/CPlaceholder.spec.ts
@@ -0,0 +1,44 @@
+import { shallowMount } from '@vue/test-utils'
+import { CPlaceholder as Component } from '../../'
+
+const ComponentName = 'CPlaceholder'
+const wrapper = shallowMount(Component)
+const customWrapper = shallowMount(Component, {
+ props: {
+ animation: 'glow',
+ color: 'secondary',
+ size: 'lg',
+ sm: 7,
+ },
+ attrs: {
+ class: 'bazinga',
+ },
+ slots: {
+ default: 'Hello World!',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(wrapper.element).toMatchSnapshot()
+ })
+ it('renders correctly with slot', () => {
+ expect(customWrapper.element).toMatchSnapshot()
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('has a prope class names', () => {
+ expect(customWrapper.find('span').classes('bazinga')).toBe(true)
+ expect(customWrapper.find('span').classes('bg-secondary')).toBe(true)
+ expect(customWrapper.find('span').classes('col-sm-7')).toBe(true)
+ expect(customWrapper.find('span').classes('placeholder-glow')).toBe(true)
+ expect(customWrapper.find('span').classes('placeholder-lg')).toBe(true)
+ })
+ it('default slot contains text', () => {
+ expect(customWrapper.text()).toBe('Hello World!')
+ })
+})
diff --git a/packages/coreui-vue/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.ts.snap b/packages/coreui-vue/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.ts.snap
new file mode 100644
index 00000000..3f43d58c
--- /dev/null
+++ b/packages/coreui-vue/src/components/placeholder/__tests__/__snapshots__/CPlaceholder.spec.ts.snap
@@ -0,0 +1,15 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CPlaceholder component renders correctly 1`] = `
+
+`;
+
+exports[`Loads and display CPlaceholder component renders correctly with slot 1`] = `
+
+ Hello World!
+
+`;
diff --git a/packages/coreui-vue/src/components/placeholder/index.ts b/packages/coreui-vue/src/components/placeholder/index.ts
new file mode 100644
index 00000000..39369fc1
--- /dev/null
+++ b/packages/coreui-vue/src/components/placeholder/index.ts
@@ -0,0 +1,10 @@
+import { App } from 'vue'
+import { CPlaceholder } from './CPlaceholder'
+
+const CPlaceholderPlugin = {
+ install: (app: App): void => {
+ app.component(CPlaceholder.name, CPlaceholder)
+ },
+}
+
+export { CPlaceholderPlugin, CPlaceholder }
diff --git a/packages/coreui-vue/src/components/popover/CPopover.ts b/packages/coreui-vue/src/components/popover/CPopover.ts
new file mode 100644
index 00000000..0e5d172b
--- /dev/null
+++ b/packages/coreui-vue/src/components/popover/CPopover.ts
@@ -0,0 +1,236 @@
+import { defineComponent, h, PropType, ref, RendererElement, Teleport, Transition } from 'vue'
+import type { Placement } from '@popperjs/core'
+
+import { usePopper } from '../../composables'
+import type { Placements, Triggers } from '../../types'
+import { executeAfterTransition } from '../../utils/transition'
+import { getRTLPlacement } from '../../utils'
+
+const CPopover = defineComponent({
+ name: 'CPopover',
+ props: {
+ /**
+ * Apply a CSS fade transition to the popover.
+ *
+ * @since 4.9.0
+ */
+ animation: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * Content for your component. If you want to pass non-string value please use dedicated slot `... `
+ */
+ content: String,
+ /**
+ * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
+ *
+ * @since 4.9.0
+ */
+ delay: {
+ type: [Number, Object] as PropType,
+ default: 0,
+ },
+ /**
+ * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
+ *
+ * @since 4.9.0
+ */
+ fallbackPlacements: {
+ type: [String, Array] as PropType,
+ default: () => ['top', 'right', 'bottom', 'left'],
+ validator: (value: Placements | Placements[]) => {
+ if (typeof value === 'string') {
+ return ['top', 'right', 'bottom', 'left'].includes(value)
+ }
+ if (Array.isArray(value)) {
+ return value.every((e) => ['top', 'right', 'bottom', 'left'].includes(e))
+ }
+ return false
+ },
+ },
+ /**
+ * Offset of the popover relative to its target.
+ */
+ offset: {
+ type: Array,
+ default: () => [0, 8],
+ },
+ /**
+ * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property.
+ */
+ placement: {
+ type: String as PropType,
+ default: 'top',
+ validator: (value: string) => {
+ return ['top', 'right', 'bottom', 'left'].includes(value)
+ },
+ },
+ /**
+ * Title for your component. If you want to pass non-string value please use dedicated slot `... `
+ */
+ title: String,
+ /**
+ * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them.
+ *
+ * @values 'click', 'focus', 'hover'
+ */
+ trigger: {
+ type: [String, Array] as PropType,
+ default: 'click',
+ validator: (value: Triggers | Triggers[]) => {
+ if (typeof value === 'string') {
+ return ['click', 'focus', 'hover'].includes(value)
+ }
+ if (Array.isArray(value)) {
+ return value.every((e) => ['click', 'focus', 'hover'].includes(e))
+ }
+ return false
+ },
+ },
+ /**
+ * Toggle the visibility of popover component.
+ */
+ visible: Boolean,
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { attrs, slots, emit }) {
+ const togglerRef = ref()
+ const popoverRef = ref()
+ const visible = ref(props.visible)
+ const { initPopper, destroyPopper } = usePopper()
+
+ const delay =
+ typeof props.delay === 'number' ? { show: props.delay, hide: props.delay } : props.delay
+
+ const popperConfig = {
+ modifiers: [
+ {
+ name: 'arrow',
+ options: {
+ element: '.popover-arrow',
+ },
+ },
+ {
+ name: 'flip',
+ options: {
+ fallbackPlacements: props.fallbackPlacements,
+ },
+ },
+ {
+ name: 'offset',
+ options: {
+ offset: props.offset,
+ },
+ },
+ ],
+ placement: getRTLPlacement(props.placement, togglerRef.value),
+ }
+
+ const handleEnter = (el: RendererElement, done: () => void) => {
+ emit('show')
+ initPopper(togglerRef.value, popoverRef.value, popperConfig)
+ el.classList.add('show')
+ executeAfterTransition(() => done(), el as HTMLElement)
+ }
+
+ const handleLeave = (el: RendererElement, done: () => void) => {
+ emit('hide')
+ el.classList.remove('show')
+ executeAfterTransition(() => {
+ done()
+ destroyPopper()
+ }, el as HTMLElement)
+ }
+
+ const toggleVisible = (event: Event, _visible: boolean) => {
+ togglerRef.value = event.target
+ if (_visible) {
+ setTimeout(() => {
+ visible.value = true
+ }, delay.show)
+ return
+ }
+
+ setTimeout(() => {
+ visible.value = false
+ }, delay.hide)
+ }
+
+ return () => [
+ h(
+ Teleport,
+ {
+ to: 'body',
+ },
+ h(
+ Transition,
+ {
+ onEnter: (el, done) => handleEnter(el, done),
+ onLeave: (el, done) => handleLeave(el, done),
+ },
+ () =>
+ visible.value &&
+ h(
+ 'div',
+ {
+ class: [
+ 'popover',
+ 'bs-popover-auto',
+ {
+ fade: props.animation,
+ },
+ ],
+ ref: popoverRef,
+ role: 'tooltip',
+ ...attrs,
+ },
+ [
+ h('div', { class: 'popover-arrow' }),
+ (props.title || slots.title) &&
+ h(
+ 'div',
+ { class: 'popover-header' },
+ {
+ default: () => (slots.title && slots.title()) || props.title,
+ },
+ ),
+ (props.content || slots.content) &&
+ h(
+ 'div',
+ { class: 'popover-body' },
+ {
+ default: () => (slots.content && slots.content()) || props.content,
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ slots.toggler &&
+ slots.toggler({
+ on: {
+ click: (event: Event) =>
+ props.trigger.includes('click') && toggleVisible(event, !visible.value),
+ blur: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, false),
+ focus: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, true),
+ mouseenter: (event: Event) =>
+ props.trigger.includes('hover') && toggleVisible(event, true),
+ mouseleave: (event: Event) =>
+ props.trigger.includes('hover') && toggleVisible(event, false),
+ },
+ }),
+ ]
+ },
+})
+
+export { CPopover }
diff --git a/packages/coreui-vue/src/components/popover/index.ts b/packages/coreui-vue/src/components/popover/index.ts
new file mode 100644
index 00000000..58eaee32
--- /dev/null
+++ b/packages/coreui-vue/src/components/popover/index.ts
@@ -0,0 +1,10 @@
+import { App } from 'vue'
+import { CPopover } from './CPopover'
+
+const CPopoverPlugin = {
+ install: (app: App): void => {
+ app.component(CPopover.name, CPopover)
+ },
+}
+
+export { CPopoverPlugin, CPopover }
diff --git a/src/components/progress/CProgress.ts b/packages/coreui-vue/src/components/progress/CProgress.ts
similarity index 90%
rename from src/components/progress/CProgress.ts
rename to packages/coreui-vue/src/components/progress/CProgress.ts
index 3f2f1ea7..66a9c84f 100644
--- a/src/components/progress/CProgress.ts
+++ b/packages/coreui-vue/src/components/progress/CProgress.ts
@@ -7,14 +7,8 @@ const CProgress = defineComponent({
props: {
/**
* Sets the height of the component. If you set that value the inner `` will automatically resize accordingly.
- *
- * @default 'undefined'
*/
- height: {
- type: Number,
- default: undefined,
- required: false,
- },
+ height: Number,
/**
* Makes progress bar thinner.
*/
diff --git a/src/components/progress/CProgressBar.ts b/packages/coreui-vue/src/components/progress/CProgressBar.ts
similarity index 87%
rename from src/components/progress/CProgressBar.ts
rename to packages/coreui-vue/src/components/progress/CProgressBar.ts
index 3b59e93d..2463c25c 100644
--- a/src/components/progress/CProgressBar.ts
+++ b/packages/coreui-vue/src/components/progress/CProgressBar.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CProgressBar = defineComponent({
name: 'CProgressBar',
@@ -8,10 +8,7 @@ const CProgressBar = defineComponent({
/**
* Use to animate the stripes right to left via CSS3 animations.
*/
- animated: {
- type: Boolean,
- required: false,
- },
+ animated: Boolean,
/**
* Sets the color context of the component to one of CoreUI’s themed colors.
*
@@ -20,12 +17,9 @@ const CProgressBar = defineComponent({
color: Color,
/**
* The percent to progress the ProgressBar.
- *
- * @default 0
*/
value: {
type: Number,
- required: false,
default: 0,
},
/**
@@ -35,8 +29,6 @@ const CProgressBar = defineComponent({
*/
variant: {
type: String,
- default: undefined,
- require: false,
validator: (value: string) => {
return value === 'striped'
},
diff --git a/packages/coreui-vue/src/components/progress/__tests__/CProgress.spec.ts b/packages/coreui-vue/src/components/progress/__tests__/CProgress.spec.ts
new file mode 100644
index 00000000..c9425d64
--- /dev/null
+++ b/packages/coreui-vue/src/components/progress/__tests__/CProgress.spec.ts
@@ -0,0 +1,47 @@
+import { mount } from '@vue/test-utils'
+import { CProgress as Component } from '../../../index'
+
+const ComponentName = 'CProgress'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ height: 100,
+ thin: true,
+ white: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('progress')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('progress')).toBe(true)
+ expect(customWrapper.classes('progress-thin')).toBe(true)
+ expect(customWrapper.classes('progress-white')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/progress/__tests__/CProgressBar.spec.ts b/packages/coreui-vue/src/components/progress/__tests__/CProgressBar.spec.ts
new file mode 100644
index 00000000..e5545ebf
--- /dev/null
+++ b/packages/coreui-vue/src/components/progress/__tests__/CProgressBar.spec.ts
@@ -0,0 +1,54 @@
+import { mount } from '@vue/test-utils'
+import { CProgressBar as Component } from '../../../index'
+
+const ComponentName = 'CProgressBar'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ animated: true,
+ color: 'warning',
+ value: 75,
+ variant: 'striped',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('progress-bar')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('progress-bar')).toBe(true)
+ expect(customWrapper.classes('progress-bar-striped')).toBe(true)
+ expect(customWrapper.classes('progress-bar-animated')).toBe(true)
+ expect(customWrapper.classes('bg-warning')).toBe(true)
+ expect(customWrapper.attributes('role')).toBe('progressbar')
+ expect(customWrapper.attributes('style')).toBe('width: 75%;')
+ expect(customWrapper.attributes('aria-valuenow')).toBe('75')
+ expect(customWrapper.attributes('aria-valuemin')).toBe('0')
+ expect(customWrapper.attributes('aria-valuemax')).toBe('100')
+ })
+})
diff --git a/packages/coreui-vue/src/components/progress/__tests__/__snapshots__/CProgress.spec.ts.snap b/packages/coreui-vue/src/components/progress/__tests__/__snapshots__/CProgress.spec.ts.snap
new file mode 100644
index 00000000..bb820197
--- /dev/null
+++ b/packages/coreui-vue/src/components/progress/__tests__/__snapshots__/CProgress.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CProgress component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CProgress component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.ts.snap b/packages/coreui-vue/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.ts.snap
new file mode 100644
index 00000000..c4daea91
--- /dev/null
+++ b/packages/coreui-vue/src/components/progress/__tests__/__snapshots__/CProgressBar.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CProgressBar component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CProgressBar component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/progress/index.ts b/packages/coreui-vue/src/components/progress/index.ts
similarity index 100%
rename from src/components/progress/index.ts
rename to packages/coreui-vue/src/components/progress/index.ts
diff --git a/packages/coreui-vue/src/components/sidebar/CSidebar.ts b/packages/coreui-vue/src/components/sidebar/CSidebar.ts
new file mode 100644
index 00000000..9dc69b52
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/CSidebar.ts
@@ -0,0 +1,173 @@
+import { defineComponent, h, onBeforeUnmount, onMounted, ref, watch } from 'vue'
+import { CBackdrop } from '../backdrop'
+
+import { isInViewport } from '../../utils'
+
+const isOnMobile = (element: HTMLDivElement) => {
+ if (!element) {
+ return
+ }
+
+ return Boolean(getComputedStyle(element).getPropertyValue('--cui-is-mobile'))
+}
+
+const CSidebar = defineComponent({
+ name: 'CSidebar',
+ props: {
+ /**
+ * Make sidebar narrow.
+ */
+ narrow: Boolean,
+ /**
+ * Set sidebar to overlaid variant.
+ */
+ overlaid: Boolean,
+ /**
+ * Place sidebar in non-static positions.
+ */
+ position: {
+ type: String,
+ validator: (value: string) => {
+ return ['fixed'].includes(value)
+ },
+ },
+ /**
+ * Size the component small, large, or extra large.
+ */
+ size: {
+ type: String,
+ validator: (value: string) => {
+ return ['sm', 'lg', 'xl'].includes(value)
+ },
+ },
+ /**
+ * Expand narrowed sidebar on hover.
+ */
+ unfoldable: Boolean,
+ /**
+ * Toggle the visibility of sidebar component.
+ */
+ visible: Boolean,
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ /**
+ * Event emitted after visibility of component changed.
+ */
+ 'visible-change',
+ ],
+ setup(props, { attrs, slots, emit }) {
+ const mobile = ref()
+ const inViewport = ref()
+ const sidebarRef = ref()
+ const visible = ref(props.visible)
+
+ watch(inViewport, () => {
+ emit('visible-change', inViewport.value)
+ inViewport.value ? emit('show') : emit('hide')
+ })
+
+ watch(
+ () => props.visible,
+ () => (visible.value = props.visible),
+ )
+
+ watch(mobile, () => {
+ if (mobile.value && visible.value) visible.value = false
+ })
+
+ onMounted(() => {
+ mobile.value = isOnMobile(sidebarRef.value)
+ inViewport.value = isInViewport(sidebarRef.value)
+
+ window.addEventListener('resize', handleResize)
+ window.addEventListener('mouseup', handleClickOutside)
+ window.addEventListener('keyup', handleKeyup)
+
+ sidebarRef.value.addEventListener('mouseup', handleOnClick)
+ sidebarRef.value.addEventListener('transitionend', () => {
+ inViewport.value = isInViewport(sidebarRef.value)
+ })
+ })
+
+ onBeforeUnmount(() => {
+ window.removeEventListener('resize', handleResize)
+ window.removeEventListener('mouseup', handleClickOutside)
+ window.removeEventListener('keyup', handleKeyup)
+
+ sidebarRef.value.removeEventListener('mouseup', handleOnClick)
+ // eslint-disable-next-line unicorn/no-invalid-remove-event-listener
+ sidebarRef.value.removeEventListener('transitionend', () => {
+ inViewport.value = isInViewport(sidebarRef.value)
+ })
+ })
+
+ const handleHide = () => {
+ visible.value = false
+ emit('visible-change', false)
+ }
+
+ const handleResize = () => {
+ mobile.value = isOnMobile(sidebarRef.value)
+ inViewport.value = isInViewport(sidebarRef.value)
+ }
+
+ const handleKeyup = (event: Event) => {
+ if (mobile.value && !sidebarRef.value.contains(event.target as HTMLElement)) {
+ handleHide()
+ }
+ }
+ const handleClickOutside = (event: Event) => {
+ if (mobile.value && !sidebarRef.value.contains(event.target as HTMLElement)) {
+ handleHide()
+ }
+ }
+
+ const handleOnClick = (event: Event) => {
+ const target = event.target as HTMLAnchorElement
+ target &&
+ target.classList.contains('nav-link') &&
+ !target.classList.contains('nav-group-toggle') &&
+ mobile.value &&
+ handleHide()
+ }
+
+ return () => [
+ h(
+ 'div',
+ {
+ class: [
+ 'sidebar',
+ {
+ 'sidebar-narrow': props.narrow,
+ 'sidebar-overlaid': props.overlaid,
+ [`sidebar-${props.position}`]: props.position,
+ [`sidebar-${props.size}`]: props.size,
+ 'sidebar-narrow-unfoldable': props.unfoldable,
+ show: visible.value === true && mobile.value,
+ hide: visible.value === false && !mobile.value,
+ },
+ attrs.class,
+ ],
+ ref: sidebarRef,
+ },
+ slots.default && slots.default(),
+ ),
+ mobile.value &&
+ h(CBackdrop, {
+ class: 'sidebar-backdrop d-none',
+ visible: props.visible,
+ onClick: () => handleHide(),
+ }),
+ ]
+ },
+})
+
+export { CSidebar }
diff --git a/src/components/sidebar/CSidebarBrand.ts b/packages/coreui-vue/src/components/sidebar/CSidebarBrand.ts
similarity index 100%
rename from src/components/sidebar/CSidebarBrand.ts
rename to packages/coreui-vue/src/components/sidebar/CSidebarBrand.ts
diff --git a/src/components/sidebar/CSidebarFooter.ts b/packages/coreui-vue/src/components/sidebar/CSidebarFooter.ts
similarity index 100%
rename from src/components/sidebar/CSidebarFooter.ts
rename to packages/coreui-vue/src/components/sidebar/CSidebarFooter.ts
diff --git a/src/components/sidebar/CSidebarHeader.ts b/packages/coreui-vue/src/components/sidebar/CSidebarHeader.ts
similarity index 100%
rename from src/components/sidebar/CSidebarHeader.ts
rename to packages/coreui-vue/src/components/sidebar/CSidebarHeader.ts
diff --git a/src/components/sidebar/CSidebarNav.ts b/packages/coreui-vue/src/components/sidebar/CSidebarNav.ts
similarity index 100%
rename from src/components/sidebar/CSidebarNav.ts
rename to packages/coreui-vue/src/components/sidebar/CSidebarNav.ts
diff --git a/src/components/sidebar/CSidebarToggler.ts b/packages/coreui-vue/src/components/sidebar/CSidebarToggler.ts
similarity index 100%
rename from src/components/sidebar/CSidebarToggler.ts
rename to packages/coreui-vue/src/components/sidebar/CSidebarToggler.ts
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/CSidebar.spec.ts b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebar.spec.ts
new file mode 100644
index 00000000..9343351d
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebar.spec.ts
@@ -0,0 +1,54 @@
+import { mount } from '@vue/test-utils'
+import { CSidebar as Component } from '../../../index'
+
+const ComponentName = 'CSidebar'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ narrow: true,
+ overlaid: true,
+ position: 'fixed',
+ size: 'xl',
+ unfoldable: true,
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('.sidebar').classes('sidebar')).toBe(true)
+ expect(defaultWrapper.find('.sidebar').classes('hide')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('.sidebar').classes('sidebar')).toBe(true)
+ expect(customWrapper.find('.sidebar').classes('sidebar-narrow')).toBe(true)
+ expect(customWrapper.find('.sidebar').classes('sidebar-overlaid')).toBe(true)
+ expect(customWrapper.find('.sidebar').classes('sidebar-fixed')).toBe(true)
+ expect(customWrapper.find('.sidebar').classes('sidebar-xl')).toBe(true)
+ expect(customWrapper.find('.sidebar').classes('sidebar-narrow-unfoldable')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarBrand.spec.ts b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarBrand.spec.ts
new file mode 100644
index 00000000..1b849317
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarBrand.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CSidebarBrand as Component } from '../../../index'
+
+const ComponentName = 'CSidebarBrand'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('sidebar-brand')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarFooter.spec.ts b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarFooter.spec.ts
new file mode 100644
index 00000000..27830c41
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarFooter.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CSidebarFooter as Component } from '../../../index'
+
+const ComponentName = 'CSidebarFooter'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('sidebar-footer')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarHeader.spec.ts b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarHeader.spec.ts
new file mode 100644
index 00000000..ced864e1
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarHeader.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CSidebarHeader as Component } from '../../../index'
+
+const ComponentName = 'CSidebarHeader'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('sidebar-header')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarNav.spec.ts b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarNav.spec.ts
new file mode 100644
index 00000000..d1bfc88d
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarNav.spec.ts
@@ -0,0 +1,21 @@
+import { mount } from '@vue/test-utils'
+import { CSidebarNav as Component } from '../../../index'
+
+const ComponentName = 'CSidebarNav'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('sidebar-nav')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarToggler.spec.ts b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarToggler.spec.ts
new file mode 100644
index 00000000..630609e6
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/CSidebarToggler.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CSidebarToggler as Component } from '../../../index'
+
+const ComponentName = 'CSidebarToggler'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('sidebar-toggler')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.ts.snap b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.ts.snap
new file mode 100644
index 00000000..cffd8e68
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebar.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CSidebar component renders correctly 1`] = `""`;
+
+exports[`Loads and display CSidebar component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.ts.snap b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.ts.snap
new file mode 100644
index 00000000..5b05d064
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarBrand.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CSidebarBrand component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.ts.snap b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.ts.snap
new file mode 100644
index 00000000..c275d81c
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarFooter.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CSidebarFooter component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.ts.snap b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.ts.snap
new file mode 100644
index 00000000..edf15cc3
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarHeader.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CSidebarHeader component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.ts.snap b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.ts.snap
new file mode 100644
index 00000000..b476da94
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarNav.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CSidebarNav component renders correctly 1`] = `""`;
diff --git a/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.ts.snap b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.ts.snap
new file mode 100644
index 00000000..402da170
--- /dev/null
+++ b/packages/coreui-vue/src/components/sidebar/__tests__/__snapshots__/CSidebarToggler.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CSidebarToggler component renders correctly 1`] = `""`;
diff --git a/src/components/sidebar/index.ts b/packages/coreui-vue/src/components/sidebar/index.ts
similarity index 100%
rename from src/components/sidebar/index.ts
rename to packages/coreui-vue/src/components/sidebar/index.ts
diff --git a/src/components/spinner/CSpinner.ts b/packages/coreui-vue/src/components/spinner/CSpinner.ts
similarity index 82%
rename from src/components/spinner/CSpinner.ts
rename to packages/coreui-vue/src/components/spinner/CSpinner.ts
index 272b6db8..f773d422 100644
--- a/src/components/spinner/CSpinner.ts
+++ b/packages/coreui-vue/src/components/spinner/CSpinner.ts
@@ -10,8 +10,6 @@ const CSpinner = defineComponent({
*/
color: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return [
'primary',
@@ -27,13 +25,10 @@ const CSpinner = defineComponent({
},
/**
* Component used for the root node. Either a string to use a HTML element or a component.
- *
- * @default 'div'
*/
component: {
type: String,
default: 'div',
- required: false,
},
/**
* Size the component small.
@@ -42,8 +37,6 @@ const CSpinner = defineComponent({
*/
size: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return value === 'sm'
},
@@ -51,26 +44,21 @@ const CSpinner = defineComponent({
/**
* Set the button variant to an outlined button or a ghost button.
*
- * @default 'border'
* @values 'border', 'grow'
*/
variant: {
type: String,
default: 'border',
- required: false,
validator: (value: string) => {
return ['border', 'grow'].includes(value)
},
},
/**
* Set visually hidden label for accessibility purposes.
- *
- * @default 'Loading...'
*/
visuallyHiddenLabel: {
type: String,
default: 'Loading...',
- required: false,
},
},
setup(props) {
@@ -80,8 +68,10 @@ const CSpinner = defineComponent({
{
class: [
`spinner-${props.variant}`,
- `text-${props.color}`,
- props.size && `spinner-${props.variant}-${props.size}`,
+ {
+ [`spinner-${props.variant}-${props.size}`]: props.size,
+ [`text-${props.color}`]: props.color,
+ },
],
role: 'status',
},
diff --git a/packages/coreui-vue/src/components/spinner/__tests__/CSpinner.spec.ts b/packages/coreui-vue/src/components/spinner/__tests__/CSpinner.spec.ts
new file mode 100644
index 00000000..0f1ec0a9
--- /dev/null
+++ b/packages/coreui-vue/src/components/spinner/__tests__/CSpinner.spec.ts
@@ -0,0 +1,52 @@
+import { mount } from '@vue/test-utils'
+import { CSpinner as Component } from '../../../index'
+
+const ComponentName = 'CSpinner'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ component: 'h4',
+ size: 'sm',
+ variant: 'grow',
+ visuallyHiddenLabel: 'visuallyHiddenLabel',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('spinner-border')).toBe(true)
+ expect(defaultWrapper.classes('text-undefined')).toBe(true)
+ expect(defaultWrapper.find('span').classes('visually-hidden')).toBe(true)
+ expect(defaultWrapper.find('span').text()).toContain('Loading...')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.classes('spinner-grow')).toBe(true)
+ expect(customWrapper.classes('text-warning')).toBe(true)
+ expect(customWrapper.classes('spinner-grow-sm')).toBe(true)
+ expect(customWrapper.find('span').classes('visually-hidden')).toBe(true)
+ expect(customWrapper.find('span').text()).toContain('visuallyHiddenLabel')
+ })
+})
diff --git a/packages/coreui-vue/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.ts.snap b/packages/coreui-vue/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.ts.snap
new file mode 100644
index 00000000..f1d49397
--- /dev/null
+++ b/packages/coreui-vue/src/components/spinner/__tests__/__snapshots__/CSpinner.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CSpinner component renders correctly 1`] = `"visuallyHiddenLabel "`;
+
+exports[`Loads and display CSpinner component renders correctly 1`] = `"Loading...
"`;
diff --git a/src/components/spinner/index.ts b/packages/coreui-vue/src/components/spinner/index.ts
similarity index 100%
rename from src/components/spinner/index.ts
rename to packages/coreui-vue/src/components/spinner/index.ts
diff --git a/packages/coreui-vue/src/components/table/CTable.ts b/packages/coreui-vue/src/components/table/CTable.ts
new file mode 100644
index 00000000..563f6ac8
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/CTable.ts
@@ -0,0 +1,317 @@
+import { computed, defineComponent, h, PropType } from 'vue'
+
+import { CTableBody } from './CTableBody'
+import { CTableCaption } from './CTableCaption'
+import { CTableDataCell } from './CTableDataCell'
+import { CTableFoot } from './CTableFoot'
+import { CTableHead } from './CTableHead'
+import { CTableHeaderCell } from './CTableHeaderCell'
+import { CTableRow } from './CTableRow'
+
+import { Color } from '../../props'
+import { getColumnLabel, getColumnNames } from './utils'
+import type { Column, FooterItem, Item } from './types'
+
+const CTable = defineComponent({
+ name: 'CTable',
+ props: {
+ /**
+ * Set the vertical aligment.
+ *
+ * @values 'bottom', 'middle', 'top'
+ */
+ align: {
+ type: String,
+ validator: (value: string) => {
+ return ['bottom', 'middle', 'top'].includes(value)
+ },
+ },
+ /**
+ * Sets the border color of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
+ */
+ borderColor: Color,
+ /**
+ * Add borders on all sides of the table and cells.
+ */
+ bordered: Boolean,
+ /**
+ * Remove borders on all sides of the table and cells.
+ */
+ borderless: Boolean,
+ /**
+ * Put the `` on the top of the table.
+ *
+ * @values 'top' | string
+ */
+ caption: String,
+ /**
+ * Set the text of the table caption and the caption on the top of the table.
+ *
+ * @since 4.5.0
+ */
+ captionTop: String,
+ /**
+ * Prop for table columns configuration. If prop is not defined, table will display columns based on the first item keys, omitting keys that begins with underscore (e.g. '_props')
+ *
+ * In columns prop each array item represents one column. Item might be specified in two ways:
+ * String: each item define column name equal to item value.
+ * Object: item is object with following keys available as column configuration:
+ * - key (required)(String) - define column name equal to item key.
+ * - label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word.
+ * - _props (Object) - adds classes to all cels in column, ex. _props: { scope: 'col', className: 'custom-class' },
+ * - _style (Object) - adds styles to the column header (useful for defining widths)
+ *
+ * @since 4.5.0
+ */
+ columns: {
+ type: Array as PropType<(Column | string)[]>,
+ },
+ /**
+ * Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
+ */
+ color: Color,
+ /**
+ * Array of objects or strings, where each element represents one cell in the table footer.
+ *
+ * Example items:
+ * ['FooterCell', 'FooterCell', 'FooterCell']
+ * or
+ * [{ label: 'FooterCell', _props: { color: 'success' }, ...]
+ *
+ * @since 4.5.0
+ */
+ footer: {
+ type: Array as PropType<(FooterItem | string)[]>,
+ },
+ /**
+ * Enable a hover state on table rows within a ``.
+ */
+ hover: Boolean,
+ /**
+ * Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '_props' key and to single cell by '_cellProps'.
+ *
+ * Example item:
+ * { name: 'John' , age: 12, _props: { color: 'success' }, _cellProps: { age: { className: 'fw-bold'}}}
+ *
+ * @since 4.5.0
+ */
+ items: {
+ type: Array as PropType- ,
+ },
+ responsive: {
+ type: [Boolean, String],
+ validator: (value: boolean | string) => {
+ if (typeof value == 'string') {
+ return ['sm', 'md', 'lg', 'xl', 'xxl'].includes(value)
+ }
+ if (typeof value == 'boolean') {
+ return true
+ }
+ return false
+ },
+ },
+ /**
+ * Make table more compact by cutting all cell `padding` in half.
+ */
+ small: Boolean,
+ /**
+ * Add zebra-striping to any table row within the `
`.
+ */
+ striped: Boolean,
+ /**
+ * Add zebra-striping to any table column.
+ *
+ * @since 4.4.0
+ */
+ stripedColumns: Boolean,
+ /**
+ * Properties that will be passed to the table footer component.
+ *
+ * Properties to [CTableFoot](#ctablefoot) component.
+ * @since 4.5.0
+ */
+ tableFootProps: {
+ type: Object,
+ },
+ /**
+ * Properties that will be passed to the table head component.
+ *
+ * Properties to [CTableHead](#ctablehead) component.
+ * @since 4.5.0
+ */
+ tableHeadProps: {
+ type: Object,
+ },
+ },
+ setup(props, { slots, attrs }) {
+ const columnNames = computed(() => getColumnNames(props.columns, props.items))
+ // props.columns
+ // ? props.columns.map((column: Column | string) => {
+ // if (typeof column === 'object') return column.key
+ // else return column
+ // })
+ // : Object.keys((props.items && props.items[0]) || {}).filter((el) => el.charAt(0) !== '_'),
+ // )
+
+ const table = () =>
+ h(
+ 'table',
+ {
+ class: [
+ 'table',
+ {
+ [`align-${props.align}`]: props.align,
+ [`caption-top`]: props.captionTop || props.caption === 'top',
+ [`border-${props.borderColor}`]: props.borderColor,
+ 'table-bordered': props.bordered,
+ 'table-borderless': props.borderless,
+ [`table-${props.color}`]: props.color,
+ 'table-hover': props.hover,
+ 'table-sm': props.small,
+ 'table-striped': props.striped,
+ 'table-striped-columns': props.stripedColumns,
+ },
+ attrs.class,
+ ],
+ },
+ {
+ default: () => [
+ ((props.caption && props.caption !== 'top') || props.captionTop) &&
+ h(
+ CTableCaption,
+ {},
+ {
+ default: () => props.caption || props.captionTop,
+ },
+ ),
+ props.columns &&
+ h(
+ CTableHead,
+ {
+ ...props.tableHeadProps,
+ },
+ {
+ default: () =>
+ h(
+ CTableRow,
+ {},
+ {
+ default: () => [
+ props.columns &&
+ props.columns.map((column: Column | string) =>
+ h(
+ CTableHeaderCell,
+ {
+ ...(typeof column === 'object' &&
+ column._props && { ...column._props }),
+ ...(typeof column === 'object' &&
+ column._style && { style: { ...column._style } }),
+ },
+ {
+ default: () => getColumnLabel(column),
+ },
+ ),
+ ),
+ ],
+ },
+ ),
+ },
+ ),
+ props.items &&
+ h(
+ CTableBody,
+ {},
+ {
+ default: () => [
+ props.items &&
+ props.items.map((item: Item) =>
+ h(
+ CTableRow,
+ {
+ ...(item._props && { ...item._props }),
+ },
+ {
+ default: () => [
+ columnNames.value &&
+ columnNames.value.map(
+ (colName: string) =>
+ item[colName] !== undefined &&
+ h(
+ CTableDataCell,
+ {
+ ...(item._cellProps &&
+ item._cellProps['all'] && { ...item._cellProps['all'] }),
+ ...(item._cellProps &&
+ item._cellProps[colName] && {
+ ...item._cellProps[colName],
+ }),
+ },
+ {
+ default: () => item[colName],
+ },
+ ),
+ ),
+ ],
+ },
+ ),
+ ),
+ ],
+ },
+ ),
+ slots.default && slots.default(),
+ props.footer &&
+ h(
+ CTableFoot,
+ {
+ ...props.tableFootProps,
+ },
+ {
+ default: () =>
+ h(
+ CTableRow,
+ {},
+ {
+ default: () => [
+ props.footer &&
+ props.footer.map((item: FooterItem | string) =>
+ h(
+ CTableDataCell,
+ {
+ ...(typeof item === 'object' &&
+ item._props && { ...item._props }),
+ },
+ {
+ default: () => (typeof item === 'object' ? item.label : item),
+ },
+ ),
+ ),
+ ],
+ },
+ ),
+ },
+ ),
+ ],
+ },
+ )
+ return () => [
+ props.responsive
+ ? h(
+ 'div',
+ {
+ class:
+ typeof props.responsive === 'boolean'
+ ? 'table-responsive'
+ : `table-responsive-${props.responsive}`,
+ },
+ table(),
+ )
+ : table(),
+ ]
+ },
+})
+
+export { CTable }
diff --git a/src/components/table/CTableBody.ts b/packages/coreui-vue/src/components/table/CTableBody.ts
similarity index 94%
rename from src/components/table/CTableBody.ts
rename to packages/coreui-vue/src/components/table/CTableBody.ts
index a847553a..83526901 100644
--- a/src/components/table/CTableBody.ts
+++ b/packages/coreui-vue/src/components/table/CTableBody.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CTableBody = defineComponent({
name: 'CTableBody',
diff --git a/src/components/table/CTableCaption.ts b/packages/coreui-vue/src/components/table/CTableCaption.ts
similarity index 94%
rename from src/components/table/CTableCaption.ts
rename to packages/coreui-vue/src/components/table/CTableCaption.ts
index 11322222..ef069990 100644
--- a/src/components/table/CTableCaption.ts
+++ b/packages/coreui-vue/src/components/table/CTableCaption.ts
@@ -2,7 +2,6 @@ import { defineComponent, h } from 'vue'
const CTableCaption = defineComponent({
name: 'CTableCaption',
- props: {},
setup(_, { slots }) {
return () => h('caption', {}, slots.default && slots.default())
},
diff --git a/src/components/table/CTableDataCell.ts b/packages/coreui-vue/src/components/table/CTableDataCell.ts
similarity index 83%
rename from src/components/table/CTableDataCell.ts
rename to packages/coreui-vue/src/components/table/CTableDataCell.ts
index d2bf7500..fa60429c 100644
--- a/src/components/table/CTableDataCell.ts
+++ b/packages/coreui-vue/src/components/table/CTableDataCell.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CTableDataCell = defineComponent({
name: 'CTableDataCell',
@@ -8,10 +8,7 @@ const CTableDataCell = defineComponent({
/**
* Highlight a table row or cell.
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Set the vertical aligment.
*
@@ -19,8 +16,6 @@ const CTableDataCell = defineComponent({
*/
align: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['bottom', 'middle', 'top'].includes(value)
},
@@ -31,11 +26,15 @@ const CTableDataCell = defineComponent({
* @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
*/
color: Color,
+ /**
+ * @ignore
+ */
+ scope: String,
},
setup(props, { slots }) {
return () =>
h(
- 'td',
+ props.scope ? 'th' : 'td',
{
class: [
{
@@ -44,6 +43,7 @@ const CTableDataCell = defineComponent({
[`table-${props.color}`]: props.color,
},
],
+ ...(props.scope && { scope: props.scope }),
},
slots.default && slots.default(),
)
diff --git a/src/components/table/CTableFoot.ts b/packages/coreui-vue/src/components/table/CTableFoot.ts
similarity index 94%
rename from src/components/table/CTableFoot.ts
rename to packages/coreui-vue/src/components/table/CTableFoot.ts
index 600e39b8..3876e05c 100644
--- a/src/components/table/CTableFoot.ts
+++ b/packages/coreui-vue/src/components/table/CTableFoot.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CTableFoot = defineComponent({
name: 'CTableFoot',
diff --git a/src/components/table/CTableHead.ts b/packages/coreui-vue/src/components/table/CTableHead.ts
similarity index 94%
rename from src/components/table/CTableHead.ts
rename to packages/coreui-vue/src/components/table/CTableHead.ts
index 07bd43db..85a50aa2 100644
--- a/src/components/table/CTableHead.ts
+++ b/packages/coreui-vue/src/components/table/CTableHead.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CTableHead = defineComponent({
name: 'CTableHead',
diff --git a/src/components/table/CTableHeaderCell.ts b/packages/coreui-vue/src/components/table/CTableHeaderCell.ts
similarity index 94%
rename from src/components/table/CTableHeaderCell.ts
rename to packages/coreui-vue/src/components/table/CTableHeaderCell.ts
index 216af624..fb4c9bea 100644
--- a/src/components/table/CTableHeaderCell.ts
+++ b/packages/coreui-vue/src/components/table/CTableHeaderCell.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CTableHeaderCell = defineComponent({
name: 'CTableHeaderCell',
diff --git a/src/components/table/CTableRow.ts b/packages/coreui-vue/src/components/table/CTableRow.ts
similarity index 87%
rename from src/components/table/CTableRow.ts
rename to packages/coreui-vue/src/components/table/CTableRow.ts
index bf21efa1..40dfeb66 100644
--- a/src/components/table/CTableRow.ts
+++ b/packages/coreui-vue/src/components/table/CTableRow.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
+import { Color } from '../../props'
const CTableRow = defineComponent({
name: 'CTableRow',
@@ -8,10 +8,7 @@ const CTableRow = defineComponent({
/**
* Highlight a table row or cell..
*/
- active: {
- type: Boolean,
- required: false,
- },
+ active: Boolean,
/**
* Set the vertical aligment.
*
@@ -19,8 +16,6 @@ const CTableRow = defineComponent({
*/
align: {
type: String,
- default: undefined,
- required: false,
validator: (value: string) => {
return ['bottom', 'middle', 'top'].includes(value)
},
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTable.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTable.spec.ts
new file mode 100644
index 00000000..04a481f0
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTable.spec.ts
@@ -0,0 +1,63 @@
+import { mount } from '@vue/test-utils'
+import { CTable as Component } from '../../../index'
+
+const ComponentName = 'CTable'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ align: 'center',
+ borderColor: 'dark',
+ bordered: true,
+ borderless: true,
+ caption: 'top',
+ color: 'warning',
+ hover: true,
+ responsive: 'lg',
+ small: true,
+ striped: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.find('table').text()).toContain('Default slot')
+ expect(defaultWrapper.find('table').classes('table')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.find('div').classes('table-responsive-lg')).toBe(true)
+ expect(customWrapper.find('table').text()).toContain('Default slot')
+ expect(customWrapper.find('table').classes('table')).toBe(true)
+ expect(customWrapper.find('table').classes('align-center')).toBe(true)
+ expect(customWrapper.find('table').classes('table')).toBe(true)
+ expect(customWrapper.find('table').classes('caption-top')).toBe(true)
+ expect(customWrapper.find('table').classes('border-dark')).toBe(true)
+ expect(customWrapper.find('table').classes('table-bordered')).toBe(true)
+ expect(customWrapper.find('table').classes('table-borderless')).toBe(true)
+ expect(customWrapper.find('table').classes('table-warning')).toBe(true)
+ expect(customWrapper.find('table').classes('table-hover')).toBe(true)
+ expect(customWrapper.find('table').classes('table-sm')).toBe(true)
+ expect(customWrapper.find('table').classes('table-striped')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableBody.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableBody.spec.ts
new file mode 100644
index 00000000..abbdc049
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableBody.spec.ts
@@ -0,0 +1,42 @@
+import { mount } from '@vue/test-utils'
+import { CTableBody as Component } from '../../../index'
+
+const ComponentName = 'CTableBody'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('table-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableCaption.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableCaption.spec.ts
new file mode 100644
index 00000000..aa388314
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableCaption.spec.ts
@@ -0,0 +1,22 @@
+import { mount } from '@vue/test-utils'
+import { CTableCaption as Component } from '../../../index'
+
+const ComponentName = 'CTableCaption'
+
+const defaultWrapper = mount(Component, {
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableDataCell.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableDataCell.spec.ts
new file mode 100644
index 00000000..530fac28
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableDataCell.spec.ts
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils'
+import { CTableDataCell as Component } from '../../../index'
+
+const ComponentName = 'CTableDataCell'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ align: 'middle',
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('align-middle')).toBe(true)
+ expect(customWrapper.classes('table-active')).toBe(true)
+ expect(customWrapper.classes('table-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableFoot.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableFoot.spec.ts
new file mode 100644
index 00000000..ccb2a125
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableFoot.spec.ts
@@ -0,0 +1,42 @@
+import { mount } from '@vue/test-utils'
+import { CTableFoot as Component } from '../../../index'
+
+const ComponentName = 'CTableFoot'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('table-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableHead.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableHead.spec.ts
new file mode 100644
index 00000000..fa8672a9
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableHead.spec.ts
@@ -0,0 +1,42 @@
+import { mount } from '@vue/test-utils'
+import { CTableHead as Component } from '../../../index'
+
+const ComponentName = 'CTableHead'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('table-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableHeaderCell.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableHeaderCell.spec.ts
new file mode 100644
index 00000000..e79a589d
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableHeaderCell.spec.ts
@@ -0,0 +1,42 @@
+import { mount } from '@vue/test-utils'
+import { CTableHeaderCell as Component } from '../../../index'
+
+const ComponentName = 'CTableHeaderCell'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('table-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/CTableRow.spec.ts b/packages/coreui-vue/src/components/table/__tests__/CTableRow.spec.ts
new file mode 100644
index 00000000..755b0da4
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/CTableRow.spec.ts
@@ -0,0 +1,46 @@
+import { mount } from '@vue/test-utils'
+import { CTableRow as Component } from '../../../index'
+
+const ComponentName = 'CTableRow'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ active: true,
+ align: 'middle',
+ color: 'warning',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('align-middle')).toBe(true)
+ expect(customWrapper.classes('table-active')).toBe(true)
+ expect(customWrapper.classes('table-warning')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTable.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTable.spec.ts.snap
new file mode 100644
index 00000000..896ca48b
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTable.spec.ts.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTable component renders correctly 1`] = `
+""
+`;
+
+exports[`Loads and display CTable component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableBody.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableBody.spec.ts.snap
new file mode 100644
index 00000000..fc64a172
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableBody.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTableBody component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CTableBody component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableCaption.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableCaption.spec.ts.snap
new file mode 100644
index 00000000..51b451b6
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableCaption.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CTableCaption component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.ts.snap
new file mode 100644
index 00000000..75f33858
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableDataCell.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTableDataCell component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CTableDataCell component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableFoot.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableFoot.spec.ts.snap
new file mode 100644
index 00000000..4d50b597
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableFoot.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTableFoot component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CTableFoot component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableHead.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableHead.spec.ts.snap
new file mode 100644
index 00000000..e2a9c114
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableHead.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTableHead component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CTableHead component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.ts.snap
new file mode 100644
index 00000000..b5523d84
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableHeaderCell.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTableHeaderCell component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CTableHeaderCell component renders correctly 1`] = `"Default slot "`;
diff --git a/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableRow.spec.ts.snap b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableRow.spec.ts.snap
new file mode 100644
index 00000000..11c6d246
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/__tests__/__snapshots__/CTableRow.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTableRow component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CTableRow component renders correctly 1`] = `"Default slot "`;
diff --git a/src/components/table/index.ts b/packages/coreui-vue/src/components/table/index.ts
similarity index 100%
rename from src/components/table/index.ts
rename to packages/coreui-vue/src/components/table/index.ts
diff --git a/packages/coreui-vue/src/components/table/types.ts b/packages/coreui-vue/src/components/table/types.ts
new file mode 100644
index 00000000..8f96b27b
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/types.ts
@@ -0,0 +1,20 @@
+export type Column = {
+ label?: string
+ key: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ _style?: any
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ _props?: any
+}
+
+export type FooterItem = {
+ label?: string
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ _props?: any
+}
+
+export type Item = {
+ [key: string]: number | string | any
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ _props?: any
+}
diff --git a/packages/coreui-vue/src/components/table/utils.ts b/packages/coreui-vue/src/components/table/utils.ts
new file mode 100644
index 00000000..9c55ade1
--- /dev/null
+++ b/packages/coreui-vue/src/components/table/utils.ts
@@ -0,0 +1,24 @@
+import type { Column, Item } from './types'
+
+export const pretifyName = (name: string) => {
+ return name
+ .replace(/[-_.]/g, ' ')
+ .replace(/ +/g, ' ')
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
+ .split(' ')
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
+ .join(' ')
+}
+
+export const getColumnLabel = (column: Column | string) =>
+ typeof column === 'object' ? column.label ?? pretifyName(column.key) : pretifyName(column)
+
+export const getColumnNames = (columns: (string | Column)[] | undefined, items?: Item[]) =>
+ columns
+ ? columns.map((column: Column | string) => {
+ return typeof column === 'object' ? column.key : column
+ })
+ : items && getColumnNamesFromItems(items)
+
+export const getColumnNamesFromItems = (items: Item[]) =>
+ Object.keys(items[0] || {}).filter((el) => el.charAt(0) !== '_')
diff --git a/src/components/tabs/CTabContent.ts b/packages/coreui-vue/src/components/tabs/CTabContent.ts
similarity index 89%
rename from src/components/tabs/CTabContent.ts
rename to packages/coreui-vue/src/components/tabs/CTabContent.ts
index e336e69f..f0ad00b1 100644
--- a/src/components/tabs/CTabContent.ts
+++ b/packages/coreui-vue/src/components/tabs/CTabContent.ts
@@ -1,7 +1,7 @@
import { defineComponent, h } from 'vue'
const CTabContent = defineComponent({
- name: 'CNavGroupItems',
+ name: 'CTabContent',
setup(_, { slots }) {
return () => h('div', { class: 'tab-content' }, slots.default && slots.default())
},
diff --git a/packages/coreui-vue/src/components/tabs/CTabPane.ts b/packages/coreui-vue/src/components/tabs/CTabPane.ts
new file mode 100644
index 00000000..9ff0050f
--- /dev/null
+++ b/packages/coreui-vue/src/components/tabs/CTabPane.ts
@@ -0,0 +1,76 @@
+import { defineComponent, h, ref, RendererElement, Transition, vShow, withDirectives } from 'vue'
+
+import { executeAfterTransition } from '../../utils/transition'
+
+const CTabPane = defineComponent({
+ name: 'CTabPane',
+ props: {
+ /**
+ * Toggle the visibility of component.
+ */
+ visible: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { slots, emit }) {
+ const tabPaneRef = ref()
+ const firstRender = ref(true)
+
+ const handleEnter = (el: RendererElement, done: () => void) => {
+ firstRender.value = false
+ emit('show')
+ setTimeout(() => {
+ executeAfterTransition(() => done(), el as HTMLElement)
+ el.classList.add('show')
+ }, 1)
+ }
+
+ const handleLeave = (el: RendererElement, done: () => void) => {
+ firstRender.value = false
+ emit('hide')
+ el.classList.remove('show')
+ executeAfterTransition(() => done(), el as HTMLElement)
+ }
+
+ return () =>
+ h(
+ Transition,
+ {
+ onEnter: (el, done) => handleEnter(el, done),
+ onLeave: (el, done) => handleLeave(el, done),
+ },
+ () =>
+ withDirectives(
+ h(
+ 'div',
+ {
+ class: [
+ 'tab-pane',
+ 'fade',
+ {
+ active: props.visible,
+ show: firstRender.value && props.visible,
+ },
+ ],
+ ref: tabPaneRef,
+ },
+ slots.default && slots.default(),
+ ),
+ [[vShow, props.visible]],
+ ),
+ )
+ },
+})
+
+export { CTabPane }
diff --git a/packages/coreui-vue/src/components/tabs/__tests__/CTabContent.spec.ts b/packages/coreui-vue/src/components/tabs/__tests__/CTabContent.spec.ts
new file mode 100644
index 00000000..20f4ffaf
--- /dev/null
+++ b/packages/coreui-vue/src/components/tabs/__tests__/CTabContent.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CTabContent as Component } from '../../../index'
+
+const ComponentName = 'CTabContent'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('tab-content')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/tabs/__tests__/CTabPane.spec.ts b/packages/coreui-vue/src/components/tabs/__tests__/CTabPane.spec.ts
new file mode 100644
index 00000000..21b235f6
--- /dev/null
+++ b/packages/coreui-vue/src/components/tabs/__tests__/CTabPane.spec.ts
@@ -0,0 +1,47 @@
+import { mount } from '@vue/test-utils'
+import { CTabPane as Component } from '../../../index'
+
+const ComponentName = 'CTabPane'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.find('.tab-pane').classes('tab-pane')).toBe(true)
+ expect(defaultWrapper.find('.tab-pane').classes('fade')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.find('.tab-pane').classes('tab-pane')).toBe(true)
+ expect(customWrapper.find('.tab-pane').classes('fade')).toBe(true)
+ expect(customWrapper.find('.tab-pane').classes('show')).toBe(true)
+ expect(customWrapper.find('.tab-pane').classes('active')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.ts.snap b/packages/coreui-vue/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.ts.snap
new file mode 100644
index 00000000..a6fe655d
--- /dev/null
+++ b/packages/coreui-vue/src/components/tabs/__tests__/__snapshots__/CTabContent.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CTabContent component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.ts.snap b/packages/coreui-vue/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.ts.snap
new file mode 100644
index 00000000..49b97a03
--- /dev/null
+++ b/packages/coreui-vue/src/components/tabs/__tests__/__snapshots__/CTabPane.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CTabPane component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
+
+exports[`Loads and display CTabPane component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
diff --git a/src/components/tabs/index.ts b/packages/coreui-vue/src/components/tabs/index.ts
similarity index 100%
rename from src/components/tabs/index.ts
rename to packages/coreui-vue/src/components/tabs/index.ts
diff --git a/packages/coreui-vue/src/components/toast/CToast.ts b/packages/coreui-vue/src/components/toast/CToast.ts
new file mode 100644
index 00000000..eb6c84e5
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/CToast.ts
@@ -0,0 +1,124 @@
+import { defineComponent, h, onMounted, provide, ref, Transition } from 'vue'
+
+import { Color } from '../../props'
+
+const CToast = defineComponent({
+ name: 'CToast',
+ props: {
+ /**
+ * Auto hide the toast.
+ */
+ autohide: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * Sets the color context of the component to one of CoreUI’s themed colors.
+ *
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light', string
+ */
+ color: Color,
+ /**
+ * Delay hiding the toast (ms).
+ */
+ delay: {
+ type: Number,
+ default: 5000,
+ },
+ /**
+ * Optionally add a close button to component and allow it to self dismiss.
+ */
+ dismissible: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * index of the component.
+ */
+ index: Number,
+ /**
+ * Title node for your component.
+ */
+ title: String,
+ /**
+ * Toggle the visibility of component.
+ */
+ visible: Boolean,
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be closed.
+ */
+ 'close',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { slots, emit }) {
+ const timeout = ref(0)
+ const visible = ref()
+
+ const updateVisible = (_visible: boolean) => {
+ visible.value = _visible
+ }
+
+ provide('updateVisible', updateVisible)
+
+ onMounted(() => {
+ if (props.visible) {
+ visible.value = props.visible
+ }
+
+ if (props.autohide) {
+ clearTimeout(timeout.value)
+ timeout.value = window.setTimeout(() => {
+ visible.value = false
+ emit('close')
+ }, props.delay)
+ }
+ })
+
+ return () =>
+ h(
+ Transition,
+ {
+ appear: true,
+ enterFromClass: '',
+ enterActiveClass: 'show showing',
+ enterToClass: 'show',
+ leaveFromClass: 'show',
+ leaveActiveClass: 'show showing',
+ leaveToClass: 'show',
+ onAfterEnter: (el) => {
+ el.classList.add('show')
+ props.index ? emit('show', props.index) : emit('show')
+ },
+ onAfterLeave: () => {
+ props.index ? emit('close', props.index) : emit('close')
+ },
+ },
+ {
+ default: () =>
+ visible.value &&
+ h(
+ 'div',
+ {
+ class: [
+ 'toast fade',
+ {
+ [`bg-${props.color}`]: props.color,
+ },
+ ],
+ 'aria-live': 'assertive',
+ 'aria-atomic': true,
+ role: 'alert',
+ },
+ slots.default && slots.default(),
+ ),
+ },
+ )
+ },
+})
+
+export { CToast }
diff --git a/src/components/toast/CToastBody.ts b/packages/coreui-vue/src/components/toast/CToastBody.ts
similarity index 100%
rename from src/components/toast/CToastBody.ts
rename to packages/coreui-vue/src/components/toast/CToastBody.ts
diff --git a/src/components/toast/CToastClose.ts b/packages/coreui-vue/src/components/toast/CToastClose.ts
similarity index 63%
rename from src/components/toast/CToastClose.ts
rename to packages/coreui-vue/src/components/toast/CToastClose.ts
index dba3fe96..f0aedd8d 100644
--- a/src/components/toast/CToastClose.ts
+++ b/packages/coreui-vue/src/components/toast/CToastClose.ts
@@ -1,4 +1,4 @@
-import { defineComponent, h, inject, resolveComponent } from 'vue'
+import { defineComponent, h, inject } from 'vue'
import { CCloseButton } from '../close-button/CCloseButton'
const CToastClose = defineComponent({
@@ -7,30 +7,32 @@ const CToastClose = defineComponent({
/**
* Component used for the root node. Either a string to use a HTML element or a component.
*/
- component: {
- type: String,
- default: undefined,
- required: false,
- },
+ component: String,
...CCloseButton.props,
},
- emits: ['dismiss'],
+ emits: [
+ /**
+ * Event called before the dissmiss animation has started.
+ */
+ 'close',
+ ],
setup(props, { slots, emit }) {
- const updateVisible = inject('updateVisible') as any
+ // eslint-disable-next-line no-unused-vars
+ const updateVisible = inject('updateVisible') as (visible: boolean) => void
const handleClose = () => {
- emit('dismiss')
+ emit('close')
updateVisible(false)
}
return () =>
props.component
? h(
- resolveComponent(props.component),
+ props.component,
{
onClick: () => {
handleClose()
},
},
- slots.default && slots.default(),
+ () => slots.default && slots.default(),
)
: h(CCloseButton, {
...props,
diff --git a/src/components/toast/CToastHeader.ts b/packages/coreui-vue/src/components/toast/CToastHeader.ts
similarity index 63%
rename from src/components/toast/CToastHeader.ts
rename to packages/coreui-vue/src/components/toast/CToastHeader.ts
index af79ac9f..74fbc651 100644
--- a/src/components/toast/CToastHeader.ts
+++ b/packages/coreui-vue/src/components/toast/CToastHeader.ts
@@ -7,24 +7,21 @@ const CToastHeader = defineComponent({
/**
* Automatically add a close button to the header.
*/
- close: {
- type: Boolean,
- require: false,
- },
+ closeButton: Boolean,
},
+ emits: [
+ /**
+ * Event called after clicking the close button.
+ */
+ 'close',
+ ],
setup(props, { slots, emit }) {
- const handleClose = () => {
- /**
- * Event called after clicking the close button.
- */
- emit('close')
- }
return () =>
h('div', { class: 'toast-header' }, [
slots.default && slots.default(),
- props.close &&
+ props.closeButton &&
h(CToastClose, {
- onClose: () => handleClose(),
+ onClose: () => emit('close'),
}),
])
},
diff --git a/src/components/toast/CToaster.ts b/packages/coreui-vue/src/components/toast/CToaster.ts
similarity index 95%
rename from src/components/toast/CToaster.ts
rename to packages/coreui-vue/src/components/toast/CToaster.ts
index a1e3be0d..6e5b8381 100644
--- a/src/components/toast/CToaster.ts
+++ b/packages/coreui-vue/src/components/toast/CToaster.ts
@@ -7,12 +7,9 @@ const CToaster = defineComponent({
* Describes the placement of component.
*
* @values 'top-start', 'top', 'top-end', 'middle-start', 'middle', 'middle-end', 'bottom-start', 'bottom', 'bottom-end'
- * @default 'top-end'
*/
placement: {
type: String,
- default: undefined,
- require: false,
validator: (value: string) => {
return [
'top-start',
diff --git a/packages/coreui-vue/src/components/toast/__tests__/CToast.spec.ts b/packages/coreui-vue/src/components/toast/__tests__/CToast.spec.ts
new file mode 100644
index 00000000..c6296599
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/CToast.spec.ts
@@ -0,0 +1,60 @@
+import { mount } from '@vue/test-utils'
+import { CToast as Component } from '../../../index'
+
+const ComponentName = 'CToast'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ autohide: false,
+ color: 'warning',
+ delay: 3000,
+ dismissible: false,
+ key: 123,
+ title: 'title',
+ visible: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.find('div').text()).toContain('Default slot')
+ expect(defaultWrapper.find('div').classes('toast')).toBe(true)
+ expect(defaultWrapper.find('div').classes('fade')).toBe(true)
+ expect(defaultWrapper.find('div').attributes('aria-live')).toBe('assertive')
+ expect(defaultWrapper.find('div').attributes('aria-atomic')).toBe('true')
+ expect(defaultWrapper.find('div').attributes('role')).toBe('alert')
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.find('div').text()).toContain('Default slot')
+ expect(customWrapper.find('div').classes('toast')).toBe(true)
+ expect(customWrapper.find('div').classes('fade')).toBe(true)
+ expect(customWrapper.find('div').classes('bg-warning')).toBe(true)
+ expect(customWrapper.find('div').attributes('aria-live')).toBe('assertive')
+ expect(customWrapper.find('div').attributes('aria-atomic')).toBe('true')
+ expect(customWrapper.find('div').attributes('role')).toBe('alert')
+ })
+})
diff --git a/packages/coreui-vue/src/components/toast/__tests__/CToastBody.spec.ts b/packages/coreui-vue/src/components/toast/__tests__/CToastBody.spec.ts
new file mode 100644
index 00000000..eab8e7e4
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/CToastBody.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CToastBody as Component } from '../../../index'
+
+const ComponentName = 'CToastBody'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('toast-body')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/toast/__tests__/CToastClose.spec.ts b/packages/coreui-vue/src/components/toast/__tests__/CToastClose.spec.ts
new file mode 100644
index 00000000..eee1ba77
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/CToastClose.spec.ts
@@ -0,0 +1,69 @@
+import { mount } from '@vue/test-utils'
+import { CButton, CToastClose as Component } from '../../../index'
+
+const ComponentName = 'CToastClose'
+
+const updateVisible = (v: boolean) => {
+ return v
+}
+
+const defaultWrapper = mount(Component, {
+ global: {
+ provide: {
+ updateVisible: updateVisible,
+ },
+ },
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ component: CButton,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+ global: {
+ provide: {
+ updateVisible: function () {
+ return true
+ },
+ },
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.classes('btn')).toBe(true)
+ expect(defaultWrapper.classes('btn-close')).toBe(true)
+ })
+ it('event on click', () => {
+ defaultWrapper.trigger('click')
+ const incrementEvent = defaultWrapper.emitted('close')
+ expect(incrementEvent).toHaveLength(1)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ //expect(customWrapper.classes('btn')).toBe(true)
+ })
+ it('event on click', () => {
+ customWrapper.trigger('click')
+ const incrementEvent = customWrapper.emitted('close')
+ expect(incrementEvent).toHaveLength(1)
+ })
+})
diff --git a/packages/coreui-vue/src/components/toast/__tests__/CToastHeader.spec.ts b/packages/coreui-vue/src/components/toast/__tests__/CToastHeader.spec.ts
new file mode 100644
index 00000000..6950cfae
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/CToastHeader.spec.ts
@@ -0,0 +1,54 @@
+import { mount } from '@vue/test-utils'
+import { CToastHeader as Component } from '../../../index'
+
+const ComponentName = 'CToastHeader'
+
+const updateVisible = (v: boolean) => {
+ return v
+}
+
+const defaultWrapper = mount(Component, {
+ global: {
+ provide: {
+ updateVisible: updateVisible,
+ },
+ },
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ closeButton: true,
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('toast-header')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('toast-header')).toBe(true)
+ expect(customWrapper.find('button').classes('btn')).toBe(true)
+ expect(customWrapper.find('button').classes('btn-close')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/toast/__tests__/CToaster.spec.ts b/packages/coreui-vue/src/components/toast/__tests__/CToaster.spec.ts
new file mode 100644
index 00000000..d6e5a617
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/CToaster.spec.ts
@@ -0,0 +1,50 @@
+import { mount } from '@vue/test-utils'
+import { CToaster as Component } from '../../../index'
+
+const ComponentName = 'CToaster'
+
+const defaultWrapper = mount(Component, {
+ propsData: {},
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+const customWrapper = mount(Component, {
+ propsData: {
+ placement: 'top-end',
+ },
+ slots: {
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(defaultWrapper.text()).toContain('Default slot')
+ expect(defaultWrapper.classes('toaster')).toBe(true)
+ expect(defaultWrapper.classes('toast-container')).toBe(true)
+ expect(defaultWrapper.classes('p-3')).toBe(true)
+ })
+})
+
+describe(`Customize ${ComponentName} component`, () => {
+ it('renders correctly', () => {
+ expect(customWrapper.html()).toMatchSnapshot()
+ })
+ it('contain slots and classes', () => {
+ expect(customWrapper.text()).toContain('Default slot')
+ expect(customWrapper.classes('toaster')).toBe(true)
+ expect(customWrapper.classes('toast-container')).toBe(true)
+ expect(customWrapper.classes('p-3')).toBe(true)
+ expect(customWrapper.classes('position-fixed')).toBe(true)
+ expect(customWrapper.classes('top-0')).toBe(true)
+ expect(customWrapper.classes('end-0')).toBe(true)
+ })
+})
diff --git a/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToast.spec.ts.snap b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToast.spec.ts.snap
new file mode 100644
index 00000000..a5234490
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToast.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CToast component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
+
+exports[`Loads and display CToast component renders correctly 1`] = `
+"
+ Default slot
+ "
+`;
diff --git a/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastBody.spec.ts.snap b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastBody.spec.ts.snap
new file mode 100644
index 00000000..0636c970
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastBody.spec.ts.snap
@@ -0,0 +1,3 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CToastBody component renders correctly 1`] = `"Default slot
"`;
diff --git a/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastClose.spec.ts.snap b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastClose.spec.ts.snap
new file mode 100644
index 00000000..6944431f
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastClose.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CToastClose component renders correctly 1`] = `"Default slot "`;
+
+exports[`Loads and display CToastClose component renders correctly 1`] = `" "`;
diff --git a/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.ts.snap b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.ts.snap
new file mode 100644
index 00000000..6682d823
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToastHeader.spec.ts.snap
@@ -0,0 +1,9 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CToastHeader component renders correctly 1`] = `""`;
+
+exports[`Loads and display CToastHeader component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToaster.spec.ts.snap b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToaster.spec.ts.snap
new file mode 100644
index 00000000..8f23150f
--- /dev/null
+++ b/packages/coreui-vue/src/components/toast/__tests__/__snapshots__/CToaster.spec.ts.snap
@@ -0,0 +1,5 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Customize CToaster component renders correctly 1`] = `"Default slot
"`;
+
+exports[`Loads and display CToaster component renders correctly 1`] = `"Default slot
"`;
diff --git a/src/components/toast/index.ts b/packages/coreui-vue/src/components/toast/index.ts
similarity index 100%
rename from src/components/toast/index.ts
rename to packages/coreui-vue/src/components/toast/index.ts
diff --git a/packages/coreui-vue/src/components/tooltip/CTooltip.ts b/packages/coreui-vue/src/components/tooltip/CTooltip.ts
new file mode 100644
index 00000000..db47bddb
--- /dev/null
+++ b/packages/coreui-vue/src/components/tooltip/CTooltip.ts
@@ -0,0 +1,224 @@
+import { defineComponent, h, PropType, ref, RendererElement, Teleport, Transition } from 'vue'
+import type { Placement } from '@popperjs/core'
+
+import { usePopper } from '../../composables'
+import type { Placements, Triggers } from '../../types'
+import { executeAfterTransition } from '../../utils/transition'
+import { getRTLPlacement } from '../../utils'
+
+const CTooltip = defineComponent({
+ name: 'CTooltip',
+ props: {
+ /**
+ * Apply a CSS fade transition to the tooltip.
+ *
+ * @since 4.9.0
+ */
+ animation: {
+ type: Boolean,
+ default: true,
+ },
+ /**
+ * Content for your component. If you want to pass non-string value please use dedicated slot `... `
+ */
+ content: String,
+ /**
+ * The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`.
+ *
+ * @since 4.9.0
+ */
+ delay: {
+ type: [Number, Object] as PropType,
+ default: 0,
+ },
+ /**
+ * Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference.
+ *
+ * @since 4.9.0
+ */
+ fallbackPlacements: {
+ type: [String, Array] as PropType,
+ default: () => ['top', 'right', 'bottom', 'left'],
+ validator: (value: Placements | Placements[]) => {
+ if (typeof value === 'string') {
+ return ['top', 'right', 'bottom', 'left'].includes(value)
+ }
+ if (Array.isArray(value)) {
+ return value.every((e) => ['top', 'right', 'bottom', 'left'].includes(e))
+ }
+ return false
+ },
+ },
+ /**
+ * Offset of the tooltip relative to its target.
+ */
+ offset: {
+ type: Array,
+ default: () => [0, 6],
+ },
+ /**
+ * Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property.
+ */
+ placement: {
+ type: String as PropType,
+ default: 'top',
+ validator: (value: string) => {
+ return ['top', 'right', 'bottom', 'left'].includes(value)
+ },
+ },
+ /**
+ * Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them.
+ *
+ * @values 'click', 'focus', 'hover'
+ */
+ trigger: {
+ type: [String, Array] as PropType,
+ default: () => ['hover', 'focus'],
+ validator: (value: Triggers | Triggers[]) => {
+ if (typeof value === 'string') {
+ return ['click', 'focus', 'hover'].includes(value)
+ }
+ if (Array.isArray(value)) {
+ return value.every((e) => ['click', 'focus', 'hover'].includes(e))
+ }
+ return false
+ },
+ },
+ /**
+ * Toggle the visibility of tooltip component.
+ */
+ visible: Boolean,
+ },
+ emits: [
+ /**
+ * Callback fired when the component requests to be hidden.
+ */
+ 'hide',
+ /**
+ * Callback fired when the component requests to be shown.
+ */
+ 'show',
+ ],
+ setup(props, { attrs, slots, emit }) {
+ const togglerRef = ref()
+ const tooltipRef = ref()
+ const visible = ref(props.visible)
+ const { initPopper, destroyPopper } = usePopper()
+
+ const delay =
+ typeof props.delay === 'number' ? { show: props.delay, hide: props.delay } : props.delay
+
+ const popperConfig = {
+ modifiers: [
+ {
+ name: 'arrow',
+ options: {
+ element: '.tooltip-arrow',
+ },
+ },
+ {
+ name: 'flip',
+ options: {
+ fallbackPlacements: props.fallbackPlacements,
+ },
+ },
+ {
+ name: 'offset',
+ options: {
+ offset: props.offset,
+ },
+ },
+ ],
+ placement: getRTLPlacement(props.placement, togglerRef.value),
+ }
+
+ const handleEnter = (el: RendererElement, done: () => void) => {
+ emit('show')
+ initPopper(togglerRef.value, tooltipRef.value, popperConfig)
+ el.classList.add('show')
+ executeAfterTransition(() => done(), el as HTMLElement)
+ }
+
+ const handleLeave = (el: RendererElement, done: () => void) => {
+ emit('hide')
+ el.classList.remove('show')
+ executeAfterTransition(() => {
+ done()
+ destroyPopper()
+ }, el as HTMLElement)
+ }
+
+ const toggleVisible = (event: Event, _visible: boolean) => {
+ togglerRef.value = event.target
+ if (_visible) {
+ setTimeout(() => {
+ visible.value = true
+ }, delay.show)
+ return
+ }
+
+ setTimeout(() => {
+ visible.value = false
+ }, delay.hide)
+ }
+
+ return () => [
+ h(
+ Teleport,
+ {
+ to: 'body',
+ },
+ h(
+ Transition,
+ {
+ onEnter: (el, done) => handleEnter(el, done),
+ onLeave: (el, done) => handleLeave(el, done),
+ },
+ () =>
+ visible.value &&
+ h(
+ 'div',
+ {
+ class: [
+ 'tooltip',
+ 'bs-tooltip-auto',
+ {
+ fade: props.animation,
+ },
+ ],
+ ref: tooltipRef,
+ role: 'tooltip',
+ ...attrs,
+ },
+ [
+ h('div', { class: 'tooltip-arrow' }),
+ (props.content || slots.content) &&
+ h(
+ 'div',
+ { class: 'tooltip-inner' },
+ {
+ default: () => (slots.content && slots.content()) || props.content,
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ slots.toggler &&
+ slots.toggler({
+ on: {
+ click: (event: Event) =>
+ props.trigger.includes('click') && toggleVisible(event, !visible.value),
+ blur: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, false),
+ focus: (event: Event) => props.trigger.includes('focus') && toggleVisible(event, true),
+ mouseenter: (event: Event) =>
+ props.trigger.includes('hover') && toggleVisible(event, true),
+ mouseleave: (event: Event) =>
+ props.trigger.includes('hover') && toggleVisible(event, false),
+ },
+ }),
+ ]
+ },
+})
+
+export { CTooltip }
diff --git a/packages/coreui-vue/src/components/tooltip/index.ts b/packages/coreui-vue/src/components/tooltip/index.ts
new file mode 100644
index 00000000..88b3e802
--- /dev/null
+++ b/packages/coreui-vue/src/components/tooltip/index.ts
@@ -0,0 +1,10 @@
+import { App } from 'vue'
+import { CTooltip } from './CTooltip'
+
+const CTooltipPlugin = {
+ install: (app: App): void => {
+ app.component(CTooltip.name, CTooltip)
+ },
+}
+
+export { CTooltipPlugin, CTooltip }
diff --git a/src/components/widgets/CWidgetStatsA.ts b/packages/coreui-vue/src/components/widgets/CWidgetStatsA.ts
similarity index 91%
rename from src/components/widgets/CWidgetStatsA.ts
rename to packages/coreui-vue/src/components/widgets/CWidgetStatsA.ts
index 24633fab..c2d3cc18 100644
--- a/src/components/widgets/CWidgetStatsA.ts
+++ b/packages/coreui-vue/src/components/widgets/CWidgetStatsA.ts
@@ -5,26 +5,17 @@ import { CCard, CCardBody } from '../card'
const CWidgetStatsA = defineComponent({
name: 'CWidgetStatsA',
props: {
- color: {
- type: String,
- default: undefined,
- require: false,
- },
+ color: String,
/**
* Title for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- title: {
- type: String,
- default: undefined,
- require: false,
- },
+ title: String,
/**
* Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... `
*/
value: {
type: [Number, String],
default: 0,
- require: false,
},
},
/**
diff --git a/src/components/widgets/CWidgetStatsB.ts b/packages/coreui-vue/src/components/widgets/CWidgetStatsB.ts
similarity index 80%
rename from src/components/widgets/CWidgetStatsB.ts
rename to packages/coreui-vue/src/components/widgets/CWidgetStatsB.ts
index f934647a..1bcd1a0d 100644
--- a/src/components/widgets/CWidgetStatsB.ts
+++ b/packages/coreui-vue/src/components/widgets/CWidgetStatsB.ts
@@ -1,9 +1,10 @@
import { defineComponent, h } from 'vue'
import { shape } from 'vue-types'
-import { Color } from '../props'
-import { CCard, CCardBody } from './../card'
-import { CProgress } from '../progress/CProgress'
+import { CCard, CCardBody } from '../card'
+import { CProgress } from '../progress'
+
+import { Color } from '../../props'
const CWidgetStatsB = defineComponent({
name: 'CWidgetStatsB',
@@ -11,27 +12,22 @@ const CWidgetStatsB = defineComponent({
/**
* Sets the color context of the component to one of CoreUI’s themed colors
*
- * @values 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* Colors have been inverted from their default dark shade.
*/
- inverse: {
- type: Boolean,
- default: undefined,
- require: false,
- },
+ inverse: Boolean,
progress: shape({
/**
* Sets the color context of the progress bar to one of CoreUI’s themed colors
*
- * @values 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* The percent to progress the ProgressBar (out of 100).
- * @default 0
*/
value: {
type: Number,
@@ -41,26 +37,17 @@ const CWidgetStatsB = defineComponent({
/**
* Helper text for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- text: {
- type: String,
- default: undefined,
- require: false,
- },
+ text: String,
/**
* Title for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- title: {
- type: String,
- default: undefined,
- require: false,
- },
+ title: String,
/**
* Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... `
*/
value: {
type: [Number, String],
default: 0,
- require: false,
},
},
setup(props, { slots }) {
@@ -70,7 +57,7 @@ const CWidgetStatsB = defineComponent({
{
class: [
{
- ['text-high-emphasis-inverse']: props.inverse,
+ 'text-high-emphasis-inverse': props.inverse,
},
],
color: props.color,
diff --git a/src/components/widgets/CWidgetStatsC.ts b/packages/coreui-vue/src/components/widgets/CWidgetStatsC.ts
similarity index 84%
rename from src/components/widgets/CWidgetStatsC.ts
rename to packages/coreui-vue/src/components/widgets/CWidgetStatsC.ts
index e20dc3b3..30584383 100644
--- a/src/components/widgets/CWidgetStatsC.ts
+++ b/packages/coreui-vue/src/components/widgets/CWidgetStatsC.ts
@@ -1,37 +1,32 @@
import { defineComponent, h } from 'vue'
import { shape } from 'vue-types'
-import { Color } from '../props'
-import { CCard, CCardBody } from './../card'
+import { Color } from '../../props'
+import { CCard, CCardBody } from '../card'
import { CProgress } from '../progress/CProgress'
const CWidgetStatsC = defineComponent({
name: 'CWidgetStatsC',
props: {
/**
- * Sets the color context of the component to one of CoreUI’s themed colors. [docs]
+ * Sets the color context of the component to one of CoreUI’s themed colors.
*
- * @values 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* Colors have been inverted from their default dark shade.
*/
- inverse: {
- type: Boolean,
- default: undefined,
- require: false,
- },
+ inverse: Boolean,
progress: shape({
/**
* Sets the color context of the progress bar to one of CoreUI’s themed colors
*
- * @values 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
* The percent to progress the ProgressBar (out of 100).
- * @default 0
*/
value: {
type: Number,
@@ -41,18 +36,13 @@ const CWidgetStatsC = defineComponent({
/**
* Title for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- title: {
- type: String,
- default: undefined,
- require: false,
- },
+ title: String,
/**
* Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... `
*/
value: {
type: [Number, String],
default: 0,
- require: false,
},
},
/**
diff --git a/src/components/widgets/CWidgetStatsD.ts b/packages/coreui-vue/src/components/widgets/CWidgetStatsD.ts
similarity index 88%
rename from src/components/widgets/CWidgetStatsD.ts
rename to packages/coreui-vue/src/components/widgets/CWidgetStatsD.ts
index 1ba3d112..894bf592 100644
--- a/src/components/widgets/CWidgetStatsD.ts
+++ b/packages/coreui-vue/src/components/widgets/CWidgetStatsD.ts
@@ -1,8 +1,9 @@
import { defineComponent, h, PropType } from 'vue'
-import { Color } from '../props'
-import { CCard, CCardBody, CCardHeader } from './../card/'
-import { CCol } from './../grid/'
+import { CCard, CCardBody, CCardHeader } from '../card/'
+import { CCol } from '../grid/'
+
+import { Color } from '../../props'
type Value = {
title?: string
@@ -13,9 +14,9 @@ const CWidgetStatsD = defineComponent({
name: 'CWidgetStatsD',
props: {
/**
- * Sets the color context of the component to one of CoreUI’s themed colors. [docs]
+ * Sets the color context of the component to one of CoreUI’s themed colors.
*
- * @values 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
@@ -24,7 +25,6 @@ const CWidgetStatsD = defineComponent({
values: {
type: Array as PropType,
default: () => [],
- require: false,
},
},
/**
diff --git a/src/components/widgets/CWidgetStatsE.ts b/packages/coreui-vue/src/components/widgets/CWidgetStatsE.ts
similarity index 90%
rename from src/components/widgets/CWidgetStatsE.ts
rename to packages/coreui-vue/src/components/widgets/CWidgetStatsE.ts
index 6c02a903..563e41b0 100644
--- a/src/components/widgets/CWidgetStatsE.ts
+++ b/packages/coreui-vue/src/components/widgets/CWidgetStatsE.ts
@@ -1,6 +1,6 @@
import { defineComponent, h } from 'vue'
-import { CCard, CCardBody } from './../card/'
+import { CCard, CCardBody } from '../card/'
const CWidgetStatsE = defineComponent({
name: 'CWidgetStatsE',
@@ -8,18 +8,13 @@ const CWidgetStatsE = defineComponent({
/**
* Title for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- title: {
- type: String,
- default: undefined,
- require: false,
- },
+ title: String,
/**
* Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... `
*/
value: {
type: [Number, String],
default: 0,
- require: false,
},
},
/**
diff --git a/src/components/widgets/CWidgetStatsF.ts b/packages/coreui-vue/src/components/widgets/CWidgetStatsF.ts
similarity index 84%
rename from src/components/widgets/CWidgetStatsF.ts
rename to packages/coreui-vue/src/components/widgets/CWidgetStatsF.ts
index 074060dd..8c4db082 100644
--- a/src/components/widgets/CWidgetStatsF.ts
+++ b/packages/coreui-vue/src/components/widgets/CWidgetStatsF.ts
@@ -1,19 +1,20 @@
import { defineComponent, h } from 'vue'
-import { Color } from '../props'
-import { CCard, CCardBody, CCardFooter } from './../card/'
+import { CCard, CCardBody, CCardFooter } from '../card/'
+
+import { Color } from '../../props'
const CWidgetStatsF = defineComponent({
name: 'CWidgetStatsF',
props: {
/**
- * Sets the color context of the component to one of CoreUI’s themed colors. [docs]
+ * Sets the color context of the component to one of CoreUI’s themed colors.
*
- * @values 'primary' | 'secondary' | 'success' | 'danger' | 'warning' | 'info' | 'dark' | 'light' | string
+ * @values 'primary', 'secondary', 'success', 'danger', 'warning', 'info', 'dark', 'light'
*/
color: Color,
/**
- * Set padding of your component. [docs]
+ * Set padding of your component.
*/
padding: {
type: Boolean,
@@ -22,26 +23,17 @@ const CWidgetStatsF = defineComponent({
/**
* Title for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- title: {
- type: String,
- default: undefined,
- require: false,
- },
+ title: String,
/**
* Helper text for your component. If you want to pass non-string value please use dedicated slot `... `
*/
- text: {
- type: String,
- default: undefined,
- require: false,
- },
+ text: String,
/**
* Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... `
*/
value: {
type: [Number, String],
default: 0,
- require: false,
},
},
/**
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsA.spec.ts b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsA.spec.ts
new file mode 100644
index 00000000..a3218baf
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsA.spec.ts
@@ -0,0 +1,26 @@
+import { mount } from '@vue/test-utils'
+import { CWidgetStatsA as Component } from '../../../index'
+
+const ComponentName = 'CWidgetStatsA'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ title: 'title',
+ value: 75,
+ },
+ slots: {
+ action: 'action',
+ chart: 'chart',
+ default: 'Default slot',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsB.spec.ts b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsB.spec.ts
new file mode 100644
index 00000000..8ef63d6a
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsB.spec.ts
@@ -0,0 +1,28 @@
+import { mount } from '@vue/test-utils'
+import { CWidgetStatsB as Component } from '../../../index'
+
+const ComponentName = 'CWidgetStatsB'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ inverse: true,
+ progress: {
+ color: 'info',
+ value: 75,
+ },
+ text: 'text',
+ title: 'title',
+ value: 75,
+ },
+ slots: {},
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsC.spec.ts b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsC.spec.ts
new file mode 100644
index 00000000..eb2374e1
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsC.spec.ts
@@ -0,0 +1,29 @@
+import { mount } from '@vue/test-utils'
+import { CWidgetStatsC as Component } from '../../../index'
+
+const ComponentName = 'CWidgetStatsC'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ inverse: true,
+ progress: {
+ color: 'info',
+ value: 75,
+ },
+ title: 'title',
+ value: 75,
+ },
+ slots: {
+ icon: 'icon',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsD.spec.ts b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsD.spec.ts
new file mode 100644
index 00000000..93101c67
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsD.spec.ts
@@ -0,0 +1,27 @@
+import { mount } from '@vue/test-utils'
+import { CWidgetStatsD as Component } from '../../../index'
+
+const ComponentName = 'CWidgetStatsD'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ values: [
+ { title: 'aa', value: 'bb' },
+ { title: 'cc', value: 'dd' },
+ ],
+ },
+ slots: {
+ icon: 'icon',
+ chart: 'chart',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsE.spec.ts b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsE.spec.ts
new file mode 100644
index 00000000..21090b6b
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsE.spec.ts
@@ -0,0 +1,24 @@
+import { mount } from '@vue/test-utils'
+import { CWidgetStatsE as Component } from '../../../index'
+
+const ComponentName = 'CWidgetStatsE'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ title: 'title',
+ value: 'value',
+ },
+ slots: {
+ chart: 'chart',
+ default: 'default',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsF.spec.ts b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsF.spec.ts
new file mode 100644
index 00000000..e2eb8ce5
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/CWidgetStatsF.spec.ts
@@ -0,0 +1,28 @@
+import { mount } from '@vue/test-utils'
+import { CWidgetStatsF as Component } from '../../../index'
+
+const ComponentName = 'CWidgetStatsF'
+
+const defaultWrapper = mount(Component, {
+ propsData: {
+ color: 'warning',
+ padding: true,
+ title: 'title',
+ text: 'text',
+ value: 75,
+ },
+ slots: {
+ icon: 'icon',
+ default: 'default',
+ footer: 'footer',
+ },
+})
+
+describe(`Loads and display ${ComponentName} component`, () => {
+ it('has a name', () => {
+ expect(Component.name).toMatch(ComponentName)
+ })
+ it('renders correctly', () => {
+ expect(defaultWrapper.html()).toMatchSnapshot()
+ })
+})
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.ts.snap b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.ts.snap
new file mode 100644
index 00000000..c8e5f776
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsA.spec.ts.snap
@@ -0,0 +1,12 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CWidgetStatsA component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.ts.snap b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.ts.snap
new file mode 100644
index 00000000..33f7850e
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsB.spec.ts.snap
@@ -0,0 +1,13 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CWidgetStatsB component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.ts.snap b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.ts.snap
new file mode 100644
index 00000000..8793d1ec
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsC.spec.ts.snap
@@ -0,0 +1,14 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CWidgetStatsC component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.ts.snap b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.ts.snap
new file mode 100644
index 00000000..77bab6a7
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsD.spec.ts.snap
@@ -0,0 +1,19 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CWidgetStatsD component renders correctly 1`] = `
+""
+`;
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.ts.snap b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.ts.snap
new file mode 100644
index 00000000..c1c85e62
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsE.spec.ts.snap
@@ -0,0 +1,10 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CWidgetStatsE component renders correctly 1`] = `
+"
+
+
title
+
value
chartdefault
+
+
"
+`;
diff --git a/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.ts.snap b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.ts.snap
new file mode 100644
index 00000000..81b9aa42
--- /dev/null
+++ b/packages/coreui-vue/src/components/widgets/__tests__/__snapshots__/CWidgetStatsF.spec.ts.snap
@@ -0,0 +1,14 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Loads and display CWidgetStatsF component renders correctly 1`] = `
+""
+`;
diff --git a/src/components/widgets/index.ts b/packages/coreui-vue/src/components/widgets/index.ts
similarity index 100%
rename from src/components/widgets/index.ts
rename to packages/coreui-vue/src/components/widgets/index.ts
diff --git a/packages/coreui-vue/src/composables/index.ts b/packages/coreui-vue/src/composables/index.ts
new file mode 100644
index 00000000..e45a266d
--- /dev/null
+++ b/packages/coreui-vue/src/composables/index.ts
@@ -0,0 +1,3 @@
+import { usePopper } from './usePopper'
+
+export { usePopper }
diff --git a/packages/coreui-vue/src/composables/usePopper.ts b/packages/coreui-vue/src/composables/usePopper.ts
new file mode 100644
index 00000000..23bba6d5
--- /dev/null
+++ b/packages/coreui-vue/src/composables/usePopper.ts
@@ -0,0 +1,25 @@
+import { ref } from 'vue'
+import { createPopper } from '@popperjs/core'
+import type { Instance, Options } from '@popperjs/core'
+
+export const usePopper = () => {
+ const _popper = ref()
+
+ const initPopper = (reference: HTMLElement, popper: HTMLElement, options: Partial) => {
+ _popper.value = createPopper(reference, popper, options)
+ }
+
+ const destroyPopper = () => {
+ if (_popper.value) {
+ _popper.value.destroy()
+ }
+
+ _popper.value = undefined
+ }
+
+ return {
+ popper: _popper.value,
+ initPopper,
+ destroyPopper,
+ }
+}
diff --git a/packages/coreui-vue/src/directives/index.ts b/packages/coreui-vue/src/directives/index.ts
new file mode 100644
index 00000000..1ee9a52b
--- /dev/null
+++ b/packages/coreui-vue/src/directives/index.ts
@@ -0,0 +1,5 @@
+import vcplaceholder from './v-c-placeholder'
+import vcpopover from './v-c-popover'
+import vctooltip from './v-c-tooltip'
+
+export { vcplaceholder, vcpopover, vctooltip }
diff --git a/packages/coreui-vue/src/directives/v-c-placeholder.ts b/packages/coreui-vue/src/directives/v-c-placeholder.ts
new file mode 100644
index 00000000..fcfe23b3
--- /dev/null
+++ b/packages/coreui-vue/src/directives/v-c-placeholder.ts
@@ -0,0 +1,32 @@
+import { DirectiveBinding } from 'vue'
+
+const BREAKPOINTS = [
+ 'xxl' as const,
+ 'xl' as const,
+ 'lg' as const,
+ 'md' as const,
+ 'sm' as const,
+ 'xs' as const,
+]
+
+export default {
+ name: 'c-placeholder',
+ mounted(el: HTMLElement, binding: DirectiveBinding): void {
+ const value = binding.value
+ el.classList.add(value.animation ? `placeholder-${value.animation}` : 'placeholder')
+
+ BREAKPOINTS.forEach((bp) => {
+ const breakpoint = value[bp]
+
+ const infix = bp === 'xs' ? '' : `-${bp}`
+
+ if (typeof breakpoint === 'number') {
+ el.classList.add(`col${infix}-${breakpoint}`)
+ }
+
+ if (typeof breakpoint === 'boolean') {
+ el.classList.add(`col${infix}`)
+ }
+ })
+ },
+}
diff --git a/src/directives/CPopover.ts b/packages/coreui-vue/src/directives/v-c-popover.ts
similarity index 78%
rename from src/directives/CPopover.ts
rename to packages/coreui-vue/src/directives/v-c-popover.ts
index 33bf0146..49d6d0f8 100644
--- a/src/directives/CPopover.ts
+++ b/packages/coreui-vue/src/directives/v-c-popover.ts
@@ -1,12 +1,7 @@
+import { DirectiveBinding } from 'vue'
import { createPopper } from '@popperjs/core'
-const getUID = (prefix: string) => {
- do {
- prefix += Math.floor(Math.random() * 1000000)
- } while (document.getElementById(prefix))
-
- return prefix
-}
+import { getUID } from '../utils'
const createPopoverElement = (id: string, header: string, content: string): HTMLDivElement => {
const popover = document.createElement('div')
@@ -19,6 +14,7 @@ const createPopoverElement = (id: string, header: string, content: string): HTML
return popover
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
const addPopoverElement = (popover: HTMLDivElement, el: HTMLElement, popperOptions: any) => {
document.body.appendChild(popover)
createPopper(el, popover, popperOptions)
@@ -30,10 +26,11 @@ const addPopoverElement = (popover: HTMLDivElement, el: HTMLElement, popperOptio
const removePopoverElement = (popover: HTMLDivElement) => {
popover.classList.remove('show')
setTimeout(() => {
- document.body.removeChild(popover)
+ popover.remove()
}, 300)
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
const togglePopoverElement = (popover: HTMLDivElement, el: HTMLElement, popperOptions: any) => {
const popperElement = document.getElementById(popover.id)
if (popperElement && popperElement.classList.contains('show')) {
@@ -43,18 +40,18 @@ const togglePopoverElement = (popover: HTMLDivElement, el: HTMLElement, popperOp
addPopoverElement(popover, el, popperOptions)
}
-const CPopover = {
+export default {
name: 'c-popover',
uid: '',
- mounted(el: HTMLElement, binding: any) {
+ mounted(el: HTMLElement, binding: DirectiveBinding): void {
const value = binding.value
- const content = typeof value === 'string' ? value : value.content ? value.content : ''
- const header = value.header ? value.header : ''
- const trigger = value.trigger ? value.trigger : 'click'
+ const content = typeof value === 'string' ? value : value.content ?? ''
+ const header = value.header ?? ''
+ const trigger = value.trigger ?? 'click'
// Popper Config
- const offset = value.offset ? value.offset : [0, 8]
- const placement = value.placement ? value.placement : 'top'
+ const offset = value.offset ?? [0, 8]
+ const placement = value.placement ?? 'top'
const popperOptions = {
placement: placement,
@@ -69,7 +66,7 @@ const CPopover = {
}
const popoverUID = getUID('popover')
- binding.dir.uid = popoverUID
+ binding.arg = popoverUID
const popover = createPopoverElement(popoverUID, header, content)
trigger.includes('click') &&
@@ -95,10 +92,8 @@ const CPopover = {
})
}
},
- unmounted(binding: any) {
- const popover = document.getElementById(binding.dir.uid)
+ unmounted(_el: HTMLElement, binding: DirectiveBinding): void {
+ const popover = binding.arg && document.getElementById(binding.arg)
popover && popover.remove()
},
}
-
-export { CPopover }
diff --git a/src/directives/CTooltip.ts b/packages/coreui-vue/src/directives/v-c-tooltip.ts
similarity index 78%
rename from src/directives/CTooltip.ts
rename to packages/coreui-vue/src/directives/v-c-tooltip.ts
index 8c032f48..20b0c09d 100644
--- a/src/directives/CTooltip.ts
+++ b/packages/coreui-vue/src/directives/v-c-tooltip.ts
@@ -1,12 +1,7 @@
+import { DirectiveBinding } from 'vue'
import { createPopper } from '@popperjs/core'
-const getUID = (prefix: string) => {
- do {
- prefix += Math.floor(Math.random() * 1000000)
- } while (document.getElementById(prefix))
-
- return prefix
-}
+import { getUID } from '../utils'
const createTooltipElement = (id: string, content: string): HTMLDivElement => {
const tooltip = document.createElement('div')
@@ -18,6 +13,7 @@ const createTooltipElement = (id: string, content: string): HTMLDivElement => {
return tooltip
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
const addTooltipElement = (tooltip: HTMLDivElement, el: HTMLElement, popperOptions: any) => {
document.body.appendChild(tooltip)
createPopper(el, tooltip, popperOptions)
@@ -29,10 +25,11 @@ const addTooltipElement = (tooltip: HTMLDivElement, el: HTMLElement, popperOptio
const removeTooltipElement = (tooltip: HTMLDivElement) => {
tooltip.classList.remove('show')
setTimeout(() => {
- document.body.removeChild(tooltip)
+ tooltip.remove()
}, 300)
}
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
const toggleTooltipElement = (tooltip: HTMLDivElement, el: HTMLElement, popperOptions: any) => {
const popperElement = document.getElementById(tooltip.id)
if (popperElement && popperElement.classList.contains('show')) {
@@ -42,17 +39,16 @@ const toggleTooltipElement = (tooltip: HTMLDivElement, el: HTMLElement, popperOp
addTooltipElement(tooltip, el, popperOptions)
}
-const CTooltip = {
+export default {
name: 'c-tooltip',
- uid: '',
- mounted(el: HTMLElement, binding: any) {
+ mounted(el: HTMLElement, binding: DirectiveBinding): void {
const value = binding.value
- const content = typeof value === 'string' ? value : value.content ? value.content : ''
- const trigger = value.trigger ? value.trigger : 'hover'
+ const content = typeof value === 'string' ? value : value.content ?? ''
+ const trigger = value.trigger ?? 'hover'
// Popper Config
- const offset = value.offset ? value.offset : [0, 0]
- const placement = value.placement ? value.placement : 'top'
+ const offset = value.offset ?? [0, 6]
+ const placement = value.placement ?? 'top'
const popperOptions = {
placement: placement,
@@ -67,7 +63,7 @@ const CTooltip = {
}
const tooltipUID = getUID('tooltip')
- binding.dir.uid = tooltipUID
+ binding.arg = tooltipUID
const tooltip = createTooltipElement(tooltipUID, content)
trigger.includes('click') &&
@@ -93,10 +89,8 @@ const CTooltip = {
})
}
},
- unmounted(binding: any) {
- const tooltip = document.getElementById(binding.dir.uid)
+ beforeUnmount(_el: HTMLElement, binding: DirectiveBinding): void {
+ const tooltip = binding.arg && document.getElementById(binding.arg)
tooltip && tooltip.remove()
},
}
-
-export { CTooltip }
diff --git a/packages/coreui-vue/src/directives/v-c-visible.ts b/packages/coreui-vue/src/directives/v-c-visible.ts
new file mode 100644
index 00000000..50c27869
--- /dev/null
+++ b/packages/coreui-vue/src/directives/v-c-visible.ts
@@ -0,0 +1,33 @@
+import { ObjectDirective } from 'vue'
+
+interface VShowElement extends HTMLElement {
+ // _vod = vue original display
+ _vod: string
+}
+
+export const vVisible: ObjectDirective = {
+ beforeMount(el, { value }, { transition }) {
+ el._vod = el.style.display === 'none' ? '' : el.style.display
+ if (transition && value) {
+ transition.beforeEnter(el)
+ }
+ },
+ mounted(el, { value }, { transition }) {
+ if (transition && value) {
+ transition.enter(el)
+ }
+ },
+ updated(el, { value, oldValue }, { transition }) {
+ if (!value === !oldValue) return
+ if (transition) {
+ if (value) {
+ transition.beforeEnter(el)
+ transition.enter(el)
+ } else {
+ transition.leave(el, () => {
+ // setDisplay(el, false)
+ })
+ }
+ }
+ },
+}
diff --git a/packages/coreui-vue/src/index.ts b/packages/coreui-vue/src/index.ts
new file mode 100644
index 00000000..262ecc6b
--- /dev/null
+++ b/packages/coreui-vue/src/index.ts
@@ -0,0 +1,23 @@
+import { App } from 'vue'
+import * as Components from './components'
+import * as Directives from './directives'
+
+const CoreuiVue = {
+ install: (app: App): void => {
+ for (const key in Components) {
+ app.component(key, Components[key])
+ }
+
+ for (const key in Directives) {
+ app.directive(Directives[key]['name'], Directives[key])
+ }
+ },
+}
+
+// Export library
+export default CoreuiVue
+
+// Export components & directives
+export * from './components'
+export * from './composables'
+export * from './directives'
diff --git a/src/components/props.ts b/packages/coreui-vue/src/props.ts
similarity index 76%
rename from src/components/props.ts
rename to packages/coreui-vue/src/props.ts
index 0ba4cb47..667186d5 100644
--- a/src/components/props.ts
+++ b/packages/coreui-vue/src/props.ts
@@ -1,4 +1,4 @@
-const Shape = {
+export const Shape = {
type: String,
validator: (value: string): boolean => {
// The value must match one of these strings
@@ -17,14 +17,16 @@ const Shape = {
].includes(value)
},
}
-const Align = {
+
+export const Align = {
type: String,
validator: (value: string): boolean => {
// The value must match one of these strings
return ['', 'left', 'center', 'right'].includes(value)
},
}
-const Color = {
+
+export const Color = {
type: String,
validator: (value: string): boolean => {
// The value must match one of these strings
@@ -42,7 +44,8 @@ const Color = {
].includes(value)
},
}
-const TextColor = {
+
+export const TextColor = {
type: String,
validator: (value: string): boolean => {
return [
@@ -56,17 +59,18 @@ const TextColor = {
'light',
'white',
'muted',
+ 'high-emphasis',
+ 'medium-emphasis',
+ 'disabled',
+ 'high-emphasis-inverse',
+ 'medium-emphasis-inverse',
+ 'disabled-inverse',
].includes(value)
},
}
-const Breakpoint = {
+
+export const Breakpoint = {
validator: (value: boolean | number): boolean => {
- if (typeof value == 'boolean' || typeof value == 'number') {
- return true
- } else {
- return false
- }
+ return typeof value == 'boolean' || typeof value == 'number' ? true : false
},
}
-
-export { Align, Breakpoint, Color, Shape, TextColor }
diff --git a/src/shims-vue.d.ts b/packages/coreui-vue/src/shims-vue.d.ts
similarity index 100%
rename from src/shims-vue.d.ts
rename to packages/coreui-vue/src/shims-vue.d.ts
diff --git a/src/components/Types.tsx b/packages/coreui-vue/src/types.ts
similarity index 98%
rename from src/components/Types.tsx
rename to packages/coreui-vue/src/types.ts
index 53ae107f..b229df7c 100644
--- a/src/components/Types.tsx
+++ b/packages/coreui-vue/src/types.ts
@@ -27,7 +27,7 @@ export type Placements =
| 'left-start'
| 'left'
| 'left-end'
- | undefined
+ | string
export type Shapes =
| 'rounded'
diff --git a/packages/coreui-vue/src/utils/getRTLPlacement.ts b/packages/coreui-vue/src/utils/getRTLPlacement.ts
new file mode 100644
index 00000000..87c38517
--- /dev/null
+++ b/packages/coreui-vue/src/utils/getRTLPlacement.ts
@@ -0,0 +1,18 @@
+import { Placement } from '@popperjs/core'
+import isRTL from './isRTL'
+
+const getRTLPlacement = (placement: string, element: HTMLDivElement | null): Placement => {
+ switch (placement) {
+ case 'right': {
+ return isRTL(element) ? 'left' : 'right'
+ }
+ case 'left': {
+ return isRTL(element) ? 'right' : 'left'
+ }
+ default: {
+ return placement as Placement
+ }
+ }
+}
+
+export default getRTLPlacement
diff --git a/packages/coreui-vue/src/utils/getUID.ts b/packages/coreui-vue/src/utils/getUID.ts
new file mode 100644
index 00000000..7aeb1b76
--- /dev/null
+++ b/packages/coreui-vue/src/utils/getUID.ts
@@ -0,0 +1,9 @@
+const getUID = (prefix: string) => {
+ do {
+ prefix += Math.floor(Math.random() * 1_000_000)
+ } while (document.getElementById(prefix))
+
+ return prefix
+}
+
+export default getUID
diff --git a/packages/coreui-vue/src/utils/index.ts b/packages/coreui-vue/src/utils/index.ts
new file mode 100644
index 00000000..2bd39724
--- /dev/null
+++ b/packages/coreui-vue/src/utils/index.ts
@@ -0,0 +1,6 @@
+import getRTLPlacement from './getRTLPlacement'
+import getUID from './getUID'
+import isInViewport from './isInViewport'
+import isRTL from './isRTL'
+
+export { getRTLPlacement, getUID, isInViewport, isRTL }
diff --git a/packages/coreui-vue/src/utils/isInViewport.ts b/packages/coreui-vue/src/utils/isInViewport.ts
new file mode 100644
index 00000000..7aae5391
--- /dev/null
+++ b/packages/coreui-vue/src/utils/isInViewport.ts
@@ -0,0 +1,11 @@
+const isInViewport = (element: HTMLElement) => {
+ const rect = element.getBoundingClientRect()
+ return (
+ Math.floor(rect.top) >= 0 &&
+ Math.floor(rect.left) >= 0 &&
+ Math.floor(rect.bottom) <= (window.innerHeight || document.documentElement.clientHeight) &&
+ Math.floor(rect.right) <= (window.innerWidth || document.documentElement.clientWidth)
+ )
+}
+
+export default isInViewport
diff --git a/packages/coreui-vue/src/utils/isRTL.ts b/packages/coreui-vue/src/utils/isRTL.ts
new file mode 100644
index 00000000..17180d80
--- /dev/null
+++ b/packages/coreui-vue/src/utils/isRTL.ts
@@ -0,0 +1,13 @@
+const isRTL = (element?: HTMLElement | HTMLDivElement | null) => {
+ if (typeof document !== 'undefined' && document.documentElement.dir === 'rtl') {
+ return true
+ }
+
+ if (element) {
+ return element.closest('[dir="rtl"]') !== null
+ }
+
+ return false
+}
+
+export default isRTL
diff --git a/packages/coreui-vue/src/utils/transition.ts b/packages/coreui-vue/src/utils/transition.ts
new file mode 100644
index 00000000..874fbf8c
--- /dev/null
+++ b/packages/coreui-vue/src/utils/transition.ts
@@ -0,0 +1,65 @@
+const execute = (callback: () => void) => {
+ if (typeof callback === 'function') {
+ callback()
+ }
+}
+
+export const executeAfterTransition = (
+ callback: () => void,
+ transitionElement: HTMLElement,
+ waitForTransition = true,
+) => {
+ if (!waitForTransition) {
+ execute(callback)
+ return
+ }
+
+ const durationPadding = 5
+ const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding
+
+ let called = false
+
+ const handler = ({ target }: { target: any }) => {
+ if (target !== transitionElement) {
+ return
+ }
+
+ called = true
+ transitionElement.removeEventListener('transitionend', handler)
+ execute(callback)
+ }
+
+ transitionElement.addEventListener('transitionend', handler)
+ setTimeout(() => {
+ if (!called) {
+ triggerTransitionEnd(transitionElement)
+ }
+ }, emulatedDuration)
+}
+
+export const getTransitionDurationFromElement = (element: HTMLElement) => {
+ if (!element) {
+ return 0
+ }
+
+ // Get transition-duration of the element
+ let { transitionDuration, transitionDelay } = window.getComputedStyle(element)
+
+ const floatTransitionDuration = Number.parseFloat(transitionDuration)
+ const floatTransitionDelay = Number.parseFloat(transitionDelay)
+
+ // Return 0 if element or transition duration is not found
+ if (!floatTransitionDuration && !floatTransitionDelay) {
+ return 0
+ }
+
+ // If multiple durations are defined, take the first
+ transitionDuration = transitionDuration.split(',')[0]
+ transitionDelay = transitionDelay.split(',')[0]
+
+ return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * 1000
+}
+
+export const triggerTransitionEnd = (element: HTMLElement) => {
+ element.dispatchEvent(new Event('transitionend'))
+}
diff --git a/packages/coreui-vue/tsconfig.json b/packages/coreui-vue/tsconfig.json
new file mode 100644
index 00000000..37245843
--- /dev/null
+++ b/packages/coreui-vue/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "extends": "../../tsconfig",
+ "compilerOptions": {
+ "declarationDir": "."
+ },
+ "include": ["src/**/*"]
+}
\ No newline at end of file
diff --git a/packages/docs/.vuepress/client.ts b/packages/docs/.vuepress/client.ts
new file mode 100644
index 00000000..a793a702
--- /dev/null
+++ b/packages/docs/.vuepress/client.ts
@@ -0,0 +1,72 @@
+import { defineClientConfig } from '@vuepress/client'
+import { CIcon } from '@coreui/icons-vue'
+import CChartPlugin from '@coreui/vue-chartjs'
+import CoreuiVue from '@coreui/vue/src/'
+import '@coreui/coreui/scss/coreui.scss'
+import '@coreui/chartjs/scss/coreui-chartjs.scss'
+
+import {
+ cibCoreuiC,
+ cibDiscourse,
+ cibGithub,
+ cibTwitter,
+ cibOpenCollective,
+ cilArrowBottom,
+ cilArrowRight,
+ cilArrowTop,
+ cilBasket,
+ cilBurn,
+ cilCheckCircle,
+ cilCloudDownload,
+ cilContrast,
+ cilHandshake,
+ cilInfo,
+ cilMenu,
+ cilMoon,
+ cilOptions,
+ cilPeople,
+ cilPuzzle,
+ cilSettings,
+ cilSpeedometer,
+ cilSun,
+ cilUserFollow,
+ cilWarning,
+} from '@coreui/icons'
+
+export const icons = {
+ cibCoreuiC,
+ cibDiscourse,
+ cibGithub,
+ cibTwitter,
+ cibOpenCollective,
+ cilArrowBottom,
+ cilArrowRight,
+ cilArrowTop,
+ cilBasket,
+ cilBurn,
+ cilCheckCircle,
+ cilCloudDownload,
+ cilContrast,
+ cilHandshake,
+ cilInfo,
+ cilMenu,
+ cilMoon,
+ cilOptions,
+ cilPeople,
+ cilPuzzle,
+ cilSettings,
+ cilSpeedometer,
+ cilSun,
+ cilUserFollow,
+ cilWarning,
+}
+
+export default defineClientConfig({
+ enhance({ app, router }) {
+ app.use(CoreuiVue)
+ app.provide('icons', icons)
+ app.component('CIcon', CIcon)
+ app.use(CChartPlugin),
+ router.addRoute({ path: '', redirect: '/getting-started/introduction.html' })
+ },
+})
diff --git a/docs/.vuepress/config.ts b/packages/docs/.vuepress/config.ts
similarity index 52%
rename from docs/.vuepress/config.ts
rename to packages/docs/.vuepress/config.ts
index 404ab258..ddf717dd 100644
--- a/docs/.vuepress/config.ts
+++ b/packages/docs/.vuepress/config.ts
@@ -1,73 +1,79 @@
import { defineUserConfig } from 'vuepress'
-import type { DefaultThemeOptions } from 'vuepress'
-import { permalink } from 'markdown-it-anchor'
-import pkg from '../../package.json'
+import anchor from 'markdown-it-anchor'
+import include_plugin from 'markdown-it-include'
+import { defaultTheme } from './theme-coreui'
-// const md = require('markdown-it')()
-const path = require('path')
+import { containerPlugin } from '@vuepress/plugin-container'
+import { registerComponentsPlugin } from '@vuepress/plugin-register-components'
+import { tocPlugin } from '@vuepress/plugin-toc'
+import { getDirname, path } from '@vuepress/utils'
-export default defineUserConfig({
- base: `/vue/docs/${pkg.config.version_short}/`,
+const __dirname = getDirname(import.meta.url)
+
+export default defineUserConfig({
+ base: `/vue/docs/`,
lang: 'en-US',
- title: 'CoreUI for Vue.js',
+ title: 'Vue UI Components · CoreUI',
description: 'UI Components Library for Vue.js (Vue 3)',
head: [
- // ['link', { rel: 'icon', href: '/logo.png' }],
- ['link', { rel: 'manifest', href: '/favicon/manifest.json' }],
- // ['meta', { name: 'theme-color', content: '#3eaf7c' }],
- // ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
- // ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
- // ['link', { rel: 'apple-touch-icon', href: '/icons/apple-touch-icon-152x152.png' }],
- // ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
- // ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
- // ['meta', { name: 'msapplication-TileColor', content: '#000000' }],
- ['script', { src: 'https://media.ethicalads.io/media/client/ethicalads.min.js' }],
+ ['link', { rel: 'icon', href: `/vue/docs/favicons/favicon-96x96.png` }],
],
- extendsMarkdown: (md) => {
- md.use(require('markdown-it-include')),
- (md.renderer.rules.table_open = function (tokens, idx) {
- return ''
- })
- },
markdown: {
anchor: {
- permalink: permalink.ariaHidden({
+ permalink: anchor.permalink.ariaHidden({
class: 'anchor-link',
placement: 'after'
})
},
+ code: {
+ lineNumbers: false,
+ },
+ },
+ extendsMarkdown: (md) => {
+ md.use(include_plugin),
+ (md.renderer.rules.table_open = function (tokens, idx) {
+ return ''
+ })
},
plugins: [
- '@vuepress/plugin-toc',
- [
- '@vuepress/container',
- {
- type: 'demo',
- render: function (tokens, idx) {
- if (tokens[idx].nesting === 1) {
- return '\n'
- } else {
- return '
\n'
- }
- },
+ containerPlugin({
+ type: 'demo',
+ render: function (tokens, idx) {
+ if (tokens[idx].nesting === 1) {
+ return '\n'
+ } else {
+ return '
\n'
+ }
},
- ],
- [
- '@vuepress/container',
- {
- type: 'demo-dark',
- render: function (tokens, idx) {
- if (tokens[idx].nesting === 1) {
- return '\n'
- } else {
- return '
\n'
- }
- },
+ }),
+ containerPlugin({
+ type: 'demo-rounded',
+ render: function (tokens, idx) {
+ if (tokens[idx].nesting === 1) {
+ return '\n'
+ } else {
+ return '
\n'
+ }
},
- ],
+ }),
+ containerPlugin({
+ type: 'demo-dark',
+ render: function (tokens, idx) {
+ if (tokens[idx].nesting === 1) {
+ return '\n'
+ } else {
+ return '
\n'
+ }
+ },
+ }),
+ tocPlugin({}),
+ registerComponentsPlugin({
+ components: {
+ ScssDocs: path.resolve(__dirname, './theme-coreui/src/client/components/ScssDocs.vue'),
+ },
+ }),
],
- theme: path.resolve(__dirname, './theme-coreui'),
- themeConfig: {
+ theme: defaultTheme({
sidebar: [
{
text: 'Getting started',
@@ -78,6 +84,29 @@ export default defineUserConfig({
text: 'Introduction',
link: `/getting-started/introduction.html`,
},
+ {
+ text: 'Accessibility',
+ link: `/getting-started/accessibility.html`,
+ },
+ ],
+ },
+ {
+ text: 'Customize',
+ icon: ' ',
+ link: '/customize/',
+ children: [
+ {
+ text: 'Sass',
+ link: '/customize/sass.html',
+ },
+ {
+ text: 'Options',
+ link: '/customize/options.html',
+ },
+ {
+ text: 'CSS Variables',
+ link: '/customize/css-variables.html',
+ },
],
},
{
@@ -113,32 +142,40 @@ export default defineUserConfig({
link: `/forms/`,
children: [
{
- text: 'Overview',
- link: `/forms/overview.html`,
+ text: 'Checkbox',
+ link: `/forms/checkbox.html`,
},
{
- text: 'Form control',
- link: `/forms/form-control.html`,
+ text: 'Input',
+ link: `/forms/input.html`,
},
{
- text: 'Select',
- link: `/forms/select.html`,
+ text: 'Input group',
+ link: `/forms/input-group.html`,
},
{
- text: 'Checks & radios',
- link: `/forms/checks-radios.html`,
+ text: 'Radio',
+ link: `/forms/radio.html`,
},
{
text: 'Range',
link: `/forms/range.html`,
},
{
- text: 'Floating labels',
- link: `/forms/floating-labels.html`,
+ text: 'Select',
+ link: `/forms/select.html`,
},
{
- text: 'Input group',
- link: `/forms/input-group.html`,
+ text: 'Switch',
+ link: `/forms/switch.html`,
+ },
+ {
+ text: 'Textarea',
+ link: `/forms/textarea.html`,
+ },
+ {
+ text: 'Floating labels',
+ link: `/forms/floating-labels.html`,
},
{
text: 'Layout',
@@ -195,6 +232,10 @@ export default defineUserConfig({
text: 'Carousel',
link: `/components/carousel.html`,
},
+ {
+ text: 'Chart',
+ link: `/components/chart.html`,
+ },
{
text: 'Close Button',
link: `/components/close-button.html`,
@@ -215,6 +256,10 @@ export default defineUserConfig({
text: 'Header',
link: `/components/header.html`,
},
+ {
+ text: 'Icon',
+ link: `/components/icon.html`,
+ },
{
text: 'Image',
link: `/components/image.html`,
@@ -228,8 +273,8 @@ export default defineUserConfig({
link: `/components/modal.html`,
},
{
- text: 'Nav',
- link: `/components/nav.html`,
+ text: 'Navs & Tabs',
+ link: `/components/navs-tabs.html`,
},
{
text: 'Navbar',
@@ -244,13 +289,8 @@ export default defineUserConfig({
link: `/components/pagination.html`,
},
{
- text: 'Placeholders',
- link: `/components/placeholders.html`,
- disabled: true,
- badge: {
- color: 'warning',
- text: 'WIP v4.1',
- }
+ text: 'Placeholder',
+ link: `/components/placeholder.html`,
},
{
text: 'Popover',
@@ -286,6 +326,48 @@ export default defineUserConfig({
},
],
},
+ {
+ text: 'Templates',
+ link: '/templates/',
+ icon: ' ',
+ children: [
+ {
+ text: 'Admin & Dashboard',
+ link: '/templates/admin-dashboard.html',
+ badge: {
+ color: 'success',
+ text: 'New',
+ },
+ },
+ {
+ text: 'Download',
+ link: '/templates/download.html',
+ },
+ {
+ text: 'Installation',
+ link: '/templates/installation.html',
+ },
+ {
+ text: 'Customize',
+ link: '/templates/customize.html',
+ },
+ {
+ text: 'Contents',
+ link: '/templates/contents.html',
+ },
+ ],
+ },
+ {
+ text: 'Migration',
+ link: '/migration/',
+ icon: ' ',
+ children: [
+ {
+ text: 'v4',
+ link: '/migration/v4.html',
+ },
+ ],
+ },
],
- },
+ }),
})
diff --git a/docs/.vuepress/public/brand/coreui-react.svg b/packages/docs/.vuepress/public/brand/coreui-react.svg
similarity index 100%
rename from docs/.vuepress/public/brand/coreui-react.svg
rename to packages/docs/.vuepress/public/brand/coreui-react.svg
diff --git a/docs/.vuepress/public/favicon.ico b/packages/docs/.vuepress/public/favicon.ico
similarity index 100%
rename from docs/.vuepress/public/favicon.ico
rename to packages/docs/.vuepress/public/favicon.ico
diff --git a/docs/.vuepress/public/favicons/android-icon-144x144.png b/packages/docs/.vuepress/public/favicons/android-icon-144x144.png
similarity index 100%
rename from docs/.vuepress/public/favicons/android-icon-144x144.png
rename to packages/docs/.vuepress/public/favicons/android-icon-144x144.png
diff --git a/docs/.vuepress/public/favicons/android-icon-192x192.png b/packages/docs/.vuepress/public/favicons/android-icon-192x192.png
similarity index 100%
rename from docs/.vuepress/public/favicons/android-icon-192x192.png
rename to packages/docs/.vuepress/public/favicons/android-icon-192x192.png
diff --git a/docs/.vuepress/public/favicons/android-icon-36x36.png b/packages/docs/.vuepress/public/favicons/android-icon-36x36.png
similarity index 100%
rename from docs/.vuepress/public/favicons/android-icon-36x36.png
rename to packages/docs/.vuepress/public/favicons/android-icon-36x36.png
diff --git a/docs/.vuepress/public/favicons/android-icon-48x48.png b/packages/docs/.vuepress/public/favicons/android-icon-48x48.png
similarity index 100%
rename from docs/.vuepress/public/favicons/android-icon-48x48.png
rename to packages/docs/.vuepress/public/favicons/android-icon-48x48.png
diff --git a/docs/.vuepress/public/favicons/android-icon-72x72.png b/packages/docs/.vuepress/public/favicons/android-icon-72x72.png
similarity index 100%
rename from docs/.vuepress/public/favicons/android-icon-72x72.png
rename to packages/docs/.vuepress/public/favicons/android-icon-72x72.png
diff --git a/docs/.vuepress/public/favicons/android-icon-96x96.png b/packages/docs/.vuepress/public/favicons/android-icon-96x96.png
similarity index 100%
rename from docs/.vuepress/public/favicons/android-icon-96x96.png
rename to packages/docs/.vuepress/public/favicons/android-icon-96x96.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-114x114.png b/packages/docs/.vuepress/public/favicons/apple-icon-114x114.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-114x114.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-114x114.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-120x120.png b/packages/docs/.vuepress/public/favicons/apple-icon-120x120.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-120x120.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-120x120.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-144x144.png b/packages/docs/.vuepress/public/favicons/apple-icon-144x144.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-144x144.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-144x144.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-152x152.png b/packages/docs/.vuepress/public/favicons/apple-icon-152x152.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-152x152.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-152x152.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-180x180.png b/packages/docs/.vuepress/public/favicons/apple-icon-180x180.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-180x180.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-180x180.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-57x57.png b/packages/docs/.vuepress/public/favicons/apple-icon-57x57.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-57x57.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-57x57.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-60x60.png b/packages/docs/.vuepress/public/favicons/apple-icon-60x60.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-60x60.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-60x60.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-72x72.png b/packages/docs/.vuepress/public/favicons/apple-icon-72x72.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-72x72.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-72x72.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-76x76.png b/packages/docs/.vuepress/public/favicons/apple-icon-76x76.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-76x76.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-76x76.png
diff --git a/docs/.vuepress/public/favicons/apple-icon-precomposed.png b/packages/docs/.vuepress/public/favicons/apple-icon-precomposed.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon-precomposed.png
rename to packages/docs/.vuepress/public/favicons/apple-icon-precomposed.png
diff --git a/docs/.vuepress/public/favicons/apple-icon.png b/packages/docs/.vuepress/public/favicons/apple-icon.png
similarity index 100%
rename from docs/.vuepress/public/favicons/apple-icon.png
rename to packages/docs/.vuepress/public/favicons/apple-icon.png
diff --git a/docs/.vuepress/public/favicons/browserconfig.xml b/packages/docs/.vuepress/public/favicons/browserconfig.xml
similarity index 100%
rename from docs/.vuepress/public/favicons/browserconfig.xml
rename to packages/docs/.vuepress/public/favicons/browserconfig.xml
diff --git a/docs/.vuepress/public/favicons/favicon-16x16.png b/packages/docs/.vuepress/public/favicons/favicon-16x16.png
similarity index 100%
rename from docs/.vuepress/public/favicons/favicon-16x16.png
rename to packages/docs/.vuepress/public/favicons/favicon-16x16.png
diff --git a/docs/.vuepress/public/favicons/favicon-32x32.png b/packages/docs/.vuepress/public/favicons/favicon-32x32.png
similarity index 100%
rename from docs/.vuepress/public/favicons/favicon-32x32.png
rename to packages/docs/.vuepress/public/favicons/favicon-32x32.png
diff --git a/docs/.vuepress/public/favicons/favicon-96x96.png b/packages/docs/.vuepress/public/favicons/favicon-96x96.png
similarity index 100%
rename from docs/.vuepress/public/favicons/favicon-96x96.png
rename to packages/docs/.vuepress/public/favicons/favicon-96x96.png
diff --git a/docs/.vuepress/public/favicons/manifest.json b/packages/docs/.vuepress/public/favicons/manifest.json
similarity index 95%
rename from docs/.vuepress/public/favicons/manifest.json
rename to packages/docs/.vuepress/public/favicons/manifest.json
index 013d4a6a..35f191b0 100644
--- a/docs/.vuepress/public/favicons/manifest.json
+++ b/packages/docs/.vuepress/public/favicons/manifest.json
@@ -1,5 +1,5 @@
{
- "name": "App",
+ "name": "CoreUI for Vue.js",
"icons": [
{
"src": "\/android-icon-36x36.png",
diff --git a/docs/.vuepress/public/favicons/ms-icon-144x144.png b/packages/docs/.vuepress/public/favicons/ms-icon-144x144.png
similarity index 100%
rename from docs/.vuepress/public/favicons/ms-icon-144x144.png
rename to packages/docs/.vuepress/public/favicons/ms-icon-144x144.png
diff --git a/docs/.vuepress/public/favicons/ms-icon-150x150.png b/packages/docs/.vuepress/public/favicons/ms-icon-150x150.png
similarity index 100%
rename from docs/.vuepress/public/favicons/ms-icon-150x150.png
rename to packages/docs/.vuepress/public/favicons/ms-icon-150x150.png
diff --git a/docs/.vuepress/public/favicons/ms-icon-310x310.png b/packages/docs/.vuepress/public/favicons/ms-icon-310x310.png
similarity index 100%
rename from docs/.vuepress/public/favicons/ms-icon-310x310.png
rename to packages/docs/.vuepress/public/favicons/ms-icon-310x310.png
diff --git a/docs/.vuepress/public/favicons/ms-icon-70x70.png b/packages/docs/.vuepress/public/favicons/ms-icon-70x70.png
similarity index 100%
rename from docs/.vuepress/public/favicons/ms-icon-70x70.png
rename to packages/docs/.vuepress/public/favicons/ms-icon-70x70.png
diff --git a/docs/.vuepress/public/favicons/safari-pinned-tab.svg b/packages/docs/.vuepress/public/favicons/safari-pinned-tab.svg
similarity index 100%
rename from docs/.vuepress/public/favicons/safari-pinned-tab.svg
rename to packages/docs/.vuepress/public/favicons/safari-pinned-tab.svg
diff --git a/docs/.vuepress/public/images/angular.jpg b/packages/docs/.vuepress/public/images/angular.jpg
similarity index 100%
rename from docs/.vuepress/public/images/angular.jpg
rename to packages/docs/.vuepress/public/images/angular.jpg
diff --git a/packages/docs/.vuepress/public/images/avatars/1.jpg b/packages/docs/.vuepress/public/images/avatars/1.jpg
new file mode 100644
index 00000000..8b5f8091
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/1.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/2.jpg b/packages/docs/.vuepress/public/images/avatars/2.jpg
new file mode 100644
index 00000000..161eeef5
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/2.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/3.jpg b/packages/docs/.vuepress/public/images/avatars/3.jpg
new file mode 100644
index 00000000..53ecc542
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/3.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/4.jpg b/packages/docs/.vuepress/public/images/avatars/4.jpg
new file mode 100644
index 00000000..a6ee3c72
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/4.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/5.jpg b/packages/docs/.vuepress/public/images/avatars/5.jpg
new file mode 100644
index 00000000..c38baeed
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/5.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/6.jpg b/packages/docs/.vuepress/public/images/avatars/6.jpg
new file mode 100644
index 00000000..57bbf968
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/6.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/7.jpg b/packages/docs/.vuepress/public/images/avatars/7.jpg
new file mode 100644
index 00000000..dfc20b7a
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/7.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/8.jpg b/packages/docs/.vuepress/public/images/avatars/8.jpg
new file mode 100644
index 00000000..4e8b48d4
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/8.jpg differ
diff --git a/packages/docs/.vuepress/public/images/avatars/9.jpg b/packages/docs/.vuepress/public/images/avatars/9.jpg
new file mode 100644
index 00000000..f690e78c
Binary files /dev/null and b/packages/docs/.vuepress/public/images/avatars/9.jpg differ
diff --git a/docs/.vuepress/public/images/brand/coreui-signet.svg b/packages/docs/.vuepress/public/images/brand/coreui-signet.svg
similarity index 100%
rename from docs/.vuepress/public/images/brand/coreui-signet.svg
rename to packages/docs/.vuepress/public/images/brand/coreui-signet.svg
diff --git a/docs/.vuepress/public/images/react.jpg b/packages/docs/.vuepress/public/images/react.jpg
similarity index 100%
rename from docs/.vuepress/public/images/react.jpg
rename to packages/docs/.vuepress/public/images/react.jpg
diff --git a/docs/.vuepress/public/images/vue.jpg b/packages/docs/.vuepress/public/images/vue.jpg
similarity index 100%
rename from docs/.vuepress/public/images/vue.jpg
rename to packages/docs/.vuepress/public/images/vue.jpg
diff --git a/docs/.vuepress/public/images/vue400.jpg b/packages/docs/.vuepress/public/images/vue400.jpg
similarity index 100%
rename from docs/.vuepress/public/images/vue400.jpg
rename to packages/docs/.vuepress/public/images/vue400.jpg
diff --git a/docs/.vuepress/theme-coreui/package.json b/packages/docs/.vuepress/theme-coreui/package.json
similarity index 100%
rename from docs/.vuepress/theme-coreui/package.json
rename to packages/docs/.vuepress/theme-coreui/package.json
diff --git a/packages/docs/.vuepress/theme-coreui/src/assets/brand/coreui-vue.svg b/packages/docs/.vuepress/theme-coreui/src/assets/brand/coreui-vue.svg
new file mode 100755
index 00000000..2b481a7d
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/assets/brand/coreui-vue.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/components/Ads.vue b/packages/docs/.vuepress/theme-coreui/src/client/components/Ads.vue
new file mode 100644
index 00000000..0cbcdb65
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/Ads.vue
@@ -0,0 +1,34 @@
+
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/components/Footer.vue b/packages/docs/.vuepress/theme-coreui/src/client/components/Footer.vue
similarity index 81%
rename from docs/.vuepress/theme-coreui/src/client/components/Footer.vue
rename to packages/docs/.vuepress/theme-coreui/src/client/components/Footer.vue
index 001b30b6..ca00885f 100644
--- a/docs/.vuepress/theme-coreui/src/client/components/Footer.vue
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/Footer.vue
@@ -8,9 +8,6 @@
Twitter
-
- Community
-
CoreUI (Vanilla)
@@ -23,23 +20,18 @@
CoreUI for Vue is Open Source UI Components Library for Vue.js.
- Currently v{{ version }}. Code licensed
+ CoreUI code licensed
- MIT
-
- , docs
+ >MIT, docs
- CC BY 3.0
-
- .
+ >CC BY 3.0.
+ CoreUI PRO requires a commercial license .
@@ -47,7 +39,7 @@
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/components/Page.vue b/packages/docs/.vuepress/theme-coreui/src/client/components/Page.vue
new file mode 100755
index 00000000..4ae63055
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/Page.vue
@@ -0,0 +1,111 @@
+
+
+
CoreUI PRO Component
+
+ To use this component you must have a CoreUI PRO license. Buy the
+ CoreUI PRO
+ and get access to all PRO components, features, templates, and dedicated support.
+
+
+
+
Support CoreUI Development
+
+ CoreUI is an MIT-licensed open source project and is completely free to use. However, the
+ amount of effort needed to maintain and develop new features for the project is not
+ sustainable without proper financial backing.
+
+
You can support our Open Source software development in the following ways:
+
+
+ Buy the
+ CoreUI PRO ,
+ and get access to PRO components, and dedicated support.
+
+
+ Became a sponsor , and get
+ your logo on BACKERS.md/README.md files or each site of this documentation
+
+
+ Give us a star ⭐️ on
+ Github .
+
+
+
+
+
+
{{ title }}
+
{{ description }}
+
+
+ Other frameworks
+
+ CoreUI components are available as native Angular, Bootstrap (Vanilla JS), and React
+ components. To learn more please visit the following pages.
+
+
+
+
+
+
+
+
+
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/components/ScssDocs.vue b/packages/docs/.vuepress/theme-coreui/src/client/components/ScssDocs.vue
new file mode 100644
index 00000000..b2579346
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/ScssDocs.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/components/Sidebar.vue b/packages/docs/.vuepress/theme-coreui/src/client/components/Sidebar.vue
new file mode 100755
index 00000000..b819a1ba
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/Sidebar.vue
@@ -0,0 +1,58 @@
+
+
+
+
+
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/components/SidebarNav.ts b/packages/docs/.vuepress/theme-coreui/src/client/components/SidebarNav.ts
new file mode 100755
index 00000000..09184a1e
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/SidebarNav.ts
@@ -0,0 +1,131 @@
+import { defineComponent, h, computed, onMounted, ref } from 'vue'
+import type { VNode } from 'vue'
+import { RouterLink, useRoute } from 'vue-router'
+import type { RouteLocationNormalizedLoaded } from 'vue-router'
+import type { ResolvedSidebarItem } from '../../shared'
+
+import { withBase } from '@vuepress/client'
+
+import { CBadge, CNavGroup, CNavItem, CSidebarNav } from '@coreui/vue/src/'
+import { CIcon } from '@coreui/icons-vue'
+
+const normalizePath = (path: string): string =>
+ decodeURI(path)
+ .replace(/#.*$/, '')
+ .replace(/(index)?\.(md|html)$/, '')
+
+const isActiveLink = (route: RouteLocationNormalizedLoaded, link?: string): boolean => {
+ if (link === undefined) {
+ return false
+ }
+
+ if (route.hash === link) {
+ return true
+ }
+
+ const currentPath = normalizePath(route.path)
+ const targetPath = normalizePath(link)
+
+ return currentPath === targetPath
+}
+
+const isActiveItem = (route: RouteLocationNormalizedLoaded, item: ResolvedSidebarItem): boolean => {
+ if (isActiveLink(route, item.link)) {
+ return true
+ }
+
+ if (item.children) {
+ return item.children.some((child) => isActiveItem(route, child))
+ }
+
+ return false
+}
+
+const SidebarNav = defineComponent({
+ name: 'SidebarNav',
+ props: {
+ items: {
+ type: Array,
+ required: true,
+ },
+ },
+ setup(props) {
+ const route = useRoute()
+ const firstRender = ref(true)
+
+ onMounted(() => {
+ firstRender.value = false
+ })
+
+ const renderItem = (item: ResolvedSidebarItem): VNode => {
+ if (item.children && !item.link.includes('.html')) {
+ const visible = computed(() => item.children.some((child) => isActiveItem(route, child)))
+
+ return h(
+ CNavGroup,
+ {
+ ...(firstRender.value && { visible: visible.value }),
+ compact: true,
+ },
+ {
+ togglerContent: () => [
+ h(CIcon, {
+ customClassName: 'nav-icon text-primary',
+ icon: ['512 512', item.icon],
+ height: 64,
+ width: 64,
+ }),
+ item.text,
+ ],
+ default: () => item.children.map((child) => renderItem(child)),
+ },
+ )
+ }
+
+ return h(
+ RouterLink,
+ {
+ to: item.link,
+ custom: true,
+ },
+ {
+ default: (props) =>
+ h(
+ CNavItem,
+ {
+ active: props.isActive,
+ disabled: item.disabled,
+ href: withBase(item.link),
+ },
+ {
+ default: () => [
+ item.text,
+ item.badge &&
+ h(
+ CBadge,
+ {
+ class: 'ms-auto',
+ color: item.badge.color,
+ },
+ {
+ default: () => item.badge.text,
+ },
+ ),
+ ],
+ },
+ ),
+ },
+ )
+ }
+
+ return () => h(
+ CSidebarNav,
+ {},
+ {
+ default: () => props.items.map((item: any) => renderItem(item)),
+ }
+ )
+ },
+})
+
+export { SidebarNav }
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/components/other_frameworks.json b/packages/docs/.vuepress/theme-coreui/src/client/components/other_frameworks.json
new file mode 100644
index 00000000..32046bbd
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/components/other_frameworks.json
@@ -0,0 +1,241 @@
+{
+ "accordion": {
+ "angular": "https://coreui.io/angular/docs/components/accordion",
+ "bootstrap": "https://coreui.io/docs/components/accordion/",
+ "react": "https://coreui.io/react/docs/components/accordion/",
+ "vue": "https://coreui.io/vue/docs/components/accordion.html"
+ },
+ "alert": {
+ "angular": "https://coreui.io/angular/docs/components/alert",
+ "bootstrap": "https://coreui.io/docs/components/alerts/",
+ "react": "https://coreui.io/react/docs/components/alert/",
+ "vue": "https://coreui.io/vue/docs/components/alert.html"
+ },
+ "avatar": {
+ "angular": "https://coreui.io/angular/docs/components/avatar",
+ "bootstrap": "https://coreui.io/docs/components/avatar/",
+ "react": "https://coreui.io/react/docs/components/avatar/",
+ "vue": "https://coreui.io/vue/docs/components/avatar.html"
+ },
+ "badge": {
+ "angular": "https://coreui.io/angular/docs/components/badge",
+ "bootstrap": "https://coreui.io/docs/components/badge/",
+ "react": "https://coreui.io/react/docs/components/badge/",
+ "vue": "https://coreui.io/vue/docs/components/badge.html"
+ },
+ "breadcrumb": {
+ "angular": "https://coreui.io/angular/docs/components/breadcrumb",
+ "bootstrap": "https://coreui.io/docs/components/breadcrumb/",
+ "react": "https://coreui.io/react/docs/components/breadcrumb/",
+ "vue": "https://coreui.io/vue/docs/components/breadcrumb.html"
+ },
+ "button": {
+ "angular": "https://coreui.io/angular/docs/components/button",
+ "bootstrap": "https://coreui.io/docs/components/buttons/",
+ "react": "https://coreui.io/react/docs/components/button/",
+ "vue": "https://coreui.io/vue/docs/components/button.html"
+ },
+ "button-group": {
+ "angular": "https://coreui.io/angular/docs/components/button-group",
+ "bootstrap": "https://coreui.io/docs/components/button-group/",
+ "react": "https://coreui.io/react/docs/components/button-group/",
+ "vue": "https://coreui.io/vue/docs/components/button-group.html"
+ },
+ "callout": {
+ "angular": "https://coreui.io/angular/docs/components/callout",
+ "bootstrap": "https://coreui.io/docs/components/callout/",
+ "react": "https://coreui.io/react/docs/components/callout/",
+ "vue": "https://coreui.io/vue/docs/components/callout.html"
+ },
+ "card": {
+ "angular": "https://coreui.io/angular/docs/components/card",
+ "bootstrap": "https://coreui.io/docs/components/card/",
+ "react": "https://coreui.io/react/docs/components/card/",
+ "vue": "https://coreui.io/vue/docs/components/card.html"
+ },
+ "carousel": {
+ "angular": "https://coreui.io/angular/docs/components/carousel",
+ "bootstrap": "https://coreui.io/docs/components/carousel/",
+ "react": "https://coreui.io/react/docs/components/carousel/",
+ "vue": "https://coreui.io/vue/docs/components/carousel.html"
+ },
+ "checkbox": {
+ "angular": "https://coreui.io/angular/docs/forms/checks-radios",
+ "bootstrap": "https://coreui.io/docs/forms/checks-radios/",
+ "react": "https://coreui.io/react/docs/forms/checkbox/",
+ "vue": "https://coreui.io/vue/docs/forms/checkbox.html"
+ },
+ "close-button": {
+ "angular": "https://coreui.io/angular/docs/components/close-button",
+ "bootstrap": "https://coreui.io/docs/components/close-button/",
+ "react": "https://coreui.io/react/docs/components/close-button/",
+ "vue": "https://coreui.io/vue/docs/components/close-button.html"
+ },
+ "collapse": {
+ "angular": "https://coreui.io/angular/docs/components/collapse",
+ "bootstrap": "https://coreui.io/docs/components/collapse/",
+ "react": "https://coreui.io/react/docs/components/collapse/",
+ "vue": "https://coreui.io/vue/docs/components/collapse.html"
+ },
+ "dropdown": {
+ "angular": "https://coreui.io/angular/docs/components/dropdown",
+ "bootstrap": "https://coreui.io/docs/components/dropdowns/",
+ "react": "https://coreui.io/react/docs/components/dropdown/",
+ "vue": "https://coreui.io/vue/docs/components/dropdown.html"
+ },
+ "footer": {
+ "angular": "https://coreui.io/angular/docs/components/footer",
+ "bootstrap": "https://coreui.io/docs/components/footer/",
+ "react": "https://coreui.io/react/docs/components/footer/",
+ "vue": "https://coreui.io/vue/docs/components/footer.html"
+ },
+ "header": {
+ "angular": "https://coreui.io/angular/docs/components/header",
+ "bootstrap": "https://coreui.io/docs/components/header/",
+ "react": "https://coreui.io/react/docs/components/header/",
+ "vue": "https://coreui.io/vue/docs/components/header.html"
+ },
+ "icon": {
+ "angular": "https://coreui.io/angular/docs/components/icon",
+ "bootstrap": "https://coreui.io/docs/components/icon/",
+ "react": "https://coreui.io/react/docs/components/icon/",
+ "vue": "https://coreui.io/vue/docs/components/icon.html"
+ },
+ "image": {
+ "angular": "https://coreui.io/angular/docs/components/image",
+ "bootstrap": "https://coreui.io/docs/content/images/",
+ "react": "https://coreui.io/react/docs/components/image/",
+ "vue": "https://coreui.io/vue/docs/components/image.html"
+ },
+ "input": {
+ "angular": "https://coreui.io/angular/docs/forms/input",
+ "bootstrap": "https://coreui.io/docs/forms/form-control/",
+ "react": "https://coreui.io/react/docs/forms/input/",
+ "vue": "https://coreui.io/vue/docs/forms/input.html"
+ },
+ "input-group": {
+ "angular": "https://coreui.io/angular/docs/forms/input-group",
+ "bootstrap": "https://coreui.io/docs/forms/input-group/",
+ "react": "https://coreui.io/react/docs/forms/input-group/",
+ "vue": "https://coreui.io/vue/docs/forms/input-group.html"
+ },
+ "floating-labels": {
+ "angular": "https://coreui.io/angular/docs/forms/floating-labels",
+ "bootstrap": "https://coreui.io/docs/forms/floating-labels/",
+ "react": "https://coreui.io/react/docs/forms/floating-labels/",
+ "vue": "https://coreui.io/vue/docs/forms/floating-labels.html"
+ },
+ "list-group": {
+ "angular": "https://coreui.io/angular/docs/components/list-group",
+ "bootstrap": "https://coreui.io/docs/components/list-group/",
+ "react": "https://coreui.io/react/docs/components/list-group/",
+ "vue": "https://coreui.io/vue/docs/components/list-group.html"
+ },
+ "modal": {
+ "angular": "https://coreui.io/angular/docs/components/modal",
+ "bootstrap": "https://coreui.io/docs/components/modal/",
+ "react": "https://coreui.io/react/docs/components/modal/",
+ "vue": "https://coreui.io/vue/docs/components/modal.html"
+ },
+ "navbar": {
+ "bootstrap": "https://coreui.io/docs/components/navbar/",
+ "react": "https://coreui.io/react/docs/components/navbar/",
+ "vue": "https://coreui.io/vue/docs/components/navbar.html"
+ },
+ "navs-tabs": {
+ "angular": "https://coreui.io/angular/docs/components/nav",
+ "bootstrap": "https://coreui.io/docs/components/navs-tabs/",
+ "react": "https://coreui.io/react/docs/components/navs-tabs/",
+ "vue": "https://coreui.io/vue/docs/components/navs-tabs.html"
+ },
+ "offcanvas": {
+ "angular": "https://coreui.io/angular/docs/components/offcanvas",
+ "bootstrap": "https://coreui.io/docs/components/offcanvas/",
+ "react": "https://coreui.io/react/docs/components/offcanvas/",
+ "vue": "https://coreui.io/vue/docs/components/offcanvas.html"
+ },
+ "pagination": {
+ "angular": "https://coreui.io/angular/docs/components/pagination",
+ "bootstrap": "https://coreui.io/docs/components/pagination/",
+ "react": "https://coreui.io/react/docs/components/pagination/",
+ "vue": "https://coreui.io/vue/docs/components/pagination.html"
+ },
+ "placeholder": {
+ "angular": "https://coreui.io/angular/docs/components/placeholder",
+ "bootstrap": "https://coreui.io/docs/components/placeholders/",
+ "react": "https://coreui.io/react/docs/components/placeholder/",
+ "vue": "https://coreui.io/vue/docs/components/placeholder.html"
+ },
+ "popover": {
+ "angular": "https://coreui.io/angular/docs/components/popover",
+ "bootstrap": "https://coreui.io/docs/components/popovers/",
+ "react": "https://coreui.io/react/docs/components/popover/",
+ "vue": "https://coreui.io/vue/docs/components/popover.html"
+ },
+ "progress": {
+ "angular": "https://coreui.io/angular/docs/components/progress",
+ "bootstrap": "https://coreui.io/docs/components/progress/",
+ "react": "https://coreui.io/react/docs/components/progress/",
+ "vue": "https://coreui.io/vue/docs/components/progress.html"
+ },
+ "radio": {
+ "angular": "https://coreui.io/angular/docs/forms/checks-radios",
+ "bootstrap": "https://coreui.io/docs/forms/checks-radios/",
+ "react": "https://coreui.io/react/docs/forms/radio/",
+ "vue": "https://coreui.io/vue/docs/forms/radio.html"
+ },
+ "range": {
+ "angular": "https://coreui.io/angular/docs/forms/range",
+ "bootstrap": "https://coreui.io/docs/forms/range/",
+ "react": "https://coreui.io/react/docs/forms/range/",
+ "vue": "https://coreui.io/vue/docs/forms/range.html"
+ },
+ "select": {
+ "angular": "https://coreui.io/angular/docs/forms/select",
+ "bootstrap": "https://coreui.io/docs/forms/select/",
+ "react": "https://coreui.io/react/docs/forms/select/",
+ "vue": "https://coreui.io/vue/docs/forms/select.html"
+ },
+ "sidebar": {
+ "angular": "https://coreui.io/angular/docs/components/sidebar",
+ "bootstrap": "https://coreui.io/docs/components/sidebar/",
+ "react": "https://coreui.io/react/docs/components/sidebar/",
+ "vue": "https://coreui.io/vue/docs/components/sidebar.html"
+ },
+ "spinner": {
+ "angular": "https://coreui.io/angular/docs/components/spinner",
+ "bootstrap": "https://coreui.io/docs/components/spinners/",
+ "react": "https://coreui.io/react/docs/components/spinner/",
+ "vue": "https://coreui.io/vue/docs/components/spinner.html"
+ },
+ "switch": {
+ "angular": "https://coreui.io/angular/docs/forms/checks-radios",
+ "bootstrap": "https://coreui.io/docs/forms/checks-radios/",
+ "react": "https://coreui.io/react/docs/forms/switch/",
+ "vue": "https://coreui.io/vue/docs/forms/switch.html"
+ },
+ "table": {
+ "angular": "https://coreui.io/angular/docs/components/table",
+ "bootstrap": "https://coreui.io/docs/content/tables/",
+ "react": "https://coreui.io/react/docs/components/table/",
+ "vue": "https://coreui.io/vue/docs/components/table.html"
+ },
+ "textarea": {
+ "angular": "https://coreui.io/angular/docs/forms/form-control",
+ "bootstrap": "https://coreui.io/docs/forms/form-control/",
+ "react": "https://coreui.io/react/docs/forms/textarea/",
+ "vue": "https://coreui.io/vue/docs/forms/textarea.html"
+ },
+ "toast": {
+ "angular": "https://coreui.io/angular/docs/components/toast",
+ "bootstrap": "https://coreui.io/docs/components/toasts/",
+ "react": "https://coreui.io/react/docs/components/toast/",
+ "vue": "https://coreui.io/vue/docs/components/toast.html"
+ },
+ "tooltip": {
+ "angular": "https://coreui.io/angular/docs/components/tooltip",
+ "bootstrap": "https://coreui.io/docs/components/tooltips/",
+ "react": "https://coreui.io/react/docs/components/tooltip/",
+ "vue": "https://coreui.io/vue/docs/components/tooltip.html"
+ }
+}
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/composables/index.ts b/packages/docs/.vuepress/theme-coreui/src/client/composables/index.ts
new file mode 100644
index 00000000..26ca889b
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/composables/index.ts
@@ -0,0 +1,3 @@
+export * from './useScrollPromise'
+export * from './useSidebarItems'
+export * from './useThemeData'
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/composables/useNavLink.ts b/packages/docs/.vuepress/theme-coreui/src/client/composables/useNavLink.ts
new file mode 100755
index 00000000..0dc5fc38
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/composables/useNavLink.ts
@@ -0,0 +1,26 @@
+import type { NavLink } from '../../shared/index.js'
+import { useResolveRouteWithRedirect } from './useResolveRouteWithRedirect.js'
+
+declare module 'vue-router' {
+ interface RouteMeta {
+ title?: string
+ }
+}
+
+/**
+ * Resolve NavLink props from string
+ *
+ * @example
+ * - Input: '/README.md'
+ * - Output: { text: 'Home', link: '/' }
+ */
+export const useNavLink = (item: string): NavLink => {
+ // the route path of vue-router is url-encoded, and we expect users are using
+ // non-url-encoded string in theme config, so we need to url-encode it first to
+ // resolve the route correctly
+ const resolved = useResolveRouteWithRedirect(encodeURI(item))
+ return {
+ text: resolved.meta.title || item,
+ link: resolved.name === '404' ? item : resolved.fullPath,
+ }
+}
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/composables/useResolveRouteWithRedirect.ts b/packages/docs/.vuepress/theme-coreui/src/client/composables/useResolveRouteWithRedirect.ts
similarity index 99%
rename from docs/.vuepress/theme-coreui/src/client/composables/useResolveRouteWithRedirect.ts
rename to packages/docs/.vuepress/theme-coreui/src/client/composables/useResolveRouteWithRedirect.ts
index d4d93285..5a1958a4 100755
--- a/docs/.vuepress/theme-coreui/src/client/composables/useResolveRouteWithRedirect.ts
+++ b/packages/docs/.vuepress/theme-coreui/src/client/composables/useResolveRouteWithRedirect.ts
@@ -1,6 +1,6 @@
+import { isFunction, isString } from '@vuepress/shared'
import { useRouter } from 'vue-router'
import type { Router } from 'vue-router'
-import { isFunction, isString } from '@vuepress/shared'
/**
* Resolve a route with redirection
@@ -25,4 +25,4 @@ export const useResolveRouteWithRedirect = (
params: route.params,
...resolvedRedirectObj,
})
-}
+}
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/composables/useScrollPromise.ts b/packages/docs/.vuepress/theme-coreui/src/client/composables/useScrollPromise.ts
similarity index 99%
rename from docs/.vuepress/theme-coreui/src/client/composables/useScrollPromise.ts
rename to packages/docs/.vuepress/theme-coreui/src/client/composables/useScrollPromise.ts
index 0405f8c7..02e726ca 100755
--- a/docs/.vuepress/theme-coreui/src/client/composables/useScrollPromise.ts
+++ b/packages/docs/.vuepress/theme-coreui/src/client/composables/useScrollPromise.ts
@@ -19,4 +19,4 @@ const scrollPromise: ScrollPromise = {
},
}
-export const useScrollPromise = (): ScrollPromise => scrollPromise
+export const useScrollPromise = (): ScrollPromise => scrollPromise
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/composables/useSidebarItems.ts b/packages/docs/.vuepress/theme-coreui/src/client/composables/useSidebarItems.ts
similarity index 84%
rename from docs/.vuepress/theme-coreui/src/client/composables/useSidebarItems.ts
rename to packages/docs/.vuepress/theme-coreui/src/client/composables/useSidebarItems.ts
index 9705c496..0cf89962 100755
--- a/docs/.vuepress/theme-coreui/src/client/composables/useSidebarItems.ts
+++ b/packages/docs/.vuepress/theme-coreui/src/client/composables/useSidebarItems.ts
@@ -1,7 +1,4 @@
-import { inject } from 'vue'
-import type { ComputedRef, InjectionKey } from 'vue'
-import { useRoute } from 'vue-router'
-import { usePageData } from '@vuepress/client'
+import { usePageData, usePageFrontmatter } from '@vuepress/client'
import type { PageHeader } from '@vuepress/client'
import {
isArray,
@@ -9,21 +6,24 @@ import {
isString,
resolveLocalePath,
} from '@vuepress/shared'
+import { computed, inject, provide } from 'vue'
+import type { ComputedRef, InjectionKey } from 'vue'
+import { useRoute } from 'vue-router'
import type {
DefaultThemeData,
DefaultThemeNormalPageFrontmatter,
+ ResolvedSidebarItem,
SidebarConfigArray,
SidebarConfigObject,
SidebarItem,
- ResolvedSidebarItem,
-} from '../../shared'
-import { useNavLink } from './useNavLink'
+} from '../../shared/index.js'
+import { useNavLink } from './useNavLink.js'
+import { useThemeLocaleData } from './useThemeData.js'
export type SidebarItemsRef = ComputedRef
-export const sidebarItemsSymbol: InjectionKey = Symbol(
- 'sidebarItems'
-)
+export const sidebarItemsSymbol: InjectionKey =
+ Symbol('sidebarItems')
/**
* Inject sidebar items global computed
@@ -36,6 +36,18 @@ export const useSidebarItems = (): SidebarItemsRef => {
return sidebarItems
}
+/**
+ * Create sidebar items ref and provide as global computed in setup
+ */
+export const setupSidebarItems = (): void => {
+ const themeLocale = useThemeLocaleData()
+ const frontmatter = usePageFrontmatter()
+ const sidebarItems = computed(() =>
+ resolveSidebarItems(frontmatter.value, themeLocale.value)
+ )
+ provide(sidebarItemsSymbol, sidebarItems)
+}
+
/**
* Resolve sidebar items global computed
*
@@ -45,7 +57,7 @@ export const resolveSidebarItems = (
frontmatter: DefaultThemeNormalPageFrontmatter,
themeLocale: DefaultThemeData
): ResolvedSidebarItem[] => {
- // get sidebar config from frontmatter > themeConfig
+ // get sidebar config from frontmatter > theme data
const sidebarConfig = frontmatter.sidebar ?? themeLocale.sidebar ?? 'auto'
const sidebarDepth = frontmatter.sidebarDepth ?? themeLocale.sidebarDepth ?? 2
@@ -77,7 +89,7 @@ export const headerToSidebarItem = (
sidebarDepth: number
): ResolvedSidebarItem => ({
text: header.title,
- link: `#${header.slug}`,
+ link: header.link,
children: headersToSidebarItemChildren(header.children, sidebarDepth),
})
@@ -164,4 +176,4 @@ export const resolveMultiSidebarItems = (
const matchedSidebarConfig = sidebarConfig[sidebarPath] ?? []
return resolveArraySidebarItems(matchedSidebarConfig, sidebarDepth)
-}
+}
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/composables/useThemeData.ts b/packages/docs/.vuepress/theme-coreui/src/client/composables/useThemeData.ts
similarity index 62%
rename from docs/.vuepress/theme-coreui/src/client/composables/useThemeData.ts
rename to packages/docs/.vuepress/theme-coreui/src/client/composables/useThemeData.ts
index a5192b45..78ab77f7 100755
--- a/docs/.vuepress/theme-coreui/src/client/composables/useThemeData.ts
+++ b/packages/docs/.vuepress/theme-coreui/src/client/composables/useThemeData.ts
@@ -1,14 +1,14 @@
import {
useThemeData as _useThemeData,
useThemeLocaleData as _useThemeLocaleData,
-} from '@vuepress/plugin-theme-data/lib/client'
+} from '@vuepress/plugin-theme-data/client'
import type {
ThemeDataRef,
ThemeLocaleDataRef,
-} from '@vuepress/plugin-theme-data/lib/client'
-import type { DefaultThemeData } from '../../shared'
+} from '@vuepress/plugin-theme-data/client'
+import type { DefaultThemeData } from '../../shared/index.js'
export const useThemeData = (): ThemeDataRef =>
_useThemeData()
export const useThemeLocaleData = (): ThemeLocaleDataRef =>
- _useThemeLocaleData()
+ _useThemeLocaleData()
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/config.ts b/packages/docs/.vuepress/theme-coreui/src/client/config.ts
new file mode 100644
index 00000000..ca174efb
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/config.ts
@@ -0,0 +1,40 @@
+import { defineClientConfig } from '@vuepress/client'
+import { h } from 'vue'
+import {
+ setupSidebarItems,
+ useScrollPromise,
+} from './composables/index.js'
+import Layout from './layouts/Layout.vue'
+import NotFound from './layouts/404.vue'
+
+import './styles/index.scss'
+
+export default defineClientConfig({
+ enhance({ app, router }) {
+
+ // compat with @vuepress/plugin-external-link-icon
+ app.component('AutoLinkExternalIcon', () => {
+ const ExternalLinkIcon = app.component('ExternalLinkIcon')
+ if (ExternalLinkIcon) {
+ return h(ExternalLinkIcon)
+ }
+ return null
+ })
+
+ // handle scrollBehavior with transition
+ const scrollBehavior = router.options.scrollBehavior!
+ router.options.scrollBehavior = async (...args) => {
+ await useScrollPromise().wait()
+ return scrollBehavior(...args)
+ }
+ },
+
+ setup() {
+ setupSidebarItems()
+ },
+
+ layouts: {
+ Layout,
+ NotFound,
+ },
+})
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/index.ts b/packages/docs/.vuepress/theme-coreui/src/client/index.ts
new file mode 100755
index 00000000..520d8125
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/index.ts
@@ -0,0 +1,2 @@
+export * from '../shared/index.js'
+export * from './composables/index.js'
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/layouts/404.vue b/packages/docs/.vuepress/theme-coreui/src/client/layouts/404.vue
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/client/layouts/404.vue
rename to packages/docs/.vuepress/theme-coreui/src/client/layouts/404.vue
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/layouts/Layout.vue b/packages/docs/.vuepress/theme-coreui/src/client/layouts/Layout.vue
new file mode 100755
index 00000000..65089b81
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/layouts/Layout.vue
@@ -0,0 +1,103 @@
+
+
+
(isSidebarOpen = event)" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ On this page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vuepress/theme-coreui/src/client/layouts/Redirect.vue b/packages/docs/.vuepress/theme-coreui/src/client/layouts/Redirect.vue
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/client/layouts/Redirect.vue
rename to packages/docs/.vuepress/theme-coreui/src/client/layouts/Redirect.vue
diff --git a/docs/.vuepress/theme-coreui/src/client/shim.d.ts b/packages/docs/.vuepress/theme-coreui/src/client/shim.d.ts
similarity index 54%
rename from docs/.vuepress/theme-coreui/src/client/shim.d.ts
rename to packages/docs/.vuepress/theme-coreui/src/client/shim.d.ts
index bf554924..f97ca4f4 100755
--- a/docs/.vuepress/theme-coreui/src/client/shim.d.ts
+++ b/packages/docs/.vuepress/theme-coreui/src/client/shim.d.ts
@@ -3,3 +3,8 @@ declare module '*.vue' {
const comp: ComponentOptions
export default comp
}
+
+declare module '*.module.scss?module' {
+ const cssVars: Record
+ export default cssVars
+}
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_ads.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_ads.scss
new file mode 100644
index 00000000..575db8b0
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_ads.scss
@@ -0,0 +1,38 @@
+// stylelint-disable declaration-no-important, selector-max-id
+
+//
+// Carbon ads
+//
+
+#carbonads {
+ position: static;
+ display: block;
+ max-width: 400px;
+ padding: 15px 15px 15px 160px;
+ margin: 2rem 0;
+ overflow: hidden;
+ @include font-size(.8125rem);
+ line-height: 1.4;
+ text-align: left;
+ background-color: var(--cui-tertiary-bg);
+
+ a {
+ color: var(--cui-body-color);
+ text-decoration: none;
+ }
+
+ @include media-breakpoint-up(sm) {
+ @include border-radius(.5rem);
+ }
+}
+
+.carbon-img {
+ float: left;
+ margin-left: -145px;
+}
+
+.carbon-poweredby {
+ display: block;
+ margin-top: .75rem;
+ color: var(--cui-body-color) !important;
+}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_anchor.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_anchor.scss
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/client/styles/_anchor.scss
rename to packages/docs/.vuepress/theme-coreui/src/client/styles/_anchor.scss
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_component-examples.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_component-examples.scss
new file mode 100644
index 00000000..ecc83bd7
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_component-examples.scss
@@ -0,0 +1,425 @@
+//
+// Docs examples
+//
+
+.docs-example-snippet {
+ border: solid var(--cui-border-color);
+ border-width: 1px 0;
+
+ @include media-breakpoint-up(md) {
+ border-width: 1px;
+ }
+}
+
+.docs-example {
+ --cd-example-padding: 1rem;
+
+ position: relative;
+ padding: var(--cd-example-padding);
+ margin: 0 ($cd-gutter-x * -.5);
+ border: solid var(--cui-border-color);
+ border-width: 1px 0;
+ @include clearfix();
+
+ @include media-breakpoint-up(md) {
+ --cd-example-padding: 1.5rem;
+
+ margin-right: 0;
+ margin-left: 0;
+ border-width: 1px;
+ @include border-top-radius(var(--cui-border-radius));
+ }
+
+ + .docs-code-snippet {
+ @include border-top-radius(0);
+ border: solid var(--cui-border-color);
+ border-width: 0 1px 1px;
+ }
+
+ + p {
+ margin-top: 2rem;
+ }
+
+ > .form-control {
+ + .form-control {
+ margin-top: .5rem;
+ }
+ }
+
+ > .nav + .nav,
+ > .alert + .alert,
+ > .navbar + .navbar,
+ > .progress + .progress {
+ margin-top: $spacer;
+ }
+
+ > .dropdown-menu {
+ position: static;
+ display: block;
+ }
+
+ > :last-child,
+ > nav:last-child .breadcrumb {
+ margin-bottom: 0;
+ }
+
+ > hr:last-child {
+ margin-bottom: $spacer;
+ }
+
+ // Images
+ > svg + svg,
+ > img + img {
+ margin-left: .5rem;
+ }
+
+ // Buttons
+ > .btn,
+ > .btn-group {
+ margin: .25rem .125rem;
+ }
+ > .btn-toolbar + .btn-toolbar {
+ margin-top: .5rem;
+ }
+
+ // List groups
+ > .list-group {
+ max-width: 400px;
+ }
+
+ > [class*="list-group-horizontal"] {
+ max-width: 100%;
+ }
+
+ // Navbars
+ .fixed-top,
+ .sticky-top {
+ position: static;
+ margin: calc(var(--cd-example-padding) * -1) calc(var(--cd-example-padding) * -1) var(--cd-example-padding); // stylelint-disable-line function-disallowed-list
+ }
+
+ .fixed-bottom,
+ .sticky-bottom {
+ position: static;
+ margin: var(--cd-example-padding) calc(var(--cd-example-padding) * -1) calc(var(--cd-example-padding) * -1); // stylelint-disable-line function-disallowed-list
+
+ }
+
+ // Pagination
+ .pagination {
+ margin-bottom: 0;
+ }
+}
+
+//
+// Grid examples
+//
+
+.docs-example-row [class^="col"],
+.docs-example-cols [class^="col"] > *,
+.docs-example-cssgrid [class*="grid"] > * {
+ padding-top: .75rem;
+ padding-bottom: .75rem;
+ background-color: rgba(var(--cd-violet-rgb), .15);
+ border: 1px solid rgba(var(--cd-violet-rgb), .3);
+}
+
+.docs-example-row .row + .row,
+.docs-example-cssgrid .grid + .grid {
+ margin-top: 1rem;
+}
+
+.docs-example-row-flex-cols .row {
+ min-height: 10rem;
+ background-color: rgba(var(--cd-violet-rgb), .15);
+}
+
+.docs-example-flex div:not(.vr) {
+ background-color: rgba(var(--cd-violet-rgb), .15);
+ border: 1px solid rgba(var(--cd-violet-rgb), .3);
+}
+
+// Grid mixins
+.example-container {
+ width: 800px;
+ @include make-container();
+}
+
+.example-row {
+ @include make-row();
+}
+
+.example-content-main {
+ @include make-col-ready();
+
+ @include media-breakpoint-up(sm) {
+ @include make-col(6);
+ }
+
+ @include media-breakpoint-up(lg) {
+ @include make-col(8);
+ }
+}
+
+.example-content-secondary {
+ @include make-col-ready();
+
+ @include media-breakpoint-up(sm) {
+ @include make-col(6);
+ }
+
+ @include media-breakpoint-up(lg) {
+ @include make-col(4);
+ }
+}
+
+// Ratio helpers
+.docs-example-ratios {
+ .ratio {
+ display: inline-block;
+ width: 10rem;
+ color: var(--cui-secondary-color);
+ background-color: var(--cui-tertiary-bg);
+ border: var(--cui-border-width) solid var(--cui-border-color);
+
+ > div {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+ }
+}
+.docs-example-ratios-breakpoint {
+ .ratio-4x3 {
+ width: 16rem;
+
+ @include media-breakpoint-up(md) {
+ --cui-aspect-ratio: 50%; // 2x1
+ }
+ }
+}
+
+.docs-example-offcanvas {
+ .offcanvas {
+ position: static;
+ display: block;
+ height: 200px;
+ visibility: visible;
+ transform: translate(0);
+ }
+}
+
+// Tooltips
+.tooltip-demo {
+ a {
+ white-space: nowrap;
+ }
+
+ .btn {
+ margin: .25rem .125rem;
+ }
+}
+
+// scss-docs-start custom-tooltip
+.custom-tooltip {
+ --cui-tooltip-bg: var(--cui-primary);
+}
+// scss-docs-end custom-tooltip
+
+// scss-docs-start custom-popovers
+.custom-popover {
+ --cui-popover-max-width: 200px;
+ --cui-popover-border-color: var(--cui-primary);
+ --cui-popover-header-bg: var(--cui-primary);
+ --cui-popover-header-color: var(--cui-white);
+ --cui-popover-body-padding-x: 1rem;
+ --cui-popover-body-padding-y: .5rem;
+}
+// scss-docs-end custom-popovers
+
+// Scrollspy demo on fixed height div
+.scrollspy-example {
+ height: 200px;
+ margin-top: .5rem;
+ overflow: auto;
+}
+
+.scrollspy-example-2 {
+ height: 350px;
+ overflow: auto;
+}
+
+.simple-list-example-scrollspy {
+ .active {
+ background-color: rgba(var(--cd-violet-rgb), .15);
+ }
+}
+
+.docs-example-border-utils {
+ [class^="border"] {
+ display: inline-block;
+ width: 5rem;
+ height: 5rem;
+ margin: .25rem;
+ background-color: var(--cui-tertiary-bg);
+ }
+}
+
+.docs-example-rounded-utils {
+ [class*="rounded"] {
+ margin: .25rem;
+ }
+}
+
+.docs-example-position-utils {
+ position: relative;
+ padding: 2rem;
+
+ .position-relative {
+ height: 200px;
+ background-color: var(--cui-tertiary-bg);
+ }
+
+ .position-absolute {
+ width: 2rem;
+ height: 2rem;
+ background-color: var(--cui-body-color);
+ @include border-radius();
+ }
+}
+
+.docs-example-position-examples {
+ &::after {
+ content: none;
+ }
+}
+
+// Placeholders
+.docs-example-placeholder-cards {
+ &::after {
+ display: none;
+ }
+
+ .card {
+ width: 18rem;
+ }
+}
+
+// Toasts
+.docs-example-toasts {
+ min-height: 240px;
+}
+
+.docs-example-zindex-levels {
+ min-height: 15rem;
+
+ > div {
+ color: var(--cui-body-bg);
+ background-color: var(--cd-violet);
+ border: 1px solid var(--cd-purple);
+
+ > span {
+ position: absolute;
+ right: 5px;
+ bottom: 0;
+ }
+ }
+
+ > :nth-child(2) {
+ top: 3rem;
+ left: 3rem;
+ }
+ > :nth-child(3) {
+ top: 4.5rem;
+ left: 4.5rem;
+ }
+ > :nth-child(4) {
+ top: 6rem;
+ left: 6rem;
+ }
+ > :nth-child(5) {
+ top: 7.5rem;
+ left: 7.5rem;
+ }
+}
+
+//
+// Code snippets
+//
+
+div[class^="language-"],
+.highlight {
+ position: relative;
+ padding: .75rem ($cd-gutter-x * .5);
+ margin-bottom: 1rem;
+ border: 1px solid var(--cui-border-color);
+ background-color: var(--cd-pre-bg);
+
+ @include media-breakpoint-up(md) {
+ padding: .75rem 1.25rem;
+ @include border-radius(var(--cui-border-radius));
+ }
+
+ pre {
+ padding: .25rem 0 .875rem;
+ margin-top: .8125rem;
+ margin-right: 1.875rem;
+ margin-bottom: 0;
+ overflow: overlay;
+ white-space: pre;
+ background-color: transparent;
+ border: 0;
+ }
+
+ pre code {
+ @include font-size(inherit);
+ color: var(--cui-body-color); // Effectively the base text color
+ word-wrap: normal;
+ }
+}
+
+.docs-code-snippet {
+ margin: 0 ($cd-gutter-x * -.5) $spacer;
+
+ div[class^="language-"],
+ .highlight {
+ margin-bottom: 0;
+ }
+
+ .docs-example ~ div[class^="language-"],
+ .docs-example ~ .highlight {
+ border: 0;
+ @include border-top-radius(0);
+ }
+
+ .docs-example {
+ margin: 0;
+ border: 0;
+ }
+
+ @include media-breakpoint-up(md) {
+ margin-right: 0;
+ margin-left: 0;
+ @include border-radius($border-radius);
+ }
+}
+
+.highlight-toolbar {
+ background-color: var(--cd-pre-bg);
+}
+
+.docs-scss-docs {
+ .highlight-toolbar {
+ @include border-top-radius(calc(var(--cui-border-radius) + 1px));
+ }
+}
+
+.docs-example {
+ border-bottom-width: 0;
+}
+
+.docs-example + div[class^="language-"],
+.docs-example + .highlight {
+ border-top-width: 0;
+ @include border-top-radius(0);
+}
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_footer.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_footer.scss
new file mode 100644
index 00000000..14e22108
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_footer.scss
@@ -0,0 +1,19 @@
+//
+// Footer
+//
+
+.footer {
+ --cui-footer-bg: var(--cui-tertiary-bg);
+ @include font-size(.875rem);
+
+ a {
+ color: #768192;
+ text-decoration: none;
+
+ &:hover,
+ &:focus {
+ color: var(--cui-link-hover-color);
+ text-decoration: underline;
+ }
+ }
+}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_layout.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_layout.scss
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/client/styles/_layout.scss
rename to packages/docs/.vuepress/theme-coreui/src/client/styles/_layout.scss
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_prism.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_prism.scss
new file mode 100644
index 00000000..21bfa2c9
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_prism.scss
@@ -0,0 +1,145 @@
+/* PrismJS 1.24.1
+https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript */
+/**
+ * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
+ * Based on https://github.com/chriskempson/tomorrow-theme
+ * @author Rose Pritchard
+ */
+
+:root {
+ // --base00: #fff;
+ // --base01: #f5f5f5;
+ --base02: #c8c8fa;
+ --base03: #565c64;
+ --base04: #666;
+ --base05: #333;
+ --base06: #fff;
+ --base07: #{$teal-700}; // #9a6700
+ --base08: #{mix($red-500, $red-600, 50%)}; // #bc4c00
+ --base09: #{$cyan-700}; // #087990
+ --base0A: #{$purple-500}; // #795da3
+ --base0B: #{$blue-700}; // #183691
+ --base0C: #{$blue-700}; // #183691
+ --base0D: #{$purple-500}; // #795da3
+ --base0E: #{$pink-600}; // #a71d5d
+ --base0F: #333;
+}
+
+code[class*='language-'],
+pre[class*='language-'] {
+ background: none;
+ font-family: var(--cui-font-monospace);
+ font-size: .875em;
+ text-align: left;
+ white-space: pre;
+
+ -moz-tab-size: 4;
+ -o-tab-size: 4;
+ tab-size: 4;
+
+ -webkit-hyphens: none;
+ -moz-hyphens: none;
+ -ms-hyphens: none;
+ hyphens: none;
+}
+
+pre[class*='language-']:not(.language-sass):not(.language-scss):not(.language-text):not(.language-css) {
+ overflow: scroll;
+ max-height: 500px;
+}
+
+.token.comment,
+.token.block-comment,
+.token.prolog,
+.token.doctype,
+.token.cdata {
+ color: var(--base03);
+}
+
+.token.tag {
+ color: var(--base08);
+}
+
+.token.attr-name,
+.token.namespace,
+.token.deleted {
+ color: var(--base0A);
+}
+
+.token.punctuation {
+ color: var(--base05);
+}
+
+.token.function-name {
+ color: var(--base0A);
+}
+
+.token.boolean,
+.token.number,
+.token.function {
+ color: var(--base09);
+}
+
+.token.class-name,
+.token.maybe-class-name {
+ color: var(--base08);
+}
+
+.token.property,
+.token.constant,
+.token.symbol {
+ color: var(--base0A);
+}
+
+.token.selector,
+.token.important,
+.token.atrule,
+.token.keyword,
+.token.builtin {
+ color: var(--base0E);
+}
+
+.token.string,
+.token.char,
+.token.attr-value,
+.token.regex,
+.token.variable {
+ color: var(--base0C);
+}
+
+.token.operator,
+.token.entity,
+.token.url {
+ color: var(--base05);
+}
+
+.token.important,
+.token.bold {
+ font-weight: bold;
+}
+.token.italic {
+ font-style: italic;
+}
+
+.token.entity {
+ cursor: help;
+}
+
+.token.inserted {
+ color: green;
+}
+
+.language-bash,
+.language-sh {
+ .token-line::before {
+ color: var(--base03);
+ content: "$ ";
+ user-select: none;
+ }
+}
+
+.language-powershell::before {
+ color: var(--base0C);
+ content: "PM> ";
+ user-select: none;
+}
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_scrolling.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_scrolling.scss
new file mode 100644
index 00000000..20179600
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_scrolling.scss
@@ -0,0 +1,13 @@
+// When navigating with the keyboard, prevent focus from landing behind the sticky header
+
+main {
+ a,
+ button,
+ h2,
+ h3,
+ h4,
+ [tabindex="0"] {
+ scroll-margin-top: 80px;
+ scroll-margin-bottom: 100px;
+ }
+}
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_search.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_search.scss
new file mode 100644
index 00000000..8b19708c
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_search.scss
@@ -0,0 +1,132 @@
+// stylelint-disable selector-class-pattern
+
+:root {
+ --docsearch-primary-color: var(--cui-primary);
+ --docsearch-logo-color: var(--cui-primary);
+}
+
+.DocSearch-Container {
+ --docsearch-muted-color: var(--cui-secondary-color);
+ --docsearch-hit-shadow: none;
+
+ z-index: 2000; // Make sure to be over all components showcased in the documentation
+ cursor: auto; // Needed because of [role="button"] in Algolia search modal. Remove once https://github.com/algolia/docsearch/issues/1370 is tackled.
+
+ @include media-breakpoint-up(lg) {
+ padding-top: 4rem;
+ }
+}
+
+.DocSearch-Button {
+ --docsearch-searchbox-background: #{rgba($black, .1)};
+ // --docsearch-searchbox-color: #{$white};
+ --docsearch-searchbox-focus-background: #{rgba($black, .25)};
+ // --docsearch-searchbox-shadow: #{0 0 0 .25rem rgba($bd-accent, .4)};
+ // --docsearch-text-color: #{$white};
+ // --docsearch-muted-color: #{rgba($white, .65)};
+
+ min-width: 200px;
+ min-height: 38px;
+ font-family: $input-font-family;
+ font-weight: $input-font-weight;
+ line-height: $input-line-height;
+ @include font-size($input-font-size);
+ color: $input-color;
+ background-color: $input-bg;
+ background-clip: padding-box;
+ border: $input-border-width solid $input-border-color;
+
+ // Note: This has no effect on s in some browsers, due to the limited stylability of ``s in CSS.
+ @include border-radius($btn-border-radius);
+
+ @include box-shadow($input-box-shadow);
+ @include transition($input-transition);
+
+ &:focus {
+ color: $input-focus-color;
+ background-color: $input-focus-bg;
+ border-color: $input-focus-border-color;
+ outline: 0;
+ @if $enable-shadows {
+ @include box-shadow($input-box-shadow, $input-focus-box-shadow);
+ } @else {
+ // Avoid using mixin so we can pass custom focus shadow properly
+ box-shadow: $input-focus-box-shadow;
+ }
+ }
+
+ &:hover:not(:disabled):not([readonly])::file-selector-button {
+ background-color: $form-file-button-hover-bg;
+ }
+
+ .DocSearch-Search-Icon {
+ opacity: .65;
+ }
+}
+
+
+.DocSearch-Button-Keys {
+ min-width: 0;
+ padding: 0 .25rem;
+ background: rgba($black, .125);
+ @include border-radius(.25rem);
+}
+
+.DocSearch-Button-Key {
+ top: 0;
+ width: auto;
+ height: 1.5rem;
+ padding: 0 .125rem;
+ margin-right: 0;
+ font-size: .875rem;
+ background: none;
+ box-shadow: none;
+}
+
+.DocSearch-Commands-Key {
+ padding-left: 1px;
+ font-size: .875rem;
+ background-color: rgba($black, .1);
+ background-image: none;
+ box-shadow: none;
+}
+
+.DocSearch-Form {
+ @include border-radius(var(--cui-border-radius));
+}
+
+.DocSearch-Hits {
+ mark {
+ padding: 0;
+ }
+}
+
+.DocSearch-Hit {
+ padding-bottom: 0;
+ @include border-radius(0);
+
+ a {
+ @include border-radius(0);
+ border: solid var(--cui-border-color);
+ border-width: 0 1px 1px;
+ }
+
+ &:first-child a {
+ @include border-top-radius(var(--cui-border-radius));
+ border-top-width: 1px;
+ }
+ &:last-child a {
+ @include border-bottom-radius(var(--cui-border-radius));
+ }
+}
+
+.DocSearch-Hit-icon {
+ display: flex;
+ align-items: center;
+}
+
+// Fix --docsearch-logo-color that doesn't do anything
+.DocSearch-Logo svg .cls-1,
+.DocSearch-Logo svg .cls-2 {
+ fill: var(--docsearch-logo-color);
+}
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_sidebar.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_sidebar.scss
new file mode 100755
index 00000000..18ab0150
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_sidebar.scss
@@ -0,0 +1,16 @@
+.sidebar.docs-sidebar {
+ --cui-sidebar-bg: var(--cui-tertiary-bg);
+ --cui-sidebar-brand-bg: transparent;
+ --cui-sidebar-brand-color: var(--cui-body-color);
+ --cui-sidebar-nav-link-color: var(--cui-body-color);
+ --cui-sidebar-nav-link-active-bg: transparent;
+ --cui-sidebar-nav-link-active-color: var(--cui-primary);
+ --cui-sidebar-nav-link-hover-bg: transparent;
+ --cui-sidebar-nav-link-hover-color: var(--cui-primary);
+ --cui-sidebar-nav-group-bg: transparent;
+ --cui-sidebar-nav-group-toggle-show-color: var(--cui-primary);
+
+ .nav-group-items {
+ --cui-sidebar-nav-link-color: var(--cui-body-color);
+ }
+}
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_table-api.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_table-api.scss
new file mode 100644
index 00000000..43d33928
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_table-api.scss
@@ -0,0 +1,35 @@
+.table-api {
+ --cui-table-striped-bg: #{rgba(#f0f4f7, .25)} !important;
+ tr td {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+ }
+ td:first-child,
+ th:first-child {
+ width: 15%;
+ padding-left: 1rem;
+ }
+ td:first-child {
+ white-space: nowrap;
+ }
+ td:nth-child(2n) {
+ width: 55%;
+ }
+ td:nth-child(3n) {
+ width: 10%;
+ }
+ td:nth-child(4n) {
+ width: 10%;
+ }
+ td:nth-child(5n) {
+ width: 10%;
+ }
+
+ & + h3 {
+ margin-top: 2rem;
+ }
+}
+
+.markdown + h3 {
+ margin-top: 3rem;
+}
\ No newline at end of file
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/_toc.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_toc.scss
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/client/styles/_toc.scss
rename to packages/docs/.vuepress/theme-coreui/src/client/styles/_toc.scss
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/_variables.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/_variables.scss
new file mode 100755
index 00000000..a76e509d
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/_variables.scss
@@ -0,0 +1,37 @@
+// responsive breakpoints
+$MQNarrow: 959px !default;
+$MQMobile: 719px !default;
+$MQMobileNarrow: 419px !default;
+
+// code languages
+$codeLang: 'c' 'cpp' 'cs' 'css' 'dart' 'docker' 'fs' 'go' 'html' 'java' 'js'
+ 'json' 'kt' 'less' 'makefile' 'md' 'php' 'py' 'rb' 'rs' 'sass' 'scss' 'sh'
+ 'styl' 'ts' 'toml' 'vue' 'yml' !default;
+
+
+// stylelint-disable scss/dollar-variable-default
+
+// Local docs variables
+$cd-purple: #4c0bce;
+$cd-violet: lighten(saturate($cd-purple, 5%), 15%); // stylelint-disable-line function-disallowed-list
+$cd-accent: #ffe484;
+
+$cd-gutter-x: 3rem;
+$cd-callout-variants: info, warning, danger !default;
+
+:root {
+ --cui-tertiary-bg: #f0f4f7;
+ --cd-purple: #{$cd-purple};
+ --cd-violet: #{$cd-violet};
+ --cd-accent: #{$cd-accent};
+ --cd-violet-rgb: #{to-rgb($cd-violet)};
+ --cd-accent-rgb: #{to-rgb($cd-accent)};
+ --cd-pink-rgb: #{to-rgb($pink-500)};
+ --cd-teal-rgb: #{to-rgb($teal-500)};
+ --cd-violet-bg: var(--cd-violet);
+ --cd-toc-color: var(--cd-violet);
+ --cd-sidebar-link-bg: rgba(var(--cd-violet-rgb), .1);
+ --cd-callout-link: #{to-rgb($blue-600)};
+ --cd-callout-code-color: #{$pink-600};
+ --cd-pre-bg: var(--cui-tertiary-bg);
+}
diff --git a/docs/.vuepress/theme-coreui/src/client/styles/custom-container.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/custom-container.scss
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/client/styles/custom-container.scss
rename to packages/docs/.vuepress/theme-coreui/src/client/styles/custom-container.scss
diff --git a/packages/docs/.vuepress/theme-coreui/src/client/styles/index.scss b/packages/docs/.vuepress/theme-coreui/src/client/styles/index.scss
new file mode 100755
index 00000000..df73b581
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/client/styles/index.scss
@@ -0,0 +1,24 @@
+@import "@coreui/coreui/scss/coreui.scss";
+@import "@docsearch/css/dist/style.css";
+
+@import "variables";
+
+@import "ads";
+@import "anchor";
+@import "component-examples";
+@import "footer";
+@import "layout";
+@import "prism";
+@import "scrolling";
+@import "search";
+@import "sidebar";
+@import "table-api";
+@import "toc";
+@import "custom-container";
+
+.back-to-top {
+--c-brand: #3eaf7c;
+--c-brand-light: #4abf8a;
+--back-to-top-color: var(--c-brand);
+--back-to-top-color-hover: var(--c-brand-light);
+}
\ No newline at end of file
diff --git a/packages/docs/.vuepress/theme-coreui/src/node/defaultTheme.ts b/packages/docs/.vuepress/theme-coreui/src/node/defaultTheme.ts
new file mode 100755
index 00000000..0886fd22
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/node/defaultTheme.ts
@@ -0,0 +1,89 @@
+import type { Page, Theme } from '@vuepress/core'
+import { activeHeaderLinksPlugin } from '@vuepress/plugin-active-header-links'
+import { backToTopPlugin } from '@vuepress/plugin-back-to-top'
+import { prismjsPlugin } from '@vuepress/plugin-prismjs'
+import { themeDataPlugin } from '@vuepress/plugin-theme-data'
+import { fs, getDirname, path } from '@vuepress/utils'
+import type { DefaultThemeLocaleOptions, DefaultThemePluginsOptions } from '../shared'
+import { assignDefaultLocaleOptions } from './utils'
+
+const __dirname = getDirname(import.meta.url)
+
+export interface DefaultThemeOptions extends DefaultThemeLocaleOptions {
+ /**
+ * To avoid confusion with the root `plugins` option,
+ * we use `themePlugins`
+ */
+ themePlugins?: DefaultThemePluginsOptions
+}
+export const defaultTheme = ({
+ themePlugins = {},
+ ...localeOptions
+}: DefaultThemeOptions = {}): Theme => {
+ assignDefaultLocaleOptions(localeOptions)
+
+ return {
+ name: '@vuepress/coreui-docs-theme',
+
+ templateBuild: path.resolve(__dirname, '../../templates/build.html'),
+
+ alias: {
+ // use alias to make all components replaceable
+ ...Object.fromEntries(
+ fs
+ .readdirSync(path.resolve(__dirname, '../client/components'))
+ .filter((file) => file.endsWith('.vue'))
+ .map((file) => [`@theme/${file}`, path.resolve(__dirname, '../client/components', file)]),
+ ),
+ },
+
+ clientConfigFile: path.resolve(__dirname, '../client/config.ts'),
+
+ extendsPage: (page: Page>) => {
+ // save relative file path into page data to generate edit link
+ page.data.filePathRelative = page.filePathRelative
+ // save title into route meta to generate navbar and sidebar
+ page.routeMeta.title = page.title
+ },
+
+ // layouts: path.resolve(__dirname, '../client/layouts'),
+
+ // clientAppEnhanceFiles: path.resolve(__dirname, '../client/clientAppEnhance.ts'),
+
+ // clientAppSetupFiles: path.resolve(__dirname, '../client/clientAppSetup.ts'),
+
+ // // use the relative file path to generate edit link
+ // extendsPageData: ({ filePathRelative }) => ({ filePathRelative }),
+
+ plugins: [
+ // @vuepress/plugin-active-header-link
+ themePlugins.activeHeaderLinks !== false
+ ? activeHeaderLinksPlugin({
+ headerLinkSelector: 'a.sidebar-item',
+ headerAnchorSelector: '.header-anchor',
+ // should greater than page transition duration
+ delay: 300,
+ })
+ : [],
+
+ // @vuepress/plugin-back-to-top
+ themePlugins.backToTop !== false ? backToTopPlugin() : [],
+
+ // @vuepress/plugin-prismjs
+ themePlugins.prismjs !== false ? prismjsPlugin() : [],
+
+ // @vuepress/plugin-theme-data
+ themeDataPlugin({ themeData: localeOptions }),
+ // [
+ // '@vuepress/active-header-links',
+ // {
+ // headerLinkSelector: 'a.sidebar-item',
+ // headerAnchorSelector: '.anchor-link',
+ // },
+ // ],
+ // ['@vuepress/back-to-top', themePlugins.backToTop !== false],
+ // ['@vuepress/prismjs', themePlugins.prismjs !== false],
+ // ['@vuepress/theme-data', { themeData: localeOptions }],
+ ],
+ }
+}
diff --git a/docs/.vuepress/theme-coreui/src/node/index.ts b/packages/docs/.vuepress/theme-coreui/src/node/index.ts
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/node/index.ts
rename to packages/docs/.vuepress/theme-coreui/src/node/index.ts
diff --git a/docs/.vuepress/theme-coreui/src/node/utils/assignDefaultLocaleOptions.ts b/packages/docs/.vuepress/theme-coreui/src/node/utils/assignDefaultLocaleOptions.ts
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/node/utils/assignDefaultLocaleOptions.ts
rename to packages/docs/.vuepress/theme-coreui/src/node/utils/assignDefaultLocaleOptions.ts
diff --git a/packages/docs/.vuepress/theme-coreui/src/node/utils/index.ts b/packages/docs/.vuepress/theme-coreui/src/node/utils/index.ts
new file mode 100755
index 00000000..8f378cef
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/src/node/utils/index.ts
@@ -0,0 +1 @@
+export * from './assignDefaultLocaleOptions'
diff --git a/docs/.vuepress/theme-coreui/src/shared/index.ts b/packages/docs/.vuepress/theme-coreui/src/shared/index.ts
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/shared/index.ts
rename to packages/docs/.vuepress/theme-coreui/src/shared/index.ts
diff --git a/docs/.vuepress/theme-coreui/src/shared/nav.ts b/packages/docs/.vuepress/theme-coreui/src/shared/nav.ts
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/shared/nav.ts
rename to packages/docs/.vuepress/theme-coreui/src/shared/nav.ts
diff --git a/docs/.vuepress/theme-coreui/src/shared/options.ts b/packages/docs/.vuepress/theme-coreui/src/shared/options.ts
similarity index 100%
rename from docs/.vuepress/theme-coreui/src/shared/options.ts
rename to packages/docs/.vuepress/theme-coreui/src/shared/options.ts
diff --git a/docs/.vuepress/theme-coreui/src/shared/page.ts b/packages/docs/.vuepress/theme-coreui/src/shared/page.ts
similarity index 94%
rename from docs/.vuepress/theme-coreui/src/shared/page.ts
rename to packages/docs/.vuepress/theme-coreui/src/shared/page.ts
index ece43ec8..9feed30c 100755
--- a/docs/.vuepress/theme-coreui/src/shared/page.ts
+++ b/packages/docs/.vuepress/theme-coreui/src/shared/page.ts
@@ -41,4 +41,6 @@ export interface DefaultThemeNormalPageFrontmatter
sidebarDepth?: number
prev?: string | NavLink
next?: string | NavLink
+ pro_component: boolean
+ other_frameworks?: string
}
diff --git a/packages/docs/.vuepress/theme-coreui/templates/build.html b/packages/docs/.vuepress/theme-coreui/templates/build.html
new file mode 100644
index 00000000..8198c3ac
--- /dev/null
+++ b/packages/docs/.vuepress/theme-coreui/templates/build.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/README.md b/packages/docs/README.md
similarity index 100%
rename from docs/README.md
rename to packages/docs/README.md
diff --git a/packages/docs/api/CChart.api.md b/packages/docs/api/CChart.api.md
new file mode 100644
index 00000000..22ddea1a
--- /dev/null
+++ b/packages/docs/api/CChart.api.md
@@ -0,0 +1,30 @@
+### CChart
+
+```jsx
+import { CChart } from '@coreui/vue-chartjs'
+// or
+import CChart from '@coreui/vue-chartjs/src/CChart'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------ | ------- |
+| **custom-tooltips** | Enables custom html based tooltips instead of standard tooltips. `@default` true | boolean | - | true |
+| **data** | The data object that is passed into the Chart.js chart (more info). | ChartData \| ((canvas: HTMLCanvasElement) => ChartData) | - | - |
+| **height** | Height attribute applied to the rendered canvas. `@default` 150 | number | - | 150 |
+| **id** | ID attribute applied to the rendered canvas. | string | - | - |
+| **options** | The options object that is passed into the Chart.js chart. {@link https://www.chartjs.org/docs/latest/general/options.html More Info} | ChartOptions | - | - |
+| **plugins** | The plugins array that is passed into the Chart.js chart (more info) {@link https://www.chartjs.org/docs/latest/developers/plugins.html More Info} | Plugin[] | - | - |
+| **redraw** | If true, will tear down and redraw chart on all updates. | boolean | - | - |
+| **type** | Chart.js chart type. `@type` 'line' \| 'bar' \| 'radar' \| 'doughnut' \| 'polarArea' \| 'bubble' \| 'pie' \| 'scatter' | ChartType | - | 'bar' |
+| **width** | Width attribute applied to the rendered canvas. `@default` 300 | number | - | 300 |
+| **wrapper** | Put the chart into the wrapper div element. `@default` true | boolean | - | true |
+
+#### Events
+
+| Event name | Description | Properties |
+| ------------------------- | ------------------------------------------------------------------------------------------- | ---------- |
+| **get-dataset-at-event** | Proxy for Chart.js getDatasetAtEvent. Calls with dataset and triggering event. |
+| **get-element-at-event** | Proxy for Chart.js getElementAtEvent. Calls with single element array and triggering event. |
+| **get-elements-at-event** | Proxy for Chart.js getElementsAtEvent. Calls with element array and triggering event. |
diff --git a/packages/docs/api/accordion/CAccordion.api.md b/packages/docs/api/accordion/CAccordion.api.md
new file mode 100644
index 00000000..4c30183a
--- /dev/null
+++ b/packages/docs/api/accordion/CAccordion.api.md
@@ -0,0 +1,15 @@
+### CAccordion
+
+```jsx
+import { CAccordion } from '@coreui/vue'
+// or
+import CAccordion from '@coreui/vue/src/components/accordion/CAccordion'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------ | ------- |
+| **active-item-key** | The active item key. | number\|string | - | - |
+| **always-open** | Make accordion items stay open when another item is opened | boolean | - | - |
+| **flush** | Removes the default background-color, some borders, and some rounded corners to render accordions edge-to-edge with their parent container. | boolean | - | - |
diff --git a/packages/docs/api/accordion/CAccordionBody.api.md b/packages/docs/api/accordion/CAccordionBody.api.md
new file mode 100644
index 00000000..a7ff4651
--- /dev/null
+++ b/packages/docs/api/accordion/CAccordionBody.api.md
@@ -0,0 +1,7 @@
+### CAccordionBody
+
+```jsx
+import { CAccordionBody } from '@coreui/vue'
+// or
+import CAccordionBody from '@coreui/vue/src/components/accordion/CAccordionBody'
+```
diff --git a/packages/docs/api/accordion/CAccordionButton.api.md b/packages/docs/api/accordion/CAccordionButton.api.md
new file mode 100644
index 00000000..873e8a2a
--- /dev/null
+++ b/packages/docs/api/accordion/CAccordionButton.api.md
@@ -0,0 +1,7 @@
+### CAccordionButton
+
+```jsx
+import { CAccordionButton } from '@coreui/vue'
+// or
+import CAccordionButton from '@coreui/vue/src/components/accordion/CAccordionButton'
+```
diff --git a/packages/docs/api/accordion/CAccordionHeader.api.md b/packages/docs/api/accordion/CAccordionHeader.api.md
new file mode 100644
index 00000000..844ac370
--- /dev/null
+++ b/packages/docs/api/accordion/CAccordionHeader.api.md
@@ -0,0 +1,7 @@
+### CAccordionHeader
+
+```jsx
+import { CAccordionHeader } from '@coreui/vue'
+// or
+import CAccordionHeader from '@coreui/vue/src/components/accordion/CAccordionHeader'
+```
diff --git a/packages/docs/api/accordion/CAccordionItem.api.md b/packages/docs/api/accordion/CAccordionItem.api.md
new file mode 100644
index 00000000..753acd83
--- /dev/null
+++ b/packages/docs/api/accordion/CAccordionItem.api.md
@@ -0,0 +1,13 @@
+### CAccordionItem
+
+```jsx
+import { CAccordionItem } from '@coreui/vue'
+// or
+import CAccordionItem from '@coreui/vue/src/components/accordion/CAccordionItem'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------ | ------------- | -------------- | ------ | ------- |
+| **item-key** | The item key. | number\|string | - | - |
diff --git a/packages/docs/api/alert/CAlert.api.md b/packages/docs/api/alert/CAlert.api.md
new file mode 100644
index 00000000..140f73d1
--- /dev/null
+++ b/packages/docs/api/alert/CAlert.api.md
@@ -0,0 +1,22 @@
+### CAlert
+
+```jsx
+import { CAlert } from '@coreui/vue'
+// or
+import CAlert from '@coreui/vue/src/components/alert/CAlert'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------------- | ------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **dismissible** | Optionally add a close button to alert and allow it to self dismisss. | boolean | - | - |
+| **variant** | Set the alert variant to a solid. | string | `'solid'` | - |
+| **visible** | Toggle the visibility of alert component. | boolean | - | true |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **close** | Callback fired when the component requests to be closed. |
diff --git a/packages/docs/api/alert/CAlertHeading.api.md b/packages/docs/api/alert/CAlertHeading.api.md
new file mode 100644
index 00000000..30262600
--- /dev/null
+++ b/packages/docs/api/alert/CAlertHeading.api.md
@@ -0,0 +1,13 @@
+### CAlertHeading
+
+```jsx
+import { CAlertHeading } from '@coreui/vue'
+// or
+import CAlertHeading from '@coreui/vue/src/components/alert/CAlertHeading'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h4' |
diff --git a/packages/docs/api/alert/CAlertLink.api.md b/packages/docs/api/alert/CAlertLink.api.md
new file mode 100644
index 00000000..c6fcfae4
--- /dev/null
+++ b/packages/docs/api/alert/CAlertLink.api.md
@@ -0,0 +1,7 @@
+### CAlertLink
+
+```jsx
+import { CAlertLink } from '@coreui/vue'
+// or
+import CAlertLink from '@coreui/vue/src/components/alert/CAlertLink'
+```
diff --git a/packages/docs/api/avatar/CAvatar.api.md b/packages/docs/api/avatar/CAvatar.api.md
new file mode 100644
index 00000000..51491b27
--- /dev/null
+++ b/packages/docs/api/avatar/CAvatar.api.md
@@ -0,0 +1,18 @@
+### CAvatar
+
+```jsx
+import { CAvatar } from '@coreui/vue'
+// or
+import CAvatar from '@coreui/vue/src/components/avatar/CAvatar'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------- | -------------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **shape** | Select the shape of the component. | string | `'rounded'`, `'rounded-top'`, `'rounded-end'`, `'rounded-bottom'`, `'rounded-start'`, `'rounded-circle'`, `'rounded-pill'`, `'rounded-0'`, `'rounded-1'`, `'rounded-2'`, `'rounded-3'` | - |
+| **size** | Size the component small, large, or extra large. | string | `'sm'`, `'md'`, `'lg'`, `'xl'` | - |
+| **src** | The src attribute for the img element. | string | - | - |
+| **status** | Sets the color context of the status indicator to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **text-color** | Sets the text color of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `'white'`, `'muted'`, `'high-emphasis'`, `'medium-emphasis'`, `'disabled'`, `'high-emphasis-inverse'`, `'medium-emphasis-inverse'`, `'disabled-inverse'` | - |
diff --git a/packages/docs/api/backdrop/CBackdrop.api.md b/packages/docs/api/backdrop/CBackdrop.api.md
new file mode 100644
index 00000000..d5e4dfaf
--- /dev/null
+++ b/packages/docs/api/backdrop/CBackdrop.api.md
@@ -0,0 +1,13 @@
+### CBackdrop
+
+```jsx
+import { CBackdrop } from '@coreui/vue'
+// or
+import CBackdrop from '@coreui/vue/src/components/backdrop/CBackdrop'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------- | ----------------------------------------- | ------- | ------ | ------- |
+| **visible** | Toggle the visibility of modal component. | boolean | - | false |
diff --git a/packages/docs/api/badge/CBadge.api.md b/packages/docs/api/badge/CBadge.api.md
new file mode 100644
index 00000000..b9fd90b0
--- /dev/null
+++ b/packages/docs/api/badge/CBadge.api.md
@@ -0,0 +1,18 @@
+### CBadge
+
+```jsx
+import { CBadge } from '@coreui/vue'
+// or
+import CBadge from '@coreui/vue/src/components/badge/CBadge'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------- | --------------------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'span' |
+| **position** | Position badge in one of the corners of a link or button. | string | `'top-start'`, `'top-end'`, `'bottom-end'`, `'bottom-start'` | - |
+| **shape** | Select the shape of the component. | string | `'rounded'`, `'rounded-top'`, `'rounded-end'`, `'rounded-bottom'`, `'rounded-start'`, `'rounded-circle'`, `'rounded-pill'`, `'rounded-0'`, `'rounded-1'`, `'rounded-2'`, `'rounded-3'` | - |
+| **size** | Size the component small. | string | `'sm'` | - |
+| **text-color** | Sets the text color of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `'white'`, `'muted'`, `'high-emphasis'`, `'medium-emphasis'`, `'disabled'`, `'high-emphasis-inverse'`, `'medium-emphasis-inverse'`, `'disabled-inverse'` | - |
diff --git a/packages/docs/api/breadcrumb/CBreadcrumb.api.md b/packages/docs/api/breadcrumb/CBreadcrumb.api.md
new file mode 100644
index 00000000..5aeae206
--- /dev/null
+++ b/packages/docs/api/breadcrumb/CBreadcrumb.api.md
@@ -0,0 +1,7 @@
+### CBreadcrumb
+
+```jsx
+import { CBreadcrumb } from '@coreui/vue'
+// or
+import CBreadcrumb from '@coreui/vue/src/components/breadcrumb/CBreadcrumb'
+```
diff --git a/packages/docs/api/breadcrumb/CBreadcrumbItem.api.md b/packages/docs/api/breadcrumb/CBreadcrumbItem.api.md
new file mode 100644
index 00000000..792d17d6
--- /dev/null
+++ b/packages/docs/api/breadcrumb/CBreadcrumbItem.api.md
@@ -0,0 +1,14 @@
+### CBreadcrumbItem
+
+```jsx
+import { CBreadcrumbItem } from '@coreui/vue'
+// or
+import CBreadcrumbItem from '@coreui/vue/src/components/breadcrumb/CBreadcrumbItem'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------- | -------------------------------------------------- | ------- | ------ | ------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **href** | The `href` attribute for the inner link component. | string | - | - |
diff --git a/packages/docs/api/button-group/CButtonGroup.api.md b/packages/docs/api/button-group/CButtonGroup.api.md
new file mode 100644
index 00000000..cef08210
--- /dev/null
+++ b/packages/docs/api/button-group/CButtonGroup.api.md
@@ -0,0 +1,14 @@
+### CButtonGroup
+
+```jsx
+import { CButtonGroup } from '@coreui/vue'
+// or
+import CButtonGroup from '@coreui/vue/src/components/button-group/CButtonGroup'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------ | ------------------------------------------------------------------------------------------------------------------------------- | ------- | -------------- | ------- |
+| **size** | Size the component small or large. | string | `'sm'`, `'lg'` | - |
+| **vertical** | Create a set of buttons that appear vertically stacked rather than horizontally. Split button dropdowns are not supported here. | boolean | - | - |
diff --git a/packages/docs/api/button-group/CButtonToolbar.api.md b/packages/docs/api/button-group/CButtonToolbar.api.md
new file mode 100644
index 00000000..f5ce68f5
--- /dev/null
+++ b/packages/docs/api/button-group/CButtonToolbar.api.md
@@ -0,0 +1,7 @@
+### CButtonToolbar
+
+```jsx
+import { CButtonToolbar } from '@coreui/vue'
+// or
+import CButtonToolbar from '@coreui/vue/src/components/button-group/CButtonToolbar'
+```
diff --git a/packages/docs/api/button/CButton.api.md b/packages/docs/api/button/CButton.api.md
new file mode 100644
index 00000000..8f8f11ee
--- /dev/null
+++ b/packages/docs/api/button/CButton.api.md
@@ -0,0 +1,27 @@
+### CButton
+
+```jsx
+import { CButton } from '@coreui/vue'
+// or
+import CButton from '@coreui/vue/src/components/button/CButton'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'button' |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **href** | The href attribute specifies the URL of the page the link goes to. | string | - | - |
+| **shape** | Select the shape of the component. | string | `'rounded'`, `'rounded-top'`, `'rounded-end'`, `'rounded-bottom'`, `'rounded-start'`, `'rounded-circle'`, `'rounded-pill'`, `'rounded-0'`, `'rounded-1'`, `'rounded-2'`, `'rounded-3'` | - |
+| **size** | Size the component small or large. | string | `'sm'`, `'lg'` | - |
+| **type** | Specifies the type of button. Always specify the type attribute for the `` element. Different browsers may use different default types for the `` element. | string | `'button'`, `'submit'`, `'reset'` | 'button' |
+| **variant** | Set the button variant to an outlined button or a ghost button. | string | `'ghost'`, `'outline'` | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | ------------------------------------------------ | ---------- |
+| **click** | Event called when the user clicks on the button. |
diff --git a/packages/docs/api/callout/CCallout.api.md b/packages/docs/api/callout/CCallout.api.md
new file mode 100644
index 00000000..77e2cd84
--- /dev/null
+++ b/packages/docs/api/callout/CCallout.api.md
@@ -0,0 +1,13 @@
+### CCallout
+
+```jsx
+import { CCallout } from '@coreui/vue'
+// or
+import CCallout from '@coreui/vue/src/components/callout/CCallout'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
diff --git a/packages/docs/api/card/CCard.api.md b/packages/docs/api/card/CCard.api.md
new file mode 100644
index 00000000..4db75e45
--- /dev/null
+++ b/packages/docs/api/card/CCard.api.md
@@ -0,0 +1,14 @@
+### CCard
+
+```jsx
+import { CCard } from '@coreui/vue'
+// or
+import CCard from '@coreui/vue/src/components/card/CCard'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------- | ------------------------------------------------------------------------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **text-color** | Sets the text color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `'white'`, `'muted'`, `'high-emphasis'`, `'medium-emphasis'`, `'disabled'`, `'high-emphasis-inverse'`, `'medium-emphasis-inverse'`, `'disabled-inverse'` | - |
diff --git a/packages/docs/api/card/CCardBody.api.md b/packages/docs/api/card/CCardBody.api.md
new file mode 100644
index 00000000..3109ba9e
--- /dev/null
+++ b/packages/docs/api/card/CCardBody.api.md
@@ -0,0 +1,7 @@
+### CCardBody
+
+```jsx
+import { CCardBody } from '@coreui/vue'
+// or
+import CCardBody from '@coreui/vue/src/components/card/CCardBody'
+```
diff --git a/packages/docs/api/card/CCardFooter.api.md b/packages/docs/api/card/CCardFooter.api.md
new file mode 100644
index 00000000..448e9f90
--- /dev/null
+++ b/packages/docs/api/card/CCardFooter.api.md
@@ -0,0 +1,7 @@
+### CCardFooter
+
+```jsx
+import { CCardFooter } from '@coreui/vue'
+// or
+import CCardFooter from '@coreui/vue/src/components/card/CCardFooter'
+```
diff --git a/packages/docs/api/card/CCardGroup.api.md b/packages/docs/api/card/CCardGroup.api.md
new file mode 100644
index 00000000..88bf125e
--- /dev/null
+++ b/packages/docs/api/card/CCardGroup.api.md
@@ -0,0 +1,7 @@
+### CCardGroup
+
+```jsx
+import { CCardGroup } from '@coreui/vue'
+// or
+import CCardGroup from '@coreui/vue/src/components/card/CCardGroup'
+```
diff --git a/packages/docs/api/card/CCardHeader.api.md b/packages/docs/api/card/CCardHeader.api.md
new file mode 100644
index 00000000..fb314279
--- /dev/null
+++ b/packages/docs/api/card/CCardHeader.api.md
@@ -0,0 +1,13 @@
+### CCardHeader
+
+```jsx
+import { CCardHeader } from '@coreui/vue'
+// or
+import CCardHeader from '@coreui/vue/src/components/card/CCardHeader'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'div' |
diff --git a/packages/docs/api/card/CCardImage.api.md b/packages/docs/api/card/CCardImage.api.md
new file mode 100644
index 00000000..117d906b
--- /dev/null
+++ b/packages/docs/api/card/CCardImage.api.md
@@ -0,0 +1,14 @@
+### CCardImage
+
+```jsx
+import { CCardImage } from '@coreui/vue'
+// or
+import CCardImage from '@coreui/vue/src/components/card/CCardImage'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------------- | --------------------------------------------------------------------------------------- | ------ | ------------------- | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'img' |
+| **orientation** | Optionally orientate the image to the top, bottom. | string | `'top'`, `'bottom'` | - |
diff --git a/packages/docs/api/card/CCardImageOverlay.api.md b/packages/docs/api/card/CCardImageOverlay.api.md
new file mode 100644
index 00000000..0c860b4b
--- /dev/null
+++ b/packages/docs/api/card/CCardImageOverlay.api.md
@@ -0,0 +1,7 @@
+### CCardImageOverlay
+
+```jsx
+import { CCardImageOverlay } from '@coreui/vue'
+// or
+import CCardImageOverlay from '@coreui/vue/src/components/card/CCardImageOverlay'
+```
diff --git a/packages/docs/api/card/CCardLink.api.md b/packages/docs/api/card/CCardLink.api.md
new file mode 100644
index 00000000..9abdeb57
--- /dev/null
+++ b/packages/docs/api/card/CCardLink.api.md
@@ -0,0 +1,13 @@
+### CCardLink
+
+```jsx
+import { CCardLink } from '@coreui/vue'
+// or
+import CCardLink from '@coreui/vue/src/components/card/CCardLink'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------ | ------ | ------ | ------- |
+| **href** | The href attribute specifies the URL of the page the link goes to. | string | - | '#' |
diff --git a/packages/docs/api/card/CCardSubtitle.api.md b/packages/docs/api/card/CCardSubtitle.api.md
new file mode 100644
index 00000000..92ebf44e
--- /dev/null
+++ b/packages/docs/api/card/CCardSubtitle.api.md
@@ -0,0 +1,13 @@
+### CCardSubtitle
+
+```jsx
+import { CCardSubtitle } from '@coreui/vue'
+// or
+import CCardSubtitle from '@coreui/vue/src/components/card/CCardSubtitle'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h6' |
diff --git a/packages/docs/api/card/CCardText.api.md b/packages/docs/api/card/CCardText.api.md
new file mode 100644
index 00000000..6dc7aaae
--- /dev/null
+++ b/packages/docs/api/card/CCardText.api.md
@@ -0,0 +1,13 @@
+### CCardText
+
+```jsx
+import { CCardText } from '@coreui/vue'
+// or
+import CCardText from '@coreui/vue/src/components/card/CCardText'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'p' |
diff --git a/packages/docs/api/card/CCardTitle.api.md b/packages/docs/api/card/CCardTitle.api.md
new file mode 100644
index 00000000..e2cb5eb4
--- /dev/null
+++ b/packages/docs/api/card/CCardTitle.api.md
@@ -0,0 +1,13 @@
+### CCardTitle
+
+```jsx
+import { CCardTitle } from '@coreui/vue'
+// or
+import CCardTitle from '@coreui/vue/src/components/card/CCardTitle'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h5' |
diff --git a/packages/docs/api/carousel/CCarousel.api.md b/packages/docs/api/carousel/CCarousel.api.md
new file mode 100644
index 00000000..b9c9bd6d
--- /dev/null
+++ b/packages/docs/api/carousel/CCarousel.api.md
@@ -0,0 +1,20 @@
+### CCarousel
+
+```jsx
+import { CCarousel } from '@coreui/vue'
+// or
+import CCarousel from '@coreui/vue/src/components/carousel/CCarousel'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | ------------------------ | ------- |
+| **controls** | Adding in the previous and next controls. | boolean | - | - |
+| **dark** | Add darker controls, indicators, and captions. | boolean | - | - |
+| **index** | index of the active item. | number | - | 0 |
+| **indicators** | Adding indicators at the bottom of the carousel for each item. | boolean | - | - |
+| **interval** | The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle. | boolean\|number | - | 5000 |
+| **pause** | If set to 'hover', pauses the cycling of the carousel on mouseenter and resumes the cycling of the carousel on mouseleave. If set to false, hovering over the carousel won't pause it. | boolean\|string | - | 'hover' |
+| **transition** | Set type of the transition. | string | `'crossfade'`, `'slide'` | 'slide' |
+| **wrap** | Set whether the carousel should cycle continuously or have hard stops. | boolean | - | true |
diff --git a/packages/docs/api/carousel/CCarouselCaption.api.md b/packages/docs/api/carousel/CCarouselCaption.api.md
new file mode 100644
index 00000000..aebeb8f3
--- /dev/null
+++ b/packages/docs/api/carousel/CCarouselCaption.api.md
@@ -0,0 +1,7 @@
+### CCarouselCaption
+
+```jsx
+import { CCarouselCaption } from '@coreui/vue'
+// or
+import CCarouselCaption from '@coreui/vue/src/components/carousel/CCarouselCaption'
+```
diff --git a/packages/docs/api/carousel/CCarouselItem.api.md b/packages/docs/api/carousel/CCarouselItem.api.md
new file mode 100644
index 00000000..9f02bf6b
--- /dev/null
+++ b/packages/docs/api/carousel/CCarouselItem.api.md
@@ -0,0 +1,13 @@
+### CCarouselItem
+
+```jsx
+import { CCarouselItem } from '@coreui/vue'
+// or
+import CCarouselItem from '@coreui/vue/src/components/carousel/CCarouselItem'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------ | ------------------------------------------------------------------ | --------------- | ------ | ------- |
+| **interval** | The amount of time to delay between automatically cycling an item. | boolean\|number | - | false |
diff --git a/packages/docs/api/close-button/CCloseButton.api.md b/packages/docs/api/close-button/CCloseButton.api.md
new file mode 100644
index 00000000..f6da7a9a
--- /dev/null
+++ b/packages/docs/api/close-button/CCloseButton.api.md
@@ -0,0 +1,20 @@
+### CCloseButton
+
+```jsx
+import { CCloseButton } from '@coreui/vue'
+// or
+import CCloseButton from '@coreui/vue/src/components/close-button/CCloseButton'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------ | -------------------------------------------- | ------- | ------ | ------- |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **white** | Change the default color to white. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | --------------------------------------------------- | ---------- |
+| **click** | Event called when the user clicks on the component. |
diff --git a/packages/docs/api/collapse/CCollapse.api.md b/packages/docs/api/collapse/CCollapse.api.md
new file mode 100644
index 00000000..4f0fa2f6
--- /dev/null
+++ b/packages/docs/api/collapse/CCollapse.api.md
@@ -0,0 +1,21 @@
+### CCollapse
+
+```jsx
+import { CCollapse } from '@coreui/vue'
+// or
+import CCollapse from '@coreui/vue/src/components/collapse/CCollapse'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------- | -------------------------------------------------------------------- | ------- | ------ | ------- |
+| **horizontal** | Set horizontal collapsing to transition the width instead of height. | boolean | - | - |
+| **visible** | Toggle the visibility of component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/dropdown/CDropdown.api.md b/packages/docs/api/dropdown/CDropdown.api.md
new file mode 100644
index 00000000..80c1de1d
--- /dev/null
+++ b/packages/docs/api/dropdown/CDropdown.api.md
@@ -0,0 +1,30 @@
+### CDropdown
+
+```jsx
+import { CDropdown } from '@coreui/vue'
+// or
+import CDropdown from '@coreui/vue/src/components/dropdown/CDropdown'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------- |
+| **alignment** | Set aligment of dropdown menu. | string \| Alignments | `{ 'start' \| 'end' \| { xs: 'start' \| 'end' } \| { sm: 'start' \| 'end' } \| { md: 'start' \| 'end' } \| { lg: 'start' \| 'end' } \| { xl: 'start' \| 'end'} \| { xxl: 'start' \| 'end'} }` | - |
+| **auto-close** | Configure the auto close behavior of the dropdown: - `true` - the dropdown will be closed by clicking outside or inside the dropdown menu. - `false` - the dropdown will be closed by clicking the toggle button and manually calling hide or toggle method. (Also will not be closed by pressing esc key) - `'inside'` - the dropdown will be closed (only) by clicking inside the dropdown menu. - `'outside'` - the dropdown will be closed (only) by clicking outside the dropdown menu. | boolean\|string | - | true |
+| **dark** | Sets a darker color scheme to match a dark navbar. | boolean | - | - |
+| **direction** | Sets a specified direction and location of the dropdown menu. | string | `'center'`, `'dropup'`, `'dropup-center'`, `'dropend'`, `'dropstart'` | - |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **offset** 4.9.0+
| Offset of the dropdown menu relative to its target. | array | - | [0, 2] |
+| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | Placement | `'auto'`, `'top-end'`, `'top'`, `'top-start'`, `'bottom-end'`, `'bottom'`, `'bottom-start'`, `'right-start'`, `'right'`, `'right-end'`, `'left-start'`, `'left'`, `'left-end'` | 'bottom-start' |
+| **popper** | If you want to disable dynamic positioning set this property to `true`. | boolean | - | true |
+| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | Triggers | - | 'click' |
+| **variant** | Set the dropdown variant to an btn-group, dropdown, input-group, and nav-item. | string | `'btn-group'`, `'dropdown'`, `'input-group'`, `'nav-item'` | 'btn-group' |
+| **visible** | Toggle the visibility of dropdown menu component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/dropdown/CDropdownDivider.api.md b/packages/docs/api/dropdown/CDropdownDivider.api.md
new file mode 100644
index 00000000..a8c44961
--- /dev/null
+++ b/packages/docs/api/dropdown/CDropdownDivider.api.md
@@ -0,0 +1,7 @@
+### CDropdownDivider
+
+```jsx
+import { CDropdownDivider } from '@coreui/vue'
+// or
+import CDropdownDivider from '@coreui/vue/src/components/dropdown/CDropdownDivider'
+```
diff --git a/packages/docs/api/dropdown/CDropdownHeader.api.md b/packages/docs/api/dropdown/CDropdownHeader.api.md
new file mode 100644
index 00000000..ce854682
--- /dev/null
+++ b/packages/docs/api/dropdown/CDropdownHeader.api.md
@@ -0,0 +1,13 @@
+### CDropdownHeader
+
+```jsx
+import { CDropdownHeader } from '@coreui/vue'
+// or
+import CDropdownHeader from '@coreui/vue/src/components/dropdown/CDropdownHeader'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h6' |
diff --git a/packages/docs/api/dropdown/CDropdownItem.api.md b/packages/docs/api/dropdown/CDropdownItem.api.md
new file mode 100644
index 00000000..d3739469
--- /dev/null
+++ b/packages/docs/api/dropdown/CDropdownItem.api.md
@@ -0,0 +1,16 @@
+### CDropdownItem
+
+```jsx
+import { CDropdownItem } from '@coreui/vue'
+// or
+import CDropdownItem from '@coreui/vue/src/components/dropdown/CDropdownItem'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **href** | The href attribute specifies the URL of the page the link goes to. | string | - | - |
diff --git a/packages/docs/api/dropdown/CDropdownMenu.api.md b/packages/docs/api/dropdown/CDropdownMenu.api.md
new file mode 100644
index 00000000..d283ed5c
--- /dev/null
+++ b/packages/docs/api/dropdown/CDropdownMenu.api.md
@@ -0,0 +1,13 @@
+### CDropdownMenu
+
+```jsx
+import { CDropdownMenu } from '@coreui/vue'
+// or
+import CDropdownMenu from '@coreui/vue/src/components/dropdown/CDropdownMenu'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | --------------- | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | `'div'`, `'ul'` | 'div' |
diff --git a/packages/docs/api/dropdown/CDropdownToggle.api.md b/packages/docs/api/dropdown/CDropdownToggle.api.md
new file mode 100644
index 00000000..14987eae
--- /dev/null
+++ b/packages/docs/api/dropdown/CDropdownToggle.api.md
@@ -0,0 +1,22 @@
+### CDropdownToggle
+
+```jsx
+import { CDropdownToggle } from '@coreui/vue'
+// or
+import CDropdownToggle from '@coreui/vue/src/components/dropdown/CDropdownToggle'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------- | -------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **caret** | Enables pseudo element caret on toggler. | boolean | - | true |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'button' |
+| **custom** | Create a custom toggler which accepts any content. | boolean | - | - |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **size** | Size the component small or large. | string | `'sm'`, `'lg'` | - |
+| **split** | Similarly, create split button dropdowns with virtually the same markup as single button dropdowns, but with the addition of `.dropdown-toggle-split` className for proper spacing around the dropdown caret. | boolean | - | - |
+| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. `@type` 'hover' \| 'focus' \| 'click' | Triggers | - | 'click' |
+| **variant** | Set the button variant to an outlined button or a ghost button. | string | `'ghost'`, `'outline'` | - |
diff --git a/packages/docs/api/footer/CFooter.api.md b/packages/docs/api/footer/CFooter.api.md
new file mode 100644
index 00000000..b1eedef2
--- /dev/null
+++ b/packages/docs/api/footer/CFooter.api.md
@@ -0,0 +1,13 @@
+### CFooter
+
+```jsx
+import { CFooter } from '@coreui/vue'
+// or
+import CFooter from '@coreui/vue/src/components/footer/CFooter'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------ | ------------------------------------- | ------ | --------------------- | ------- |
+| **position** | Place footer in non-static positions. | string | `'fixed'`, `'sticky'` | - |
diff --git a/packages/docs/api/form/CForm.api.md b/packages/docs/api/form/CForm.api.md
new file mode 100644
index 00000000..fdaf792d
--- /dev/null
+++ b/packages/docs/api/form/CForm.api.md
@@ -0,0 +1,13 @@
+### CForm
+
+```jsx
+import { CForm } from '@coreui/vue'
+// or
+import CForm from '@coreui/vue/src/components/form/CForm'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **validated** | Mark a form as validated. If you set it `true`, all validation styles will be applied to the forms component. | boolean | - | - |
diff --git a/packages/docs/api/form/CFormCheck.api.md b/packages/docs/api/form/CFormCheck.api.md
new file mode 100644
index 00000000..1d906212
--- /dev/null
+++ b/packages/docs/api/form/CFormCheck.api.md
@@ -0,0 +1,37 @@
+### CFormCheck
+
+```jsx
+import { CFormCheck } from '@coreui/vue'
+// or
+import CFormCheck from '@coreui/vue/src/components/form/CFormCheck'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ----------------------- | ---------- |
+| **button** | Create button-like checkboxes and radio buttons. `@see` http://coreui.io/vue/docs/components/button.html | object | - | - |
+| **false-value** 4.10.0+
| Use in conjunction with the v-model directive to specify the value that should be assigned to the bound variable when the checkbox is in the `false` state. | string | - | - |
+| **feedback** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-invalid** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-valid** 4.3.0+
| Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **hit-area** | Sets hit area to the full area of the component. | string | - | - |
+| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | string | - | - |
+| **indeterminate** | Input Checkbox indeterminate Property | boolean | - | - |
+| **inline** | Group checkboxes or radios on the same horizontal row by adding. | boolean | - | - |
+| **invalid** | Set component validation state to invalid. | boolean | - | - |
+| **label** | The element represents a caption for a component. | string | - | - |
+| **model-value** | The default name for a value passed using v-model. | array\|boolean\|string | - | - |
+| **reverse** 4.8.0+
| Put checkboxes or radios on the opposite side. | boolean | - | - |
+| **tooltip-feedback** 4.3.0+
| Display validation feedback in a styled tooltip. | boolean | - | - |
+| **true-value** 4.10.0+
| Use in conjunction with the v-model directive to specify the value that should be assigned to the bound variable when the checkbox is in the `true` state. | string | - | - |
+| **type** | Specifies the type of component. | string | `'checkbox'`, `'radio'` | 'checkbox' |
+| **valid** | Set component validation state to valid. | boolean | - | - |
+| **value** | The value attribute of component. | string | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| --------------------- | ----------------------------------------------------- | ---------- |
+| **change** | Event occurs when the checked value has been changed. |
+| **update:modelValue** | Emit the new value whenever there’s a change event. |
diff --git a/packages/docs/api/form/CFormControl.api.md b/packages/docs/api/form/CFormControl.api.md
new file mode 100644
index 00000000..b522760f
--- /dev/null
+++ b/packages/docs/api/form/CFormControl.api.md
@@ -0,0 +1,7 @@
+### CFormControl
+
+```jsx
+import { CFormControl } from '@coreui/vue'
+// or
+import CFormControl from '@coreui/vue/src/components/form/CFormControl'
+```
diff --git a/packages/docs/api/form/CFormControlValidation.api.md b/packages/docs/api/form/CFormControlValidation.api.md
new file mode 100644
index 00000000..09aed3b7
--- /dev/null
+++ b/packages/docs/api/form/CFormControlValidation.api.md
@@ -0,0 +1,18 @@
+### CFormControlValidation
+
+```jsx
+import { CFormControlValidation } from '@coreui/vue'
+// or
+import CFormControlValidation from '@coreui/vue/src/components/form/CFormControlValidation'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **feedback** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-invalid** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-valid** 4.3.0+
| Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **invalid** | Set component validation state to invalid. | boolean | - | - |
+| **tooltip-feedback** 4.3.0+
| Display validation feedback in a styled tooltip. | boolean | - | - |
+| **valid** | Set component validation state to valid. | boolean | - | - |
diff --git a/packages/docs/api/form/CFormControlWrapper.api.md b/packages/docs/api/form/CFormControlWrapper.api.md
new file mode 100644
index 00000000..c4d97891
--- /dev/null
+++ b/packages/docs/api/form/CFormControlWrapper.api.md
@@ -0,0 +1,15 @@
+### CFormControlWrapper
+
+```jsx
+import { CFormControlWrapper } from '@coreui/vue'
+// or
+import CFormControlWrapper from '@coreui/vue/src/components/form/CFormControlWrapper'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **floating-label** 4.3.0+
| Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **label** 4.3.0+
| Add a caption for a component. | string | - | - |
+| **text** 4.3.0+
| Add helper text to the component. | string | - | - |
diff --git a/packages/docs/api/form/CFormFeedback.api.md b/packages/docs/api/form/CFormFeedback.api.md
new file mode 100644
index 00000000..bc45a57d
--- /dev/null
+++ b/packages/docs/api/form/CFormFeedback.api.md
@@ -0,0 +1,16 @@
+### CFormFeedback
+
+```jsx
+import { CFormFeedback } from '@coreui/vue'
+// or
+import CFormFeedback from '@coreui/vue/src/components/form/CFormFeedback'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'div' |
+| **invalid** | Method called immediately after the `value` prop changes. | boolean | - | - |
+| **tooltip** | If your form layout allows it, you can display validation feedback in a styled tooltip. | boolean | - | - |
+| **valid** | Set component validation state to valid. | boolean | - | - |
diff --git a/packages/docs/api/form/CFormFloating.api.md b/packages/docs/api/form/CFormFloating.api.md
new file mode 100644
index 00000000..8a462a15
--- /dev/null
+++ b/packages/docs/api/form/CFormFloating.api.md
@@ -0,0 +1,7 @@
+### CFormFloating
+
+```jsx
+import { CFormFloating } from '@coreui/vue'
+// or
+import CFormFloating from '@coreui/vue/src/components/form/CFormFloating'
+```
diff --git a/packages/docs/api/form/CFormInput.api.md b/packages/docs/api/form/CFormInput.api.md
new file mode 100644
index 00000000..1dfb422b
--- /dev/null
+++ b/packages/docs/api/form/CFormInput.api.md
@@ -0,0 +1,36 @@
+### CFormInput
+
+```jsx
+import { CFormInput } from '@coreui/vue'
+// or
+import CFormInput from '@coreui/vue/src/components/form/CFormInput'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | --------------------------------------- | ------- |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **feedback** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-invalid** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-valid** 4.3.0+
| Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **floating-label** 4.3.0+
| Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | string | - | - |
+| **invalid** | Set component validation state to invalid. | boolean | - | - |
+| **label** 4.3.0+
| Add a caption for a component. | string | - | - |
+| **model-value** | The default name for a value passed using v-model. | File\|number\|string | - | - |
+| **plain-text** | Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. | boolean | - | - |
+| **readonly** | Toggle the readonly state for the component. | boolean | - | - |
+| **size** | Size the component small or large. | string | `'sm' \| 'lg'` | - |
+| **text** 4.3.0+
| Add helper text to the component. | string | - | - |
+| **tooltip-feedback** 4.3.0+
| Display validation feedback in a styled tooltip. | boolean | - | - |
+| **type** | Specifies the type of component. | string | `'color' \| 'file' \| 'text' \| string` | 'text' |
+| **valid** | Set component validation state to valid. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| --------------------- | ------------------------------------------------------------------------------ | ---------- |
+| **change** | Event occurs when the element loses focus, after the content has been changed. |
+| **input** | Event occurs immediately after the value of a component has changed. |
+| **update:modelValue** | Emit the new value whenever there’s an input or change event. |
diff --git a/packages/docs/api/form/CFormLabel.api.md b/packages/docs/api/form/CFormLabel.api.md
new file mode 100644
index 00000000..adc3c93b
--- /dev/null
+++ b/packages/docs/api/form/CFormLabel.api.md
@@ -0,0 +1,13 @@
+### CFormLabel
+
+```jsx
+import { CFormLabel } from '@coreui/vue'
+// or
+import CFormLabel from '@coreui/vue/src/components/form/CFormLabel'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------------------- | --------------------------------------------------------------------------------------------------------- | ------------- | ------ | ------- |
+| **custom-class-name** | A string of all className you want to be applied to the component, and override standard className value. | array\|string | - | - |
diff --git a/packages/docs/api/form/CFormRange.api.md b/packages/docs/api/form/CFormRange.api.md
new file mode 100644
index 00000000..878b82d2
--- /dev/null
+++ b/packages/docs/api/form/CFormRange.api.md
@@ -0,0 +1,27 @@
+### CFormRange
+
+```jsx
+import { CFormRange } from '@coreui/vue'
+// or
+import CFormRange from '@coreui/vue/src/components/form/CFormRange'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------------------------------------------------- | ---------------------------------------------------------------- | ------- | ------ | ------- |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **label** 4.3.0+
| Add a caption for a component. | string | - | - |
+| **max** | Specifies the maximum value for the component. | number | - | - |
+| **min** | Specifies the minimum value for the component. | number | - | - |
+| **model-value** | The default name for a value passed using v-model. | string | - | - |
+| **readonly** | Toggle the readonly state for the component. | boolean | - | - |
+| **steps** | Specifies the interval between legal numbers in the component. | number | - | - |
+| **value** | The `value` attribute of component. `@controllable` onChange | number | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| --------------------- | --------------------------------------------------- | ---------- |
+| **change** | Event occurs when the value has been changed. |
+| **update:modelValue** | Emit the new value whenever there’s a change event. |
diff --git a/packages/docs/api/form/CFormSelect.api.md b/packages/docs/api/form/CFormSelect.api.md
new file mode 100644
index 00000000..8d77c483
--- /dev/null
+++ b/packages/docs/api/form/CFormSelect.api.md
@@ -0,0 +1,33 @@
+### CFormSelect
+
+```jsx
+import { CFormSelect } from '@coreui/vue'
+// or
+import CFormSelect from '@coreui/vue/src/components/form/CFormSelect'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- | -------------- | ------- |
+| **feedback** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-invalid** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-valid** 4.3.0+
| Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **floating-label** 4.3.0+
| Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **html-size** | Specifies the number of visible options in a drop-down list. | number | - | - |
+| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | string | - | - |
+| **invalid** | Set component validation state to invalid. | boolean | - | - |
+| **label** 4.3.0+
| Add a caption for a component. | string | - | - |
+| **model-value** | The default name for a value passed using v-model. | string \| string[] | - | - |
+| **options** | Options list of the select component. Available keys: `label`, `value`, `disabled`. Examples: - `:options="[{ value: 'js', label: 'JavaScript' }, { value: 'html', label: 'HTML', disabled: true }]"` - `:options="['js', 'html']"` | Option[] \| string[] | - | - |
+| **size** | Size the component small or large. | string | `'sm' \| 'lg'` | - |
+| **text** 4.3.0+
| Add helper text to the component. | string | - | - |
+| **tooltip-feedback** 4.3.0+
| Display validation feedback in a styled tooltip. | boolean | - | - |
+| **valid** | Set component validation state to valid. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| --------------------- | ---------------------------------------------------------------------------------- | ---------- |
+| **change** | Event occurs when when a user changes the selected option of a `` element. |
+| **update:modelValue** | Emit the new value whenever there’s a change event. |
diff --git a/packages/docs/api/form/CFormSwitch.api.md b/packages/docs/api/form/CFormSwitch.api.md
new file mode 100644
index 00000000..fc2864c1
--- /dev/null
+++ b/packages/docs/api/form/CFormSwitch.api.md
@@ -0,0 +1,27 @@
+### CFormSwitch
+
+```jsx
+import { CFormSwitch } from '@coreui/vue'
+// or
+import CFormSwitch from '@coreui/vue/src/components/form/CFormSwitch'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------------------------------------------------- | -------------------------------------------------------------------------------------------- | --------------- | ----------------------- | ---------- |
+| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document | string | - | - |
+| **invalid** | Set component validation state to invalid. | boolean | - | - |
+| **label** | The element represents a caption for a component. | string | - | - |
+| **model-value** | The default name for a value passed using v-model. | boolean\|string | - | - |
+| **reverse** 4.8.0+
| Put checkboxes or radios on the opposite side. | boolean | - | - |
+| **size** | Size the component large or extra large. Works only with `switch`. | string | `'lg' \| 'xl'` | - |
+| **type** | Specifies the type of component. | string | `'checkbox'`, `'radio'` | 'checkbox' |
+| **valid** | Set component validation state to valid. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| --------------------- | ----------------------------------------------------- | ---------- |
+| **change** | Event occurs when the checked value has been changed. |
+| **update:modelValue** | Emit the new value whenever there’s a change event. |
diff --git a/packages/docs/api/form/CFormText.api.md b/packages/docs/api/form/CFormText.api.md
new file mode 100644
index 00000000..939772da
--- /dev/null
+++ b/packages/docs/api/form/CFormText.api.md
@@ -0,0 +1,13 @@
+### CFormText
+
+```jsx
+import { CFormText } from '@coreui/vue'
+// or
+import CFormText from '@coreui/vue/src/components/form/CFormText'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'div' |
diff --git a/packages/docs/api/form/CFormTextarea.api.md b/packages/docs/api/form/CFormTextarea.api.md
new file mode 100644
index 00000000..d3bb2949
--- /dev/null
+++ b/packages/docs/api/form/CFormTextarea.api.md
@@ -0,0 +1,34 @@
+### CFormTextarea
+
+```jsx
+import { CFormTextarea } from '@coreui/vue'
+// or
+import CFormTextarea from '@coreui/vue/src/components/form/CFormTextarea'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **feedback** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-invalid** 4.3.0+
| Provide valuable, actionable feedback. | string | - | - |
+| **feedback-valid** 4.3.0+
| Provide valuable, actionable invalid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **floating-label** 4.3.0+
| Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. | string | - | - |
+| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | string | - | - |
+| **invalid** | Set component validation state to invalid. | boolean | - | - |
+| **label** 4.3.0+
| Add a caption for a component. | string | - | - |
+| **model-value** | The default name for a value passed using v-model. | string | - | - |
+| **plain-text** | Render the component styled as plain text. Removes the default form field styling and preserve the correct margin and padding. Recommend to use only along side `readonly`. | boolean | - | - |
+| **readonly** | Toggle the readonly state for the component. | boolean | - | - |
+| **text** 4.3.0+
| Add helper text to the component. | string | - | - |
+| **tooltip-feedback** 4.3.0+
| Display validation feedback in a styled tooltip. | boolean | - | - |
+| **valid** | Set component validation state to valid. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| --------------------- | ------------------------------------------------------------------------------ | ---------- |
+| **change** | Event occurs when the element loses focus, after the content has been changed. |
+| **input** | Event occurs immediately after the value of a component has changed. |
+| **update:modelValue** | Emit the new value whenever there’s an input or change event. |
diff --git a/packages/docs/api/form/CInputGroup.api.md b/packages/docs/api/form/CInputGroup.api.md
new file mode 100644
index 00000000..128ce4f1
--- /dev/null
+++ b/packages/docs/api/form/CInputGroup.api.md
@@ -0,0 +1,13 @@
+### CInputGroup
+
+```jsx
+import { CInputGroup } from '@coreui/vue'
+// or
+import CInputGroup from '@coreui/vue/src/components/form/CInputGroup'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ---------------------------------- | ------ | -------------- | ------- |
+| **size** | Size the component small or large. | string | `'sm'`, `'lg'` | - |
diff --git a/packages/docs/api/form/CInputGroupText.api.md b/packages/docs/api/form/CInputGroupText.api.md
new file mode 100644
index 00000000..a3ad985f
--- /dev/null
+++ b/packages/docs/api/form/CInputGroupText.api.md
@@ -0,0 +1,13 @@
+### CInputGroupText
+
+```jsx
+import { CInputGroupText } from '@coreui/vue'
+// or
+import CInputGroupText from '@coreui/vue/src/components/form/CInputGroupText'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'span' |
diff --git a/packages/docs/api/grid/CCol.api.md b/packages/docs/api/grid/CCol.api.md
new file mode 100644
index 00000000..7ba17d00
--- /dev/null
+++ b/packages/docs/api/grid/CCol.api.md
@@ -0,0 +1,18 @@
+### CCol
+
+```jsx
+import { CCol } from '@coreui/vue'
+// or
+import CCol from '@coreui/vue/src/components/grid/CCol'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
+| **xs** | The number of columns/offset/order on extra small devices (<576px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | - |
+| **sm** | The number of columns/offset/order on small devices (<768px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | - |
+| **md** | The number of columns/offset/order on medium devices (<992px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | - |
+| **lg** | The number of columns/offset/order on large devices (<1200px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | - |
+| **xl** | The number of columns/offset/order on X-Large devices (<1400px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | - |
+| **xxl** | The number of columns/offset/order on XX-Large devices (≥1400px). | Col | `'auto' \| number \| string \| boolean \| { span: 'auto' \| number \| string \| boolean } \| { offset: number \| string } \| { order: 'first' \| 'last' \| number \| string }` | - |
diff --git a/packages/docs/api/grid/CContainer.api.md b/packages/docs/api/grid/CContainer.api.md
new file mode 100644
index 00000000..fc321b95
--- /dev/null
+++ b/packages/docs/api/grid/CContainer.api.md
@@ -0,0 +1,18 @@
+### CContainer
+
+```jsx
+import { CContainer } from '@coreui/vue'
+// or
+import CContainer from '@coreui/vue/src/components/grid/CContainer'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------- | ------- | ------ | ------- |
+| **sm** | Set container 100% wide until small breakpoint. | boolean | - | - |
+| **md** | Set container 100% wide until medium breakpoint. | boolean | - | - |
+| **lg** | Set container 100% wide until large breakpoint. | boolean | - | - |
+| **xl** | Set container 100% wide until X-large breakpoint. | boolean | - | - |
+| **xxl** | Set container 100% wide until XX-large breakpoint. | boolean | - | - |
+| **fluid** | Set container 100% wide, spanning the entire width of the viewport. | boolean | - | - |
diff --git a/packages/docs/api/grid/CRow.api.md b/packages/docs/api/grid/CRow.api.md
new file mode 100644
index 00000000..9510684e
--- /dev/null
+++ b/packages/docs/api/grid/CRow.api.md
@@ -0,0 +1,18 @@
+### CRow
+
+```jsx
+import { CRow } from '@coreui/vue'
+// or
+import CRow from '@coreui/vue/src/components/grid/CRow'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------- | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | ------- |
+| **xs** | The number of columns/offset/order on extra small devices (<576px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | - |
+| **sm** | The number of columns/offset/order on small devices (<768px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | - |
+| **md** | The number of columns/offset/order on medium devices (<992px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | - |
+| **lg** | The number of columns/offset/order on large devices (<1200px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | - |
+| **xl** | The number of columns/offset/order on X-Large devices (<1400px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | - |
+| **xxl** | The number of columns/offset/order on XX-Large devices (≥1400px). | Object as () => BPObject | `{ cols: 'auto' \| number \| string } \| { gutter: number \| string } \| { gutterX: number \| string } \| { gutterY: number \| string }` | - |
diff --git a/packages/docs/api/header/CHeader.api.md b/packages/docs/api/header/CHeader.api.md
new file mode 100644
index 00000000..0416d9ee
--- /dev/null
+++ b/packages/docs/api/header/CHeader.api.md
@@ -0,0 +1,14 @@
+### CHeader
+
+```jsx
+import { CHeader } from '@coreui/vue'
+// or
+import CHeader from '@coreui/vue/src/components/header/CHeader'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ------------------------------------------------------ | --------------- | ------------------------------------------------------------- | ------- |
+| **container** | Defines optional container wrapping children elements. | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'`, `'fluid'` | - |
+| **position** | Place header in non-static positions. | string | `'fixed'`, `'sticky'` | - |
diff --git a/packages/docs/api/header/CHeaderBrand.api.md b/packages/docs/api/header/CHeaderBrand.api.md
new file mode 100644
index 00000000..a87636c5
--- /dev/null
+++ b/packages/docs/api/header/CHeaderBrand.api.md
@@ -0,0 +1,13 @@
+### CHeaderBrand
+
+```jsx
+import { CHeaderBrand } from '@coreui/vue'
+// or
+import CHeaderBrand from '@coreui/vue/src/components/header/CHeaderBrand'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
diff --git a/packages/docs/api/header/CHeaderDivider.api.md b/packages/docs/api/header/CHeaderDivider.api.md
new file mode 100644
index 00000000..d1b28fb9
--- /dev/null
+++ b/packages/docs/api/header/CHeaderDivider.api.md
@@ -0,0 +1,7 @@
+### CHeaderDivider
+
+```jsx
+import { CHeaderDivider } from '@coreui/vue'
+// or
+import CHeaderDivider from '@coreui/vue/src/components/header/CHeaderDivider'
+```
diff --git a/packages/docs/api/header/CHeaderNav.api.md b/packages/docs/api/header/CHeaderNav.api.md
new file mode 100644
index 00000000..1ceb45e3
--- /dev/null
+++ b/packages/docs/api/header/CHeaderNav.api.md
@@ -0,0 +1,13 @@
+### CHeaderNav
+
+```jsx
+import { CHeaderNav } from '@coreui/vue'
+// or
+import CHeaderNav from '@coreui/vue/src/components/header/CHeaderNav'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'ul' |
diff --git a/packages/docs/api/header/CHeaderText.api.md b/packages/docs/api/header/CHeaderText.api.md
new file mode 100644
index 00000000..3c989326
--- /dev/null
+++ b/packages/docs/api/header/CHeaderText.api.md
@@ -0,0 +1,7 @@
+### CHeaderText
+
+```jsx
+import { CHeaderText } from '@coreui/vue'
+// or
+import CHeaderText from '@coreui/vue/src/components/header/CHeaderText'
+```
diff --git a/packages/docs/api/header/CHeaderToggler.api.md b/packages/docs/api/header/CHeaderToggler.api.md
new file mode 100644
index 00000000..8e01dac1
--- /dev/null
+++ b/packages/docs/api/header/CHeaderToggler.api.md
@@ -0,0 +1,7 @@
+### CHeaderToggler
+
+```jsx
+import { CHeaderToggler } from '@coreui/vue'
+// or
+import CHeaderToggler from '@coreui/vue/src/components/header/CHeaderToggler'
+```
diff --git a/packages/docs/api/image/CImage.api.md b/packages/docs/api/image/CImage.api.md
new file mode 100644
index 00000000..bdbc187b
--- /dev/null
+++ b/packages/docs/api/image/CImage.api.md
@@ -0,0 +1,16 @@
+### CImage
+
+```jsx
+import { CImage } from '@coreui/vue'
+// or
+import CImage from '@coreui/vue/src/components/image/CImage'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ---------------------------------------------- | ------- | ------------------------------ | ------- |
+| **align** | Set the horizontal aligment. | string | `'start'`, `'center'`, `'end'` | - |
+| **fluid** | Make image responsive. | boolean | - | - |
+| **rounded** | Make image rounded. | boolean | - | - |
+| **thumbnail** | Give an image a rounded 1px border appearance. | boolean | - | - |
diff --git a/packages/docs/api/link/CLink.api.md b/packages/docs/api/link/CLink.api.md
new file mode 100644
index 00000000..5404dffa
--- /dev/null
+++ b/packages/docs/api/link/CLink.api.md
@@ -0,0 +1,22 @@
+### CLink
+
+```jsx
+import { CLink } from '@coreui/vue'
+// or
+import CLink from '@coreui/vue/src/components/link/CLink'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **href** | The href attribute specifies the URL of the page the link goes to. | string | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | --------------------------------------------------- | ---------- |
+| **click** | Event called when the user clicks on the component. |
diff --git a/packages/docs/api/list-group/CListGroup.api.md b/packages/docs/api/list-group/CListGroup.api.md
new file mode 100644
index 00000000..005ead80
--- /dev/null
+++ b/packages/docs/api/list-group/CListGroup.api.md
@@ -0,0 +1,15 @@
+### CListGroup
+
+```jsx
+import { CListGroup } from '@coreui/vue'
+// or
+import CListGroup from '@coreui/vue/src/components/list-group/CListGroup'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ----------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'ul' |
+| **flush** | Remove some borders and rounded corners to render list group items edge-to-edge in a parent component (e.g., ``) | boolean | - | - |
+| **layout** | Specify a layout type. | string | `'horizontal'`, `'horizontal-sm'`, `'horizontal-md'`, `'horizontal-lg'`, `'horizontal-xl'`, `'horizontal-xxl'`, `` | - |
diff --git a/packages/docs/api/list-group/CListGroupItem.api.md b/packages/docs/api/list-group/CListGroupItem.api.md
new file mode 100644
index 00000000..3cfe1132
--- /dev/null
+++ b/packages/docs/api/list-group/CListGroupItem.api.md
@@ -0,0 +1,16 @@
+### CListGroupItem
+
+```jsx
+import { CListGroupItem } from '@coreui/vue'
+// or
+import CListGroupItem from '@coreui/vue/src/components/list-group/CListGroupItem'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | ------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'li' |
diff --git a/packages/docs/api/modal/CModal.api.md b/packages/docs/api/modal/CModal.api.md
new file mode 100644
index 00000000..7485e03c
--- /dev/null
+++ b/packages/docs/api/modal/CModal.api.md
@@ -0,0 +1,30 @@
+### CModal
+
+```jsx
+import { CModal } from '@coreui/vue'
+// or
+import CModal from '@coreui/vue/src/components/modal/CModal'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------- | ------- |
+| **alignment** | Align the modal in the center or top of the screen. | string | `'top'`, `'center'` | 'top' |
+| **backdrop** | Apply a backdrop on body while offcanvas is open. | boolean\|string | `boolean \| 'static'` | true |
+| **content-class-name** | A string of all className you want applied to the modal content component. | string | - | - |
+| **fullscreen** | Set modal to covers the entire user viewport | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | - |
+| **keyboard** | Closes the modal when escape key is pressed. | boolean | - | true |
+| **scrollable** | Create a scrollable modal that allows scrolling the modal body. | boolean | - | - |
+| **size** | Size the component small, large, or extra large. | string | `'sm'`, `'lg'`, `'xl'` | - |
+| **transition** | Remove animation to create modal that simply appear rather than fade in to view. | boolean | - | true |
+| **unmount-on-close** | By default the component is unmounted after close animation, if you want to keep the component mounted set this property to false. | boolean | - | true |
+| **visible** | Toggle the visibility of alert component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| **close** | Callback fired when the component requests to be closed. |
+| **close-prevented** | Callback fired when the component requests to be closed. |
+| **show** | Callback fired when the modal is shown, its backdrop is static and a click outside the modal or an escape key press is performed with the keyboard option set to false. |
diff --git a/packages/docs/api/modal/CModalBody.api.md b/packages/docs/api/modal/CModalBody.api.md
new file mode 100644
index 00000000..17e58f45
--- /dev/null
+++ b/packages/docs/api/modal/CModalBody.api.md
@@ -0,0 +1,7 @@
+### CModalBody
+
+```jsx
+import { CModalBody } from '@coreui/vue'
+// or
+import CModalBody from '@coreui/vue/src/components/modal/CModalBody'
+```
diff --git a/packages/docs/api/modal/CModalFooter.api.md b/packages/docs/api/modal/CModalFooter.api.md
new file mode 100644
index 00000000..265a5090
--- /dev/null
+++ b/packages/docs/api/modal/CModalFooter.api.md
@@ -0,0 +1,7 @@
+### CModalFooter
+
+```jsx
+import { CModalFooter } from '@coreui/vue'
+// or
+import CModalFooter from '@coreui/vue/src/components/modal/CModalFooter'
+```
diff --git a/packages/docs/api/modal/CModalHeader.api.md b/packages/docs/api/modal/CModalHeader.api.md
new file mode 100644
index 00000000..caede3d5
--- /dev/null
+++ b/packages/docs/api/modal/CModalHeader.api.md
@@ -0,0 +1,13 @@
+### CModalHeader
+
+```jsx
+import { CModalHeader } from '@coreui/vue'
+// or
+import CModalHeader from '@coreui/vue/src/components/modal/CModalHeader'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------- | ------------------------------------------- | ------- | ------ | ------- |
+| **close-button** | Add a close button component to the header. | boolean | - | true |
diff --git a/packages/docs/api/modal/CModalTitle.api.md b/packages/docs/api/modal/CModalTitle.api.md
new file mode 100644
index 00000000..81ba100e
--- /dev/null
+++ b/packages/docs/api/modal/CModalTitle.api.md
@@ -0,0 +1,13 @@
+### CModalTitle
+
+```jsx
+import { CModalTitle } from '@coreui/vue'
+// or
+import CModalTitle from '@coreui/vue/src/components/modal/CModalTitle'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h5' |
diff --git a/packages/docs/api/nav/CNav.api.md b/packages/docs/api/nav/CNav.api.md
new file mode 100644
index 00000000..249b3f6b
--- /dev/null
+++ b/packages/docs/api/nav/CNav.api.md
@@ -0,0 +1,15 @@
+### CNav
+
+```jsx
+import { CNav } from '@coreui/vue'
+// or
+import CNav from '@coreui/vue/src/components/nav/CNav'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ----------------------- | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'ul' |
+| **layout** | Specify a layout type for component. | string | `'fill'`, `'justified'` | - |
+| **variant** | Set the nav variant to tabs or pills. | string | `'tabs'`, `'pills'` | - |
diff --git a/packages/docs/api/nav/CNavGroup.api.md b/packages/docs/api/nav/CNavGroup.api.md
new file mode 100644
index 00000000..3d826283
--- /dev/null
+++ b/packages/docs/api/nav/CNavGroup.api.md
@@ -0,0 +1,20 @@
+### CNavGroup
+
+```jsx
+import { CNavGroup } from '@coreui/vue'
+// or
+import CNavGroup from '@coreui/vue/src/components/nav/CNavGroup'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------- | ------------------------------------------------------------- | ------- | ------ | ------- |
+| **compact** | Make nav group more compact by cutting all `padding` in half. | boolean | - | - |
+| **visible** | Show nav group items. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ------------------ | ----------- | ---------- |
+| **visible-change** | |
diff --git a/packages/docs/api/nav/CNavGroupItems.api.md b/packages/docs/api/nav/CNavGroupItems.api.md
new file mode 100644
index 00000000..c689a0e2
--- /dev/null
+++ b/packages/docs/api/nav/CNavGroupItems.api.md
@@ -0,0 +1,7 @@
+### CNavGroupItems
+
+```jsx
+import { CNavGroupItems } from '@coreui/vue'
+// or
+import CNavGroupItems from '@coreui/vue/src/components/nav/CNavGroupItems'
+```
diff --git a/packages/docs/api/nav/CNavItem.api.md b/packages/docs/api/nav/CNavItem.api.md
new file mode 100644
index 00000000..0be3893c
--- /dev/null
+++ b/packages/docs/api/nav/CNavItem.api.md
@@ -0,0 +1,7 @@
+### CNavItem
+
+```jsx
+import { CNavItem } from '@coreui/vue'
+// or
+import CNavItem from '@coreui/vue/src/components/nav/CNavItem'
+```
diff --git a/packages/docs/api/nav/CNavLink.api.md b/packages/docs/api/nav/CNavLink.api.md
new file mode 100644
index 00000000..748b5bea
--- /dev/null
+++ b/packages/docs/api/nav/CNavLink.api.md
@@ -0,0 +1,15 @@
+### CNavLink
+
+```jsx
+import { CNavLink } from '@coreui/vue'
+// or
+import CNavLink from '@coreui/vue/src/components/nav/CNavLink'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
diff --git a/packages/docs/api/nav/CNavTitle.api.md b/packages/docs/api/nav/CNavTitle.api.md
new file mode 100644
index 00000000..856e314b
--- /dev/null
+++ b/packages/docs/api/nav/CNavTitle.api.md
@@ -0,0 +1,7 @@
+### CNavTitle
+
+```jsx
+import { CNavTitle } from '@coreui/vue'
+// or
+import CNavTitle from '@coreui/vue/src/components/nav/CNavTitle'
+```
diff --git a/packages/docs/api/navbar/CNavbar.api.md b/packages/docs/api/navbar/CNavbar.api.md
new file mode 100644
index 00000000..d907f3fc
--- /dev/null
+++ b/packages/docs/api/navbar/CNavbar.api.md
@@ -0,0 +1,18 @@
+### CNavbar
+
+```jsx
+import { CNavbar } from '@coreui/vue'
+// or
+import CNavbar from '@coreui/vue/src/components/navbar/CNavbar'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------- | --------------------------------------------------------------------------------------- | --------------- | --------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
+| **color-scheme** | Sets if the color of text should be colored for a light or dark dark background. | string | `'dark'`, `'light'` | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'nav' |
+| **container** | Defines optional container wrapping children elements. | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'`, `'fluid'` | - |
+| **expand** | Defines the responsive breakpoint to determine when content collapses. | boolean\|string | `boolean`, `'sm'`, `'md'`, `'lg'`, `'xl'`, `'xxl'` | - |
+| **placement** | Place component in non-static positions. | string | `'fixed-top'`, `'fixed-bottom'`, `'sticky-top'` | - |
diff --git a/packages/docs/api/navbar/CNavbarBrand.api.md b/packages/docs/api/navbar/CNavbarBrand.api.md
new file mode 100644
index 00000000..5d24b0e8
--- /dev/null
+++ b/packages/docs/api/navbar/CNavbarBrand.api.md
@@ -0,0 +1,14 @@
+### CNavbarBrand
+
+```jsx
+import { CNavbarBrand } from '@coreui/vue'
+// or
+import CNavbarBrand from '@coreui/vue/src/components/navbar/CNavbarBrand'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'a' |
+| **href** | The href attribute specifies the URL of the page the link goes to. | string | - | - |
diff --git a/packages/docs/api/navbar/CNavbarNav.api.md b/packages/docs/api/navbar/CNavbarNav.api.md
new file mode 100644
index 00000000..d71b96fc
--- /dev/null
+++ b/packages/docs/api/navbar/CNavbarNav.api.md
@@ -0,0 +1,13 @@
+### CNavbarNav
+
+```jsx
+import { CNavbarNav } from '@coreui/vue'
+// or
+import CNavbarNav from '@coreui/vue/src/components/navbar/CNavbarNav'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'ul' |
diff --git a/packages/docs/api/navbar/CNavbarText.api.md b/packages/docs/api/navbar/CNavbarText.api.md
new file mode 100644
index 00000000..fe71eefd
--- /dev/null
+++ b/packages/docs/api/navbar/CNavbarText.api.md
@@ -0,0 +1,7 @@
+### CNavbarText
+
+```jsx
+import { CNavbarText } from '@coreui/vue'
+// or
+import CNavbarText from '@coreui/vue/src/components/navbar/CNavbarText'
+```
diff --git a/packages/docs/api/navbar/CNavbarToggler.api.md b/packages/docs/api/navbar/CNavbarToggler.api.md
new file mode 100644
index 00000000..a709a452
--- /dev/null
+++ b/packages/docs/api/navbar/CNavbarToggler.api.md
@@ -0,0 +1,7 @@
+### CNavbarToggler
+
+```jsx
+import { CNavbarToggler } from '@coreui/vue'
+// or
+import CNavbarToggler from '@coreui/vue/src/components/navbar/CNavbarToggler'
+```
diff --git a/packages/docs/api/offcanvas/COffcanvas.api.md b/packages/docs/api/offcanvas/COffcanvas.api.md
new file mode 100644
index 00000000..ec04f04e
--- /dev/null
+++ b/packages/docs/api/offcanvas/COffcanvas.api.md
@@ -0,0 +1,25 @@
+### COffcanvas
+
+```jsx
+import { COffcanvas } from '@coreui/vue'
+// or
+import COffcanvas from '@coreui/vue/src/components/offcanvas/COffcanvas'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | --------------- | -------------------------------------------------- | ------- |
+| **backdrop** | Apply a backdrop on body while offcanvas is open. | boolean\|string | `boolean \| 'static'` | true |
+| **keyboard** | Closes the offcanvas when escape key is pressed. | boolean | - | true |
+| **placement** | Components placement, there’s no default placement. | string | `'start'`, `'end'`, `'top'`, `'bottom'` | - |
+| **responsive** 4.7.0+
| Responsive offcanvas property hide content outside the viewport from a specified breakpoint and down. | boolean\|string | `boolean \| 'sm' \| 'md' \| 'lg' \| 'xl' \| 'xxl'` | true |
+| **scroll** | Allow body scrolling while offcanvas is open | boolean | - | false |
+| **visible** | Toggle the visibility of offcanvas component. | boolean | - | false |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/offcanvas/COffcanvasBody.api.md b/packages/docs/api/offcanvas/COffcanvasBody.api.md
new file mode 100644
index 00000000..012b209e
--- /dev/null
+++ b/packages/docs/api/offcanvas/COffcanvasBody.api.md
@@ -0,0 +1,7 @@
+### COffcanvasBody
+
+```jsx
+import { COffcanvasBody } from '@coreui/vue'
+// or
+import COffcanvasBody from '@coreui/vue/src/components/offcanvas/COffcanvasBody'
+```
diff --git a/packages/docs/api/offcanvas/COffcanvasHeader.api.md b/packages/docs/api/offcanvas/COffcanvasHeader.api.md
new file mode 100644
index 00000000..97e87d66
--- /dev/null
+++ b/packages/docs/api/offcanvas/COffcanvasHeader.api.md
@@ -0,0 +1,7 @@
+### COffcanvasHeader
+
+```jsx
+import { COffcanvasHeader } from '@coreui/vue'
+// or
+import COffcanvasHeader from '@coreui/vue/src/components/offcanvas/COffcanvasHeader'
+```
diff --git a/packages/docs/api/offcanvas/COffcanvasTitle.api.md b/packages/docs/api/offcanvas/COffcanvasTitle.api.md
new file mode 100644
index 00000000..48fff654
--- /dev/null
+++ b/packages/docs/api/offcanvas/COffcanvasTitle.api.md
@@ -0,0 +1,13 @@
+### COffcanvasTitle
+
+```jsx
+import { COffcanvasTitle } from '@coreui/vue'
+// or
+import COffcanvasTitle from '@coreui/vue/src/components/offcanvas/COffcanvasTitle'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'h5' |
diff --git a/packages/docs/api/pagination/CPagination.api.md b/packages/docs/api/pagination/CPagination.api.md
new file mode 100644
index 00000000..cfd5eb9c
--- /dev/null
+++ b/packages/docs/api/pagination/CPagination.api.md
@@ -0,0 +1,14 @@
+### CPagination
+
+```jsx
+import { CPagination } from '@coreui/vue'
+// or
+import CPagination from '@coreui/vue/src/components/pagination/CPagination'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------- | ------ | ------------------------------ | ------- |
+| **align** | Set the alignment of pagination components. | string | `'start'`, `'center'`, `'end'` | - |
+| **size** | Size the component small or large. | string | `'sm'`, `'lg'` | - |
diff --git a/packages/docs/api/pagination/CPaginationItem.api.md b/packages/docs/api/pagination/CPaginationItem.api.md
new file mode 100644
index 00000000..fced0268
--- /dev/null
+++ b/packages/docs/api/pagination/CPaginationItem.api.md
@@ -0,0 +1,16 @@
+### CPaginationItem
+
+```jsx
+import { CPaginationItem } from '@coreui/vue'
+// or
+import CPaginationItem from '@coreui/vue/src/components/pagination/CPaginationItem'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **active** | Toggle the active state for the component. | boolean | - | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | - |
+| **disabled** | Toggle the disabled state for the component. | boolean | - | - |
+| **href** | The href attribute specifies the URL of the page the link goes to. | string | - | - |
diff --git a/packages/docs/api/placeholder/CPlaceholder.api.md b/packages/docs/api/placeholder/CPlaceholder.api.md
new file mode 100644
index 00000000..e229a9dc
--- /dev/null
+++ b/packages/docs/api/placeholder/CPlaceholder.api.md
@@ -0,0 +1,22 @@
+### CPlaceholder
+
+```jsx
+import { CPlaceholder } from '@coreui/vue'
+// or
+import CPlaceholder from '@coreui/vue/src/components/placeholder/CPlaceholder'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------- | ------- |
+| **animation** | Set animation type to better convey the perception of something being actively loaded. | string | `'glow'`, `'wave'` | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'span' |
+| **size** | Size the component extra small, small, or large. | string | `'xs'`, `'sm'`, `'lg'` | - |
+| **xs** | The number of columns on extra small devices (<576px). | number | - | - |
+| **sm** | The number of columns on small devices (<768px). | number | - | - |
+| **md** | The number of columns on medium devices (<992px). | number | - | - |
+| **lg** | The number of columns on large devices (<1200px). | number | - | - |
+| **xl** | The number of columns on X-Large devices (<1400px). | number | - | - |
+| **xxl** | The number of columns on XX-Large devices (≥1400px). | number | - | - |
diff --git a/packages/docs/api/popover/CPopover.api.md b/packages/docs/api/popover/CPopover.api.md
new file mode 100644
index 00000000..648449b9
--- /dev/null
+++ b/packages/docs/api/popover/CPopover.api.md
@@ -0,0 +1,28 @@
+### CPopover
+
+```jsx
+import { CPopover } from '@coreui/vue'
+// or
+import CPopover from '@coreui/vue/src/components/popover/CPopover'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------- | ---------------------------------------- |
+| **animation** 4.9.0+
| Apply a CSS fade transition to the popover. | boolean | - | true |
+| **content** | Content for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **delay** 4.9.0+
| The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. | number \| { show: number; hide: number } | - | 0 |
+| **fallback-placements** 4.9.0+
| Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. | Placements \| Placements[] | - | () => ['top', 'right', 'bottom', 'left'] |
+| **offset** | Offset of the popover relative to its target. | array | - | [0, 8] |
+| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | Placement | - | 'top' |
+| **title** | Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | Triggers \| Triggers[] | `'click'`, `'focus'`, `'hover'` | 'click' |
+| **visible** | Toggle the visibility of popover component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/progress/CProgress.api.md b/packages/docs/api/progress/CProgress.api.md
new file mode 100644
index 00000000..3621fe13
--- /dev/null
+++ b/packages/docs/api/progress/CProgress.api.md
@@ -0,0 +1,15 @@
+### CProgress
+
+```jsx
+import { CProgress } from '@coreui/vue'
+// or
+import CProgress from '@coreui/vue/src/components/progress/CProgress'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------- | ------------------------------------------------------------------------------------------------------------------------- | ------- | ------ | ------- |
+| **height** | Sets the height of the component. If you set that value the inner `` will automatically resize accordingly. | number | - | - |
+| **thin** | Makes progress bar thinner. | boolean | - | - |
+| **white** | Change the default color to white. | boolean | - | - |
diff --git a/packages/docs/api/progress/CProgressBar.api.md b/packages/docs/api/progress/CProgressBar.api.md
new file mode 100644
index 00000000..efff5775
--- /dev/null
+++ b/packages/docs/api/progress/CProgressBar.api.md
@@ -0,0 +1,16 @@
+### CProgressBar
+
+```jsx
+import { CProgressBar } from '@coreui/vue'
+// or
+import CProgressBar from '@coreui/vue/src/components/progress/CProgressBar'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------ | ------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | ------- |
+| **animated** | Use to animate the stripes right to left via CSS3 animations. | boolean | - | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **value** | The percent to progress the ProgressBar. | number | - | 0 |
+| **variant** | Set the progress bar variant to optional striped. | string | `'striped'` | - |
diff --git a/packages/docs/api/sidebar/CSidebar.api.md b/packages/docs/api/sidebar/CSidebar.api.md
new file mode 100644
index 00000000..37e6f9ee
--- /dev/null
+++ b/packages/docs/api/sidebar/CSidebar.api.md
@@ -0,0 +1,26 @@
+### CSidebar
+
+```jsx
+import { CSidebar } from '@coreui/vue'
+// or
+import CSidebar from '@coreui/vue/src/components/sidebar/CSidebar'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| -------------- | ------------------------------------------------ | ------- | ------ | ------- |
+| **narrow** | Make sidebar narrow. | boolean | - | - |
+| **overlaid** | Set sidebar to overlaid variant. | boolean | - | - |
+| **position** | Place sidebar in non-static positions. | string | - | - |
+| **size** | Size the component small, large, or extra large. | string | - | - |
+| **unfoldable** | Expand narrowed sidebar on hover. | boolean | - | - |
+| **visible** | Toggle the visibility of sidebar component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ------------------ | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
+| **visible-change** | Event emitted after visibility of component changed. |
diff --git a/packages/docs/api/sidebar/CSidebarBrand.api.md b/packages/docs/api/sidebar/CSidebarBrand.api.md
new file mode 100644
index 00000000..79d69d44
--- /dev/null
+++ b/packages/docs/api/sidebar/CSidebarBrand.api.md
@@ -0,0 +1,7 @@
+### CSidebarBrand
+
+```jsx
+import { CSidebarBrand } from '@coreui/vue'
+// or
+import CSidebarBrand from '@coreui/vue/src/components/sidebar/CSidebarBrand'
+```
diff --git a/packages/docs/api/sidebar/CSidebarFooter.api.md b/packages/docs/api/sidebar/CSidebarFooter.api.md
new file mode 100644
index 00000000..baa1fb7e
--- /dev/null
+++ b/packages/docs/api/sidebar/CSidebarFooter.api.md
@@ -0,0 +1,7 @@
+### CSidebarFooter
+
+```jsx
+import { CSidebarFooter } from '@coreui/vue'
+// or
+import CSidebarFooter from '@coreui/vue/src/components/sidebar/CSidebarFooter'
+```
diff --git a/packages/docs/api/sidebar/CSidebarHeader.api.md b/packages/docs/api/sidebar/CSidebarHeader.api.md
new file mode 100644
index 00000000..efe7681a
--- /dev/null
+++ b/packages/docs/api/sidebar/CSidebarHeader.api.md
@@ -0,0 +1,7 @@
+### CSidebarHeader
+
+```jsx
+import { CSidebarHeader } from '@coreui/vue'
+// or
+import CSidebarHeader from '@coreui/vue/src/components/sidebar/CSidebarHeader'
+```
diff --git a/packages/docs/api/sidebar/CSidebarNav.api.md b/packages/docs/api/sidebar/CSidebarNav.api.md
new file mode 100644
index 00000000..30558957
--- /dev/null
+++ b/packages/docs/api/sidebar/CSidebarNav.api.md
@@ -0,0 +1,7 @@
+### CSidebarNav
+
+```jsx
+import { CSidebarNav } from '@coreui/vue'
+// or
+import CSidebarNav from '@coreui/vue/src/components/sidebar/CSidebarNav'
+```
diff --git a/packages/docs/api/sidebar/CSidebarToggler.api.md b/packages/docs/api/sidebar/CSidebarToggler.api.md
new file mode 100644
index 00000000..00af2ff5
--- /dev/null
+++ b/packages/docs/api/sidebar/CSidebarToggler.api.md
@@ -0,0 +1,7 @@
+### CSidebarToggler
+
+```jsx
+import { CSidebarToggler } from '@coreui/vue'
+// or
+import CSidebarToggler from '@coreui/vue/src/components/sidebar/CSidebarToggler'
+```
diff --git a/packages/docs/api/spinner/CSpinner.api.md b/packages/docs/api/spinner/CSpinner.api.md
new file mode 100644
index 00000000..df9d77ed
--- /dev/null
+++ b/packages/docs/api/spinner/CSpinner.api.md
@@ -0,0 +1,17 @@
+### CSpinner
+
+```jsx
+import { CSpinner } from '@coreui/vue'
+// or
+import CSpinner from '@coreui/vue/src/components/spinner/CSpinner'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------- | --------------------------------------------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------- | ------------ |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'div' |
+| **size** | Size the component small. | string | `'sm'` | - |
+| **variant** | Set the button variant to an outlined button or a ghost button. | string | `'border'`, `'grow'` | 'border' |
+| **visually-hidden-label** | Set visually hidden label for accessibility purposes. | string | - | 'Loading...' |
diff --git a/packages/docs/api/table/CTable.api.md b/packages/docs/api/table/CTable.api.md
new file mode 100644
index 00000000..d66ae093
--- /dev/null
+++ b/packages/docs/api/table/CTable.api.md
@@ -0,0 +1,28 @@
+### CTable
+
+```jsx
+import { CTable } from '@coreui/vue'
+// or
+import CTable from '@coreui/vue/src/components/table/CTable'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | --------------------------------------------------------------------------------------------------------- | ------- |
+| **align** | Set the vertical aligment. | string | `'bottom'`, `'middle'`, `'top'` | - |
+| **border-color** | Sets the border color of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **bordered** | Add borders on all sides of the table and cells. | boolean | - | - |
+| **borderless** | Remove borders on all sides of the table and cells. | boolean | - | - |
+| **caption** | Put the `` on the top of the table. | string | `'top' \| string` | - |
+| **caption-top** 4.5.0+
| Set the text of the table caption and the caption on the top of the table. | string | - | - |
+| **columns** 4.5.0+
| Prop for table columns configuration. If prop is not defined, table will display columns based on the first item keys, omitting keys that begins with underscore (e.g. '\_props') In columns prop each array item represents one column. Item might be specified in two ways: String: each item define column name equal to item value. Object: item is object with following keys available as column configuration: - key (required)(String) - define column name equal to item key. - label (String) - define visible label of column. If not defined, label will be generated automatically based on column name, by converting kebab-case and snake_case to individual words and capitalization of each word. - \_props (Object) - adds classes to all cels in column, ex. \_props: { scope: 'col', className: 'custom-class' }, - \_style (Object) - adds styles to the column header (useful for defining widths) | (Column \| string)[] | - | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
+| **footer** 4.5.0+
| Array of objects or strings, where each element represents one cell in the table footer. Example items: ['FooterCell', 'FooterCell', 'FooterCell'] or [{ label: 'FooterCell', _props: { color: 'success' }, ...] | (FooterItem \| string)[] | - | - |
+| **hover** | Enable a hover state on table rows within a ``. | boolean | - | - |
+| **items** 4.5.0+
| Array of objects, where each object represents one item - row in table. Additionally, you can add style classes to each row by passing them by '\_props' key and to single cell by '\_cellProps'. Example item: { name: 'John' , age: 12, \_props: { color: 'success' }, \_cellProps: { age: { className: 'fw-bold'}}} | Item[] | - | - |
+| **small** | Make table more compact by cutting all cell `padding` in half. | boolean | - | - |
+| **striped** | Add zebra-striping to any table row within the ``. | boolean | - | - |
+| **striped-columns** 4.4.0+
| Add zebra-striping to any table column. | boolean | - | - |
+| **table-foot-props** 4.5.0+
| Properties that will be passed to the table footer component. Properties to [CTableFoot](#ctablefoot) component. | object | - | - |
+| **table-head-props** 4.5.0+
| Properties that will be passed to the table head component. Properties to [CTableHead](#ctablehead) component. | object | - | - |
diff --git a/packages/docs/api/table/CTableBody.api.md b/packages/docs/api/table/CTableBody.api.md
new file mode 100644
index 00000000..36042398
--- /dev/null
+++ b/packages/docs/api/table/CTableBody.api.md
@@ -0,0 +1,13 @@
+### CTableBody
+
+```jsx
+import { CTableBody } from '@coreui/vue'
+// or
+import CTableBody from '@coreui/vue/src/components/table/CTableBody'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
diff --git a/packages/docs/api/table/CTableCaption.api.md b/packages/docs/api/table/CTableCaption.api.md
new file mode 100644
index 00000000..dea077aa
--- /dev/null
+++ b/packages/docs/api/table/CTableCaption.api.md
@@ -0,0 +1,7 @@
+### CTableCaption
+
+```jsx
+import { CTableCaption } from '@coreui/vue'
+// or
+import CTableCaption from '@coreui/vue/src/components/table/CTableCaption'
+```
diff --git a/packages/docs/api/table/CTableDataCell.api.md b/packages/docs/api/table/CTableDataCell.api.md
new file mode 100644
index 00000000..b1409a32
--- /dev/null
+++ b/packages/docs/api/table/CTableDataCell.api.md
@@ -0,0 +1,15 @@
+### CTableDataCell
+
+```jsx
+import { CTableDataCell } from '@coreui/vue'
+// or
+import CTableDataCell from '@coreui/vue/src/components/table/CTableDataCell'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------- | ------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | ------- |
+| **active** | Highlight a table row or cell. | boolean | - | - |
+| **align** | Set the vertical aligment. | string | `'bottom'`, `'middle'`, `'top'` | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
diff --git a/packages/docs/api/table/CTableFoot.api.md b/packages/docs/api/table/CTableFoot.api.md
new file mode 100644
index 00000000..b961f96c
--- /dev/null
+++ b/packages/docs/api/table/CTableFoot.api.md
@@ -0,0 +1,13 @@
+### CTableFoot
+
+```jsx
+import { CTableFoot } from '@coreui/vue'
+// or
+import CTableFoot from '@coreui/vue/src/components/table/CTableFoot'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
diff --git a/packages/docs/api/table/CTableHead.api.md b/packages/docs/api/table/CTableHead.api.md
new file mode 100644
index 00000000..5f7facc3
--- /dev/null
+++ b/packages/docs/api/table/CTableHead.api.md
@@ -0,0 +1,13 @@
+### CTableHead
+
+```jsx
+import { CTableHead } from '@coreui/vue'
+// or
+import CTableHead from '@coreui/vue/src/components/table/CTableHead'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
diff --git a/packages/docs/api/table/CTableHeaderCell.api.md b/packages/docs/api/table/CTableHeaderCell.api.md
new file mode 100644
index 00000000..c1217162
--- /dev/null
+++ b/packages/docs/api/table/CTableHeaderCell.api.md
@@ -0,0 +1,13 @@
+### CTableHeaderCell
+
+```jsx
+import { CTableHeaderCell } from '@coreui/vue'
+// or
+import CTableHeaderCell from '@coreui/vue/src/components/table/CTableHeaderCell'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ------------------------------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
diff --git a/packages/docs/api/table/CTableRow.api.md b/packages/docs/api/table/CTableRow.api.md
new file mode 100644
index 00000000..19670a06
--- /dev/null
+++ b/packages/docs/api/table/CTableRow.api.md
@@ -0,0 +1,15 @@
+### CTableRow
+
+```jsx
+import { CTableRow } from '@coreui/vue'
+// or
+import CTableRow from '@coreui/vue/src/components/table/CTableRow'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------- | ------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | ------- |
+| **active** | Highlight a table row or cell.. | boolean | - | - |
+| **align** | Set the vertical aligment. | string | `'bottom'`, `'middle'`, `'top'` | - |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
diff --git a/packages/docs/api/tabs/CTabContent.api.md b/packages/docs/api/tabs/CTabContent.api.md
new file mode 100644
index 00000000..788d2118
--- /dev/null
+++ b/packages/docs/api/tabs/CTabContent.api.md
@@ -0,0 +1,7 @@
+### CTabContent
+
+```jsx
+import { CTabContent } from '@coreui/vue'
+// or
+import CTabContent from '@coreui/vue/src/components/tabs/CTabContent'
+```
diff --git a/packages/docs/api/tabs/CTabPane.api.md b/packages/docs/api/tabs/CTabPane.api.md
new file mode 100644
index 00000000..61e1db99
--- /dev/null
+++ b/packages/docs/api/tabs/CTabPane.api.md
@@ -0,0 +1,20 @@
+### CTabPane
+
+```jsx
+import { CTabPane } from '@coreui/vue'
+// or
+import CTabPane from '@coreui/vue/src/components/tabs/CTabPane'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------- | ----------------------------------- | ------- | ------ | ------- |
+| **visible** | Toggle the visibility of component. | boolean | - | false |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/toast/CToast.api.md b/packages/docs/api/toast/CToast.api.md
new file mode 100644
index 00000000..6079903e
--- /dev/null
+++ b/packages/docs/api/toast/CToast.api.md
@@ -0,0 +1,26 @@
+### CToast
+
+```jsx
+import { CToast } from '@coreui/vue'
+// or
+import CToast from '@coreui/vue/src/components/toast/CToast'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------------- | ------------------------------------------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------- | ------- |
+| **autohide** | Auto hide the toast. | boolean | - | true |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'`, `string` | - |
+| **delay** | Delay hiding the toast (ms). | number | - | 5000 |
+| **dismissible** | Optionally add a close button to component and allow it to self dismiss. | boolean | - | true |
+| **index** | index of the component. | number | - | - |
+| **title** | Title node for your component. | string | - | - |
+| **visible** | Toggle the visibility of component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **close** | Callback fired when the component requests to be closed. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/toast/CToastBody.api.md b/packages/docs/api/toast/CToastBody.api.md
new file mode 100644
index 00000000..b858d476
--- /dev/null
+++ b/packages/docs/api/toast/CToastBody.api.md
@@ -0,0 +1,7 @@
+### CToastBody
+
+```jsx
+import { CToastBody } from '@coreui/vue'
+// or
+import CToastBody from '@coreui/vue/src/components/toast/CToastBody'
+```
diff --git a/packages/docs/api/toast/CToastClose.api.md b/packages/docs/api/toast/CToastClose.api.md
new file mode 100644
index 00000000..beab2765
--- /dev/null
+++ b/packages/docs/api/toast/CToastClose.api.md
@@ -0,0 +1,19 @@
+### CToastClose
+
+```jsx
+import { CToastClose } from '@coreui/vue'
+// or
+import CToastClose from '@coreui/vue/src/components/toast/CToastClose'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | --------------------------------------------------------------------------------------- | ------ | ------ | ------- |
+| **component** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | ------------------------------------------------------- | ---------- |
+| **close** | Event called before the dissmiss animation has started. |
diff --git a/packages/docs/api/toast/CToastHeader.api.md b/packages/docs/api/toast/CToastHeader.api.md
new file mode 100644
index 00000000..fdd97dc8
--- /dev/null
+++ b/packages/docs/api/toast/CToastHeader.api.md
@@ -0,0 +1,19 @@
+### CToastHeader
+
+```jsx
+import { CToastHeader } from '@coreui/vue'
+// or
+import CToastHeader from '@coreui/vue/src/components/toast/CToastHeader'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------- | ----------------------------------------------- | ------- | ------ | ------- |
+| **close-button** | Automatically add a close button to the header. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | --------------------------------------------- | ---------- |
+| **close** | Event called after clicking the close button. |
diff --git a/packages/docs/api/toast/CToaster.api.md b/packages/docs/api/toast/CToaster.api.md
new file mode 100644
index 00000000..f21a2180
--- /dev/null
+++ b/packages/docs/api/toast/CToaster.api.md
@@ -0,0 +1,13 @@
+### CToaster
+
+```jsx
+import { CToaster } from '@coreui/vue'
+// or
+import CToaster from '@coreui/vue/src/components/toast/CToaster'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ------------- | ------------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------- | ------- |
+| **placement** | Describes the placement of component. | string | `'top-start'`, `'top'`, `'top-end'`, `'middle-start'`, `'middle'`, `'middle-end'`, `'bottom-start'`, `'bottom'`, `'bottom-end'` | - |
diff --git a/packages/docs/api/tooltip/CTooltip.api.md b/packages/docs/api/tooltip/CTooltip.api.md
new file mode 100644
index 00000000..8279d9d3
--- /dev/null
+++ b/packages/docs/api/tooltip/CTooltip.api.md
@@ -0,0 +1,27 @@
+### CTooltip
+
+```jsx
+import { CTooltip } from '@coreui/vue'
+// or
+import CTooltip from '@coreui/vue/src/components/tooltip/CTooltip'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------- | ---------------------------------------- |
+| **animation** 4.9.0+
| Apply a CSS fade transition to the tooltip. | boolean | - | true |
+| **content** | Content for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **delay** 4.9.0+
| The delay for displaying and hiding the popover (in milliseconds). When a numerical value is provided, the delay applies to both the hide and show actions. The object structure for specifying the delay is as follows: delay: `{ 'show': 500, 'hide': 100 }`. | number \| { show: number; hide: number } | - | 0 |
+| **fallback-placements** 4.9.0+
| Specify the desired order of fallback placements by providing a list of placements as an array. The placements should be prioritized based on preference. | Placements \| Placements[] | - | () => ['top', 'right', 'bottom', 'left'] |
+| **offset** | Offset of the tooltip relative to its target. | array | - | [0, 6] |
+| **placement** | Describes the placement of your component after Popper.js has applied all the modifiers that may have flipped or altered the originally provided placement property. | Placement | - | 'top' |
+| **trigger** | Sets which event handlers you’d like provided to your toggle prop. You can specify one trigger or an array of them. | Triggers \| Triggers[] | `'click'`, `'focus'`, `'hover'` | () => ['hover', 'focus'] |
+| **visible** | Toggle the visibility of tooltip component. | boolean | - | - |
+
+#### Events
+
+| Event name | Description | Properties |
+| ---------- | -------------------------------------------------------- | ---------- |
+| **hide** | Callback fired when the component requests to be hidden. |
+| **show** | Callback fired when the component requests to be shown. |
diff --git a/packages/docs/api/widgets/CWidgetStatsA.api.md b/packages/docs/api/widgets/CWidgetStatsA.api.md
new file mode 100644
index 00000000..5bab31a0
--- /dev/null
+++ b/packages/docs/api/widgets/CWidgetStatsA.api.md
@@ -0,0 +1,21 @@
+### CWidgetStatsA
+
+```jsx
+import { CWidgetStatsA } from '@coreui/vue'
+// or
+import CWidgetStatsA from '@coreui/vue/src/components/widgets/CWidgetStatsA'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------ | ------- |
+| **title** | Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **value** | Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
+
+#### Slots
+
+| Name | Description | Bindings |
+| ------ | ------------------------------------------------- | -------- |
+| chart | Location for chart component. | |
+| action | Location for action component, ex. ``. | |
diff --git a/packages/docs/api/widgets/CWidgetStatsB.api.md b/packages/docs/api/widgets/CWidgetStatsB.api.md
new file mode 100644
index 00000000..53c4aaf6
--- /dev/null
+++ b/packages/docs/api/widgets/CWidgetStatsB.api.md
@@ -0,0 +1,17 @@
+### CWidgetStatsB
+
+```jsx
+import { CWidgetStatsB } from '@coreui/vue'
+// or
+import CWidgetStatsB from '@coreui/vue/src/components/widgets/CWidgetStatsB'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **inverse** | Colors have been inverted from their default dark shade. | boolean | - | - |
+| **text** | Helper text for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **title** | Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **value** | Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
diff --git a/packages/docs/api/widgets/CWidgetStatsC.api.md b/packages/docs/api/widgets/CWidgetStatsC.api.md
new file mode 100644
index 00000000..485f5f4f
--- /dev/null
+++ b/packages/docs/api/widgets/CWidgetStatsC.api.md
@@ -0,0 +1,22 @@
+### CWidgetStatsC
+
+```jsx
+import { CWidgetStatsC } from '@coreui/vue'
+// or
+import CWidgetStatsC from '@coreui/vue/src/components/widgets/CWidgetStatsC'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **inverse** | Colors have been inverted from their default dark shade. | boolean | - | - |
+| **title** | Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **value** | Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
+
+#### Slots
+
+| Name | Description | Bindings |
+| ---- | ---------------------------- | -------- |
+| icon | Location for icon component. | |
diff --git a/packages/docs/api/widgets/CWidgetStatsD.api.md b/packages/docs/api/widgets/CWidgetStatsD.api.md
new file mode 100644
index 00000000..6e6835c5
--- /dev/null
+++ b/packages/docs/api/widgets/CWidgetStatsD.api.md
@@ -0,0 +1,21 @@
+### CWidgetStatsD
+
+```jsx
+import { CWidgetStatsD } from '@coreui/vue'
+// or
+import CWidgetStatsD from '@coreui/vue/src/components/widgets/CWidgetStatsD'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ---------- | ------------------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------- | -------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **values** | Values and titles for your component. | Value[] | - | () => [] |
+
+#### Slots
+
+| Name | Description | Bindings |
+| ----- | ----------------------------------------------- | -------- |
+| chart | Location for chart component. | |
+| icon | Location for icon component, ex. ``. | |
diff --git a/packages/docs/api/widgets/CWidgetStatsE.api.md b/packages/docs/api/widgets/CWidgetStatsE.api.md
new file mode 100644
index 00000000..436ec923
--- /dev/null
+++ b/packages/docs/api/widgets/CWidgetStatsE.api.md
@@ -0,0 +1,20 @@
+### CWidgetStatsE
+
+```jsx
+import { CWidgetStatsE } from '@coreui/vue'
+// or
+import CWidgetStatsE from '@coreui/vue/src/components/widgets/CWidgetStatsE'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| --------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ------ | ------- |
+| **title** | Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **value** | Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
+
+#### Slots
+
+| Name | Description | Bindings |
+| ----- | ----------------------------- | -------- |
+| chart | Location for chart component. | |
diff --git a/packages/docs/api/widgets/CWidgetStatsF.api.md b/packages/docs/api/widgets/CWidgetStatsF.api.md
new file mode 100644
index 00000000..49dd0bdb
--- /dev/null
+++ b/packages/docs/api/widgets/CWidgetStatsF.api.md
@@ -0,0 +1,23 @@
+### CWidgetStatsF
+
+```jsx
+import { CWidgetStatsF } from '@coreui/vue'
+// or
+import CWidgetStatsF from '@coreui/vue/src/components/widgets/CWidgetStatsF'
+```
+
+#### Props
+
+| Prop name | Description | Type | Values | Default |
+| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -------------- | ----------------------------------------------------------------------------------------------- | ------- |
+| **color** | Sets the color context of the component to one of CoreUI’s themed colors. | string | `'primary'`, `'secondary'`, `'success'`, `'danger'`, `'warning'`, `'info'`, `'dark'`, `'light'` | - |
+| **padding** | Set padding of your component. | boolean | - | true |
+| **title** | Title for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **text** | Helper text for your component. If you want to pass non-string value please use dedicated slot `... ` | string | - | - |
+| **value** | Value for your component. If you want to pass non-string or non-number value please use dedicated slot `... ` | number\|string | - | 0 |
+
+#### Slots
+
+| Name | Description | Bindings |
+| ---- | ---------------------------- | -------- |
+| icon | Location for icon component. | |
diff --git a/build/.eslintrc.json b/packages/docs/build/.eslintrc.json
similarity index 82%
rename from build/.eslintrc.json
rename to packages/docs/build/.eslintrc.json
index 40605483..b890edff 100644
--- a/build/.eslintrc.json
+++ b/packages/docs/build/.eslintrc.json
@@ -6,7 +6,7 @@
"parserOptions": {
"sourceType": "script"
},
- "extends": "../.eslintrc.js",
+ "extends": "../../../.eslintrc.js",
"rules": {
"no-console": "off",
"strict": "error"
diff --git a/build/buildVscodeHints.js b/packages/docs/build/buildVscodeHints.js
similarity index 100%
rename from build/buildVscodeHints.js
rename to packages/docs/build/buildVscodeHints.js
diff --git a/build/changelog-template.hbs b/packages/docs/build/changelog-template.hbs
similarity index 100%
rename from build/changelog-template.hbs
rename to packages/docs/build/changelog-template.hbs
diff --git a/packages/docs/build/docgen.config.js b/packages/docs/build/docgen.config.js
new file mode 100644
index 00000000..67b35dee
--- /dev/null
+++ b/packages/docs/build/docgen.config.js
@@ -0,0 +1,35 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+'use strict'
+
+const path = require('path')
+// const pkg = require('./../package.json')
+
+module.exports = {
+ componentsRoot: './../../packages', // the folder where CLI will start searching for components.
+ components: [
+ '**/[A-Z]*.ts',
+ '!**/[A-Z]*.d.ts',
+ '!**/[A-Z]*.spec.ts'
+ ],
+ outDir: 'api', // folder to save components docs in (relative to the current working directry)
+ getDocFileName: (componentPath) =>
+ componentPath.replace(/\.ts$/, '.md'), // specify the name of the input md file
+ getDestFile: (file, config) => {
+ return path.join(
+ config.outDir,
+ file.replace('coreui-vue/src/components', '')
+ .replace('coreui-vue-chartjs/src/', '')).replace(/\.ts$/, '.api.md') // specify the name of the output md file
+ },
+ // templates,
+ templates: {
+ // global component template wrapping all others see #templates
+ component: require('./templates/component'),
+ events: require('./templates/events'),
+ props: require('./templates/props'),
+ slots: require('./templates/slots'),
+ },
+ docsRepo: '@coreui/vue',
+ docsBranch: 'main',
+ docsFolder: '',
+ editLinkLabel: 'Edit on github',
+}
\ No newline at end of file
diff --git a/build/templates/component.js b/packages/docs/build/templates/component.js
similarity index 84%
rename from build/templates/component.js
rename to packages/docs/build/templates/component.js
index 2d7fea04..d5f403cf 100644
--- a/build/templates/component.js
+++ b/packages/docs/build/templates/component.js
@@ -1,7 +1,7 @@
'use strict'
module.exports = (renderedUsage, doc, config, fileName, requiresMd, { isSubComponent, hasSubComponents }) => {
- const { displayName, description, docsBlocks, tags, functional } = doc;
+ const { displayName, description, tags, functional } = doc;
const { deprecated, author, since, version, see, link } = tags || {};
const frontMatter = [];
if (!config.outFile && deprecated) {
@@ -13,6 +13,7 @@ module.exports = (renderedUsage, doc, config, fileName, requiresMd, { isSubCompo
// show more than one level on subcomponents
frontMatter.push('sidebarDepth: 2');
}
+
return `${frontMatter.length && !isSubComponent
? `
---
@@ -25,6 +26,13 @@ ${isSubComponent || hasSubComponents ? '#' : ''}### ${deprecated ? `~~${displayN
${deprecated ? `> **Deprecated** ${deprecated[0].description}\n` : ''}
${description ? '> ' + description : ''}
+
+\`\`\`jsx
+import { ${displayName} } from '@coreui/${fileName.replace('coreui-', '').split('/')[0]}'
+// or
+import ${displayName} from '@coreui/${fileName.replace('coreui-', '').replace('.ts', '')}'
+\`\`\`\n
+
${functional ? renderedUsage.functionalTag : ''}
${author ? author.map(a => `Author: ${a.description}\n`) : ''}
${since ? `Since: ${since[0].description}\n` : ''}
@@ -36,7 +44,6 @@ ${renderedUsage.props}
${renderedUsage.methods}
${renderedUsage.events}
${renderedUsage.slots}
-${docsBlocks ? '---\n' + docsBlocks.join('\n---\n') : ''}
${requiresMd.length
? '---\n' + requiresMd.map(component => component.content).join('\n---\n')
diff --git a/build/templates/events.js b/packages/docs/build/templates/events.js
similarity index 72%
rename from build/templates/events.js
rename to packages/docs/build/templates/events.js
index 94f77bb9..56550438 100644
--- a/build/templates/events.js
+++ b/packages/docs/build/templates/events.js
@@ -24,7 +24,9 @@ const tmpl = (events) => {
events.forEach(evt => {
const { description = '', ...e } = evt
const readableProperties = e.properties ? `${formatProperties(e.properties)}` : ''
- ret += `| ${mdclean(e.name)}
| ${mdclean(readableProperties)} | ${mdclean(description)}\n`
+ ret += `| **${e.name.includes('update:') ? mdclean(e.name) : mdclean(e.name.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
+ .map(x => x.toLowerCase())
+ .join('-'))}** | ${mdclean(description)}| ${mdclean(readableProperties)}\n`
})
return ret
}
@@ -33,7 +35,7 @@ module.exports = (events, opt = {}) => {
return `
${opt.isSubComponent || opt.hasSubComponents ? '#' : ''}#### Events
- | Event name | Properties | Description |
+ | Event name | Description | Properties |
| -------------- |--------------- | -------------|
${tmpl(events)}
`
diff --git a/packages/docs/build/templates/props.js b/packages/docs/build/templates/props.js
new file mode 100644
index 00000000..44997ddf
--- /dev/null
+++ b/packages/docs/build/templates/props.js
@@ -0,0 +1,45 @@
+'use strict'
+function mdclean(input) {
+ return input.replace(/\r?\n/g, ' ').replace(/\|/g, '\\|')
+}
+function isTag(v) {
+ return !!v.content;
+}
+const renderTags = (tags) => {
+ if (!tags) {
+ return '';
+ }
+ return Object.entries(tags)
+ .map(([tag, values]) => {
+ return tag !== 'since' ? values.map(v => ` \`@${tag}\` ${isTag(v) ? v.content : v.description}`).join(''): '';
+ })
+ .join('');
+};
+const tmpl = (props) => {
+ let ret = '';
+ const replaceToString = /Color|TextColor|Shape/i;
+ props.forEach(prop => {
+ const name = prop.name
+ let t = prop.description ?? ''
+ t += renderTags(prop.tags)
+ const n = prop.type?.name ?? ''
+ const v = prop.values?.map(pv => `\`${pv}\``).join(', ') ?? '-'
+ const d = prop.defaultValue?.value ?? '-'
+ const since = prop.tags && prop.tags.since ? `${prop.tags.since[0].description}+
` : ''
+
+ if (prop.description && !prop.description.includes('@ignore')) {
+ ret += `| **${mdclean(name.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
+ .map(x => x.toLowerCase())
+ .join('-'))}** ${mdclean(since)} | ${mdclean(t)} | ${mdclean(n.replace(replaceToString, 'string'))} | ${mdclean(v)} | ${mdclean(d.replace('undefined', '-'))} |\n`;
+ }
+ });
+ return ret;
+};
+module.exports = (props, opt = {}) => {
+ return `
+${opt.isSubComponent || opt.hasSubComponents ? '#' : ''}#### Props
+ | Prop name | Description | Type | Values | Default |
+ | ------------- | ----------- | --------- | ----------- | ----------- |
+ ${tmpl(props)}
+ `;
+};
diff --git a/build/templates/slots.js b/packages/docs/build/templates/slots.js
similarity index 100%
rename from build/templates/slots.js
rename to packages/docs/build/templates/slots.js
diff --git a/build/webpack.config.js b/packages/docs/build/webpack.config.js
similarity index 100%
rename from build/webpack.config.js
rename to packages/docs/build/webpack.config.js
diff --git a/packages/docs/components/accordion.md b/packages/docs/components/accordion.md
new file mode 100644
index 00000000..def460c1
--- /dev/null
+++ b/packages/docs/components/accordion.md
@@ -0,0 +1,309 @@
+---
+title: Vue Accordion Component
+name: Accordion
+description: Build vertically collapsing accordions in combination with our Vue Collapse component.
+other_frameworks: accordion
+---
+
+## Examples
+
+Click the accordions below to expand/collapse the accordion content.
+
+::: demo
+
+
+
+ Accordion Item #1
+
+
+ This is the first item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #2
+
+
+ This is the second item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #3
+
+
+ This is the third item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+:::
+```markup
+
+
+
+ Accordion Item #1
+
+
+ This is the first item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #2
+
+
+ This is the second item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #3
+
+
+ This is the third item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+```
+
+### Flush
+
+Add `flush` to remove the default `background-color`, some borders, and some rounded corners to render accordions edge-to-edge with their parent container.
+
+:::demo
+
+
+
+ Accordion Item #1
+
+
+ This is the first item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #2
+
+
+ This is the second item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #3
+
+
+ This is the third item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+:::
+```markup
+
+
+
+ Accordion Item #1
+
+
+ This is the first item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #2
+
+
+ This is the second item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #3
+
+
+ This is the third item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+```
+
+### Always open
+
+Add `always-open` property to make accordion items stay open when another item is opened.
+
+:::demo
+
+
+
+ Accordion Item #1
+
+
+ This is the first item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #2
+
+
+ This is the second item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #3
+
+
+ This is the third item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+:::
+```markup
+
+
+
+ Accordion Item #1
+
+
+ This is the first item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #2
+
+
+ This is the second item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+
+ Accordion Item #3
+
+
+ This is the third item's accordion body. It is hidden by default,
+ until the collapse plugin adds the appropriate classes that we use to style each
+ element. These classes control the overall appearance, as well as the showing and
+ hiding via CSS transitions. You can modify any of this with custom CSS or overriding
+ our default variables. It's also worth noting that just about any HTML can go within
+ the .accordion-body
, though the transition does limit overflow.
+
+
+
+```
+
+## Customizing
+
+### CSS variables
+
+Vue accordions use local CSS variables on `.accordion` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
+## API
+
+!!!include(./api/accordion/CAccordion.api.md)!!!
+
+!!!include(./api/accordion/CAccordionHeader.api.md)!!!
+
+!!!include(./api/accordion/CAccordionBody.api.md)!!!
\ No newline at end of file
diff --git a/packages/docs/components/alert.md b/packages/docs/components/alert.md
new file mode 100644
index 00000000..8575ad96
--- /dev/null
+++ b/packages/docs/components/alert.md
@@ -0,0 +1,296 @@
+---
+title: Vue Alert Component
+description: Vue alert component gives contextual feedback information for common user operations. The alert component is delivered with a bunch of usable and adjustable alert messages.
+other_frameworks: alert
+---
+
+## Examples
+
+Vue Alert is prepared for any length of text, as well as an optional close button. For a styling, use one of the **required** contextual `color` props (e.g., `primary`). For inline dismissal, use the [dismissing prop](#dismissing).
+
+::: demo
+A simple primary alert—check it out!
+A simple secondary alert—check it out!
+A simple success alert—check it out!
+A simple danger alert—check it out!
+A simple warning alert—check it out!
+A simple info alert—check it out!
+A simple light alert—check it out!
+A simple dark alert—check it out!
+:::
+```markup
+A simple primary alert—check it out!
+A simple secondary alert—check it out!
+A simple success alert—check it out!
+A simple danger alert—check it out!
+A simple warning alert—check it out!
+A simple info alert—check it out!
+A simple light alert—check it out!
+A simple dark alert—check it out!
+```
+
+### Live example
+
+Click the button below to show an alert (hidden with inline styles to start), then dismiss (and destroy) it with the built-in close button.
+
+::: demo
+ { liveExampleVisible = false }">A simple primary alert—check it out!
+ { liveExampleVisible = true }">Show live alert
+:::
+```markup
+ { liveExampleVisible = false }">A simple primary alert—check it out!
+ { liveExampleVisible = true }">Show live alert
+```
+
+### Link color
+
+Use the `` component to immediately give matching colored links inside any alert.
+::: demo
+
+ A simple primary alert with an example link . Give it a click if you like.
+
+
+ A simple secondary alert with an example link . Give it a click if you like.
+
+
+ A simple success alert with an example link . Give it a click if you like.
+
+
+ A simple danger alert with an example link . Give it a click if you like.
+
+
+ A simple warning alert with an example link . Give it a click if you like.
+
+
+ A simple info alert with an example link . Give it a click if you like.
+
+
+ A simple light alert with an example link . Give it a click if you like.
+
+
+ A simple dark alert with an example link . Give it a click if you like.
+
+:::
+
+```markup
+
+ A simple primary alert with an example link . Give it a click if you like.
+
+
+ A simple secondary alert with an example link . Give it a click if you like.
+
+
+ A simple success alert with an example link . Give it a click if you like.
+
+
+ A simple danger alert with an example link . Give it a click if you like.
+
+
+ A simple warning alert with an example link . Give it a click if you like.
+
+
+ A simple info alert with an example link . Give it a click if you like.
+
+
+ A simple light alert with an example link . Give it a click if you like.
+
+
+ A simple dark alert with an example link . Give it a click if you like.
+
+```
+
+### Additional content
+
+Alert can also incorporate supplementary HTML elements like heading, paragraph, and divider.
+
+::: demo
+
+ Well done!
+ Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.
+
+ Whenever you need to, be sure to use margin utilities to keep things nice and tidy.
+
+:::
+
+```markup
+
+ Well done!
+ Aww yeah, you successfully read this important alert message. This example text is going to run a bit longer so that you can see how spacing within an alert works with this kind of content.
+
+ Whenever you need to, be sure to use margin utilities to keep things nice and tidy.
+
+```
+### Icons
+
+Similarly, you can use [flexbox utilities](https//coreui.io/docs/4.0/utilities/flex") and [CoreUI Icons](https://icons.coreui.io) to create alerts with icons. Depending on your icons and content, you may want to add more utilities or custom styles.
+
+::: demo
+
+
+
+
+
+ An example alert with an icon
+
+
+:::
+```markup
+
+
+
+
+
+ An example alert with an icon
+
+
+```
+
+Need more than one icon for your alerts? Consider using [CoreUI Icons](https://icons.coreui.io).
+
+::: demo
+
+
+
+ An example alert with an icon
+
+
+
+
+
+ An example success alert with an icon
+
+
+
+
+
+ An example warning alert with an icon
+
+
+
+
+
+ An example danger alert with an icon
+
+
+:::
+```markup
+
+
+
+ An example alert with an icon
+
+
+
+
+
+ An example success alert with an icon
+
+
+
+
+
+ An example warning alert with an icon
+
+
+
+
+
+ An example danger alert with an icon
+
+
+```
+
+### Solid
+
+Use `variant="solid"` to change contextual colors to solid.
+
+::: demo
+A simple solid primary alert—check it out!
+A simple solid secondary alert—check it out!
+A simple solid success alert—check it out!
+A simple solid danger alert—check it out!
+A simple solid warning alert—check it out!
+A simple solid info alert—check it out!
+A simple solid light alert—check it out!
+A simple solid dark alert—check it out!
+:::
+
+```markup
+A simple solid primary alert—check it out!
+A simple solid secondary alert—check it out!
+A simple solid success alert—check it out!
+A simple solid danger alert—check it out!
+A simple solid warning alert—check it out!
+A simple solid info alert—check it out!
+A simple solid light alert—check it out!
+A simple solid dark alert—check it out!
+```
+
+### Dismissing
+
+Alerts can also be easily dismissed. Just add the `dismissible` prop.
+
+::: demo
+
+ Go right ahead and click that dimiss over there on the right.
+
+:::
+
+```markup
+
+ Go right ahead and click that dimiss over there on the right.
+
+
+
+```
+
+
+
+## Customizing
+
+### CSS variables
+
+Vue alerts use local CSS variables on `.alert` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
+## API
+
+!!!include(./api/alert/CAlert.api.md)!!!
+
+!!!include(./api/alert/CAlertHeading.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/avatar.md b/packages/docs/components/avatar.md
similarity index 65%
rename from docs/components/avatar.md
rename to packages/docs/components/avatar.md
index cdad1768..e94d7e27 100644
--- a/docs/components/avatar.md
+++ b/packages/docs/components/avatar.md
@@ -2,6 +2,7 @@
title: Vue Avatar Component
name: Avatar
description: Vue avatar component can be used to display circular user profile pictures. Avatar can be used to portray people or objects. It supports images, icons, or letters.
+other_frameworks: avatar
---
## Image avatars
@@ -19,14 +20,14 @@ description: Vue avatar component can be used to display circular user profile p
## Letter avatars
::: demo
-CUI
+CUI
CUI
-CUI
+CUI
:::
```vue
-CUI
+CUI
CUI
-CUI
+CUI
```
## Rounded avatars
@@ -34,28 +35,28 @@ description: Vue avatar component can be used to display circular user profile p
Use the `shape="rounded"` prop to make avatars squared with rounded corners.
::: demo
-CUI
+CUI
CUI
-CUI
+CUI
:::
```vue
-CUI
+CUI
CUI
-CUI
+CUI
```
## Square avatars
Use the `shape="rounded-0"` prop to make avatars squared.
::: demo
-CUI
+CUI
CUI
-CUI
+CUI
:::
```vue
-CUI
+CUI
CUI
-CUI
+CUI
```
## Sizes
@@ -78,7 +79,8 @@ Fancy larger or smaller avatar? Add `size="xl"`, `size="lg"` or `size="sm"` for
## Avatars with status
::: demo
-
+
+
CUI
:::
```vue
@@ -88,4 +90,4 @@ Fancy larger or smaller avatar? Add `size="xl"`, `size="lg"` or `size="sm"` for
## API
-!!!include(./docs/api/avatar/CAvatar.api.md)!!!
\ No newline at end of file
+!!!include(./api/avatar/CAvatar.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/badge.md b/packages/docs/components/badge.md
similarity index 53%
rename from docs/components/badge.md
rename to packages/docs/components/badge.md
index 88f6b005..5f6a22a0 100644
--- a/docs/components/badge.md
+++ b/packages/docs/components/badge.md
@@ -2,13 +2,14 @@
title: Vue Badge Component
name: Badge
description: Vue badge component is small count and labeling component.
+other_frameworks: badge
---
## Example
Badge component scales to suit the size of the parent element by using relative font sizing and `em` units.
-## Basic usage
+### Basic usage
::: demo
Example heading New
@@ -57,6 +58,83 @@ Unless the context is clear, consider including additional context with a visual
```
+### Positioned
+
+Use `position` prop to modify a component and position it in the corner of a link or button.
+
+::: demo
+
+ Profile
+
+ 99+ unread messages
+
+
+
+ Profile
+
+ 99+ unread messages
+
+
+
+
+ Profile
+
+ 99+ unread messages
+
+
+
+ Profile
+
+ 99+ unread messages
+
+
+:::
+```vue
+
+ Profile
+
+ 99+ unread messages
+
+
+
+ Profile
+
+ 99+ unread messages
+
+
+
+ Profile
+
+ 99+ unread messages
+
+
+
+ Profile
+
+ 99+ unread messages
+
+
+```
+
+You can also create more generic indicators without a counter using a few more utilities.
+
+::: demo
+
+ Profile
+
+ New alerts
+
+
+:::
+```vue
+
+ Profile
+
+ New alerts
+
+
+```
+
## Contextual variations
Add any of the below-mentioned `color` props to modify the presentation of a badge.
@@ -103,6 +181,28 @@ Apply the `shape="rounded-pill"` prop to make badges rounded.
dark
```
+## Customizing
+
+### CSS variables
+
+Vue badges use local CSS variables on `.badges` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/badge/CBadge.api.md)!!!
\ No newline at end of file
+!!!include(./api/badge/CBadge.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/breadcrumb.md b/packages/docs/components/breadcrumb.md
similarity index 85%
rename from docs/components/breadcrumb.md
rename to packages/docs/components/breadcrumb.md
index cba2ab55..02f50c53 100644
--- a/docs/components/breadcrumb.md
+++ b/packages/docs/components/breadcrumb.md
@@ -1,6 +1,8 @@
---
title: Vue Breadcrumb Component
name: Breadcrumb
+description: Vue breadcrumb navigation component which indicates the current location within a navigational hierarchy that automatically adds separators.
+other_frameworks: breadcrumb
---
@@ -105,6 +107,28 @@ Since breadcrumbs provide navigation, it's useful to add a significant label suc
For more information, see the [WAI-ARIA Authoring Practices for the breadcrumb pattern](https://www.w3.org/TR/wai-aria-practices/#breadcrumb).
+## Customizing
+
+### CSS variables
+
+Vue breadcrumbs use local CSS variables on `.breadcrumb` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/breadcrumb/CBreadcrumbItem.api.md)!!!
\ No newline at end of file
+!!!include(./api/breadcrumb/CBreadcrumbItem.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/button-group.md b/packages/docs/components/button-group.md
similarity index 79%
rename from docs/components/button-group.md
rename to packages/docs/components/button-group.md
index f071564e..64d66009 100644
--- a/docs/components/button-group.md
+++ b/packages/docs/components/button-group.md
@@ -2,6 +2,7 @@
title: Vue Button Group Component
name: Button group
description: Vue button group component allows to group a series of buttons and power them with JavaScript.
+other_frameworks: button-group
---
## Basic example
@@ -86,46 +87,31 @@ Combine button-like checkbox and radio toggle buttons into a seamless looking bu
::: demo
-
-
-
+
+
+
:::
```vue
-
-
-
+
+
+
```
::: demo
-
-
-
+
+
+
:::
```vue
-
-
-
-
-```
-
-::: demo
-
-
-
-
-
-:::
-```vue
-
-
-
-
+
+
+
```
@@ -231,48 +217,46 @@ Alternatively, of implementing button sizing classes to each button in a group,
::: demo
- Left
- Middle
- Right
+ Left
+ Middle
+ Right
- Left
- Middle
- Right
+ Left
+ Middle
+ Right
- Left
- Middle
- Right
+ Left
+ Middle
+ Right
:::
```vue
- Left
- Middle
- Right
+ Left
+ Middle
+ Right
- Left
- Middle
- Right
+ Left
+ Middle
+ Right
- Left
- Middle
- Right
+ Left
+ Middle
+ Right
```
## Nesting
-TODO: fix dropdown examples
-
-Put a `` inside another `` when you need dropdown menus combined with a series of buttons.
+Put a `` inside `` when you need dropdown menus combined with a series of buttons.
::: demo
@@ -433,19 +417,19 @@ Create a set of buttons that appear vertically stacked rather than horizontally.
::: demo
-
-
-
+
+
+
:::
```vue
-
-
-
+
+
+
```
## API
-!!!include(./docs/api/button-group/CButtonGroup.api.md)!!!
\ No newline at end of file
+!!!include(./api/button-group/CButtonGroup.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/button.md b/packages/docs/components/button.md
similarity index 93%
rename from docs/components/button.md
rename to packages/docs/components/button.md
index c8a6114d..05a3d5dc 100644
--- a/docs/components/button.md
+++ b/packages/docs/components/button.md
@@ -2,7 +2,7 @@
title: Vue Buttons Component
name: Buttons
description: Vue button component for actions in tables, forms, cards, and more. CoreUI for Vue.js provides various styles, states, and size. Ready to use and easy to customize.
-
+other_frameworks: button
---
## Examples
@@ -114,7 +114,8 @@ If you need a ghost variant of button, set `variant="ghost"` prop to remove all
Dark
```
-CALLOUT: Some of the button styles use a relatively light foreground color, and should only be used on a dark background in order to have sufficient contrast.
+
+Some of the button styles use a relatively light foreground color, and should only be used on a dark background in order to have sufficient contrast.
## Sizes
@@ -271,6 +272,29 @@ Additional utilities can be used to adjust the alignment of buttons when horizon
```
+## Customizing
+
+### CSS variables
+
+Vue buttons use local CSS variables on `.btn` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/button/CButton.api.md)!!!
\ No newline at end of file
+!!!include(./api/button/CButton.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/callout.md b/packages/docs/components/callout.md
similarity index 86%
rename from docs/components/callout.md
rename to packages/docs/components/callout.md
index 5e0c6713..5066f13f 100644
--- a/docs/components/callout.md
+++ b/packages/docs/components/callout.md
@@ -2,7 +2,7 @@
title: Vue Callout Component
name: Callout
description: Vue callout component provides presentation of content in a visually distinct manner. Includes a heading, icon and typically text-based content.
-
+other_frameworks: callout
---
## Examples
@@ -69,6 +69,28 @@ Callout component is prepared for any length of text, as well as an optional ele
+## Customizing
+
+### CSS variables
+
+Vue callouts use local CSS variables on `.callout` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/callout/CCallout.api.md)!!!
\ No newline at end of file
+!!!include(./api/callout/CCallout.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/card.md b/packages/docs/components/card.md
similarity index 64%
rename from docs/components/card.md
rename to packages/docs/components/card.md
index d277964d..591ab009 100644
--- a/docs/components/card.md
+++ b/packages/docs/components/card.md
@@ -2,7 +2,7 @@
title: Vue Card Component
name: Card
description: Vue card component provides a flexible and extensible container for displaying content. Card is delivered with a bunch of variants and options.
-
+other_frameworks: card
---
## Examples
@@ -20,7 +20,7 @@ Below is an example of a basic card with mixed content and a fixed width. Cards
::: demo
- Placeholder Image cap
+
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
@@ -30,7 +30,7 @@ Below is an example of a basic card with mixed content and a fixed width. Cards
:::
```vue
- Placeholder Image cap
+
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
@@ -96,7 +96,7 @@ Subtitles are managed by `` component. If the `` also
::: demo
- Placeholder Image cap
+
Some quick example text to build on the card title and make up the bulk of the card's content.
@@ -104,7 +104,7 @@ Subtitles are managed by `` component. If the `` also
:::
```vue
- Placeholder Image cap
+
Some quick example text to build on the card title and make up the bulk of the card's content.
@@ -181,7 +181,7 @@ Combine and match many content types to build the card you need, or throw everyt
::: demo
- Placeholder Image cap
+
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
@@ -199,7 +199,7 @@ Combine and match many content types to build the card you need, or throw everyt
:::
```vue
- Placeholder Image cap
+
Card title
Some quick example text to build on the card title and make up the bulk of the card's content.
@@ -634,7 +634,7 @@ Similar to headers and footers, cards can include top and bottom "image caps"—
::: demo
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -647,12 +647,12 @@ Similar to headers and footers, cards can include top and bottom "image caps"—
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
Last updated 3 mins ago
- Placeholder Image cap
+
:::
```vue
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -665,7 +665,7 @@ Similar to headers and footers, cards can include top and bottom "image caps"—
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
Last updated 3 mins ago
- Placeholder Image cap
+
```
@@ -675,7 +675,7 @@ Adapt an image into a background and overlay your text. Depending on the image,
::: demo
- Placeholder Image
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -685,7 +685,7 @@ Adapt an image into a background and overlay your text. Depending on the image,
:::
```vue
- Placeholder Image
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -702,7 +702,7 @@ Using a combination of grid and utility classes, cards can be made horizontal in
- Placeholder Image
+
@@ -718,7 +718,7 @@ Using a combination of grid and utility classes, cards can be made horizontal in
- Placeholder Image
+
@@ -750,7 +750,7 @@ Use `color` property to change the appearance of a card.
{ color: 'light' },
{ color: 'dark', textColor: 'white' }
]">
-
+
Header
{{item.color}} card title
@@ -770,7 +770,7 @@ Use `color` property to change the appearance of a card.
{ color: 'light' },
{ color: 'dark', textColor: 'white' }
]">
-
+
Header
{{item.color}} card title
@@ -789,7 +789,7 @@ Use `color` property to change the appearance of a card.
### Border
-Use [border utilities](https://coreui.io/docs/utilities/borders/) to change just the `border-color` of a card. Note that you can set `textColor` property on the `` or a subset of the card's contents as shown below.
+Use [border utilities](https://coreui.io/docs/utilities/borders/) to change just the `border-color` of a card. Note that you can set `text-color` property on the `` or a subset of the card's contents as shown below.
::: demo
-
+
Header
{{item.color}} card title
@@ -822,7 +822,7 @@ Use [border utilities](https://coreui.io/docs/utilities/borders/) to change just
{ color: 'light'},
{ color: 'dark'}
]">
-
+
Header
{{item.color}} card title
@@ -845,7 +845,7 @@ Use [border utilities](https://coreui.io/docs/utilities/borders/) to change just
{ color: 'light'},
{ color: 'dark'}
]">
-
+
Header
{{item.color}} card title
@@ -865,7 +865,7 @@ Use [border utilities](https://coreui.io/docs/utilities/borders/) to change just
{ color: 'light'},
{ color: 'dark'}
]">
-
+
Header
{{item.color}} card title
@@ -886,7 +886,7 @@ Use card groups to render cards as a single, attached element with equal width a
::: demo
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -894,7 +894,7 @@ Use card groups to render cards as a single, attached element with equal width a
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -902,7 +902,7 @@ Use card groups to render cards as a single, attached element with equal width a
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -914,7 +914,7 @@ Use card groups to render cards as a single, attached element with equal width a
```vue
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -922,7 +922,7 @@ Use card groups to render cards as a single, attached element with equal width a
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -930,7 +930,7 @@ Use card groups to render cards as a single, attached element with equal width a
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -945,7 +945,7 @@ When using card groups with footers, their content will automatically line up.
::: demo
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -953,7 +953,7 @@ When using card groups with footers, their content will automatically line up.
Last updated 3 mins ago
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -961,7 +961,7 @@ When using card groups with footers, their content will automatically line up.
Last updated 3 mins ago
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -973,7 +973,7 @@ When using card groups with footers, their content will automatically line up.
```vue
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -981,7 +981,7 @@ When using card groups with footers, their content will automatically line up.
Last updated 3 mins ago
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -989,7 +989,7 @@ When using card groups with footers, their content will automatically line up.
Last updated 3 mins ago
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -1007,7 +1007,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1017,7 +1017,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1027,7 +1027,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1037,7 +1037,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1051,7 +1051,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1061,7 +1061,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1071,7 +1071,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1081,7 +1081,7 @@ Use the `CRow` component and set `:xs|sm|md|lg|xl|xxl="{ cols: * }"` property to
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1098,7 +1098,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1108,7 +1108,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1118,7 +1118,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1128,7 +1128,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1142,7 +1142,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1152,7 +1152,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1162,7 +1162,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1172,7 +1172,7 @@ Change it to `:md="{ cols: 3}"` and you'll see the fourth card wrap.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1189,7 +1189,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1198,7 +1198,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -1207,7 +1207,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -1216,7 +1216,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1229,7 +1229,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1238,7 +1238,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -1247,7 +1247,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -1256,7 +1256,7 @@ When you need equal height, add `.h-100` to the cards. If you want equal heights
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1272,7 +1272,7 @@ Just like with card groups, card footers will automatically line up.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1282,7 +1282,7 @@ Just like with card groups, card footers will automatically line up.
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -1292,7 +1292,7 @@ Just like with card groups, card footers will automatically line up.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -1306,7 +1306,7 @@ Just like with card groups, card footers will automatically line up.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.
@@ -1316,7 +1316,7 @@ Just like with card groups, card footers will automatically line up.
- Placeholder Image cap
+
Card title
This card has supporting text below as a natural lead-in to additional content.
@@ -1326,7 +1326,7 @@ Just like with card groups, card footers will automatically line up.
- Placeholder Image cap
+
Card title
This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.
@@ -1337,16 +1337,38 @@ Just like with card groups, card footers will automatically line up.
```
+## Customizing
+
+### CSS variables
+
+Vue cards use local CSS variables on `.card` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/card/CCard.api.md)!!!
+!!!include(./api/card/CCard.api.md)!!!
-!!!include(./docs/api/card/CCardHeader.api.md)!!!
+!!!include(./api/card/CCardHeader.api.md)!!!
-!!!include(./docs/api/card/CCardImage.api.md)!!!
+!!!include(./api/card/CCardImage.api.md)!!!
-!!!include(./docs/api/card/CCardSubtitle.api.md)!!!
+!!!include(./api/card/CCardSubtitle.api.md)!!!
-!!!include(./docs/api/card/CCardText.api.md)!!!
+!!!include(./api/card/CCardText.api.md)!!!
-!!!include(./docs/api/card/CCardTitle.api.md)!!!
\ No newline at end of file
+!!!include(./api/card/CCardTitle.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/carousel.md b/packages/docs/components/carousel.md
similarity index 97%
rename from docs/components/carousel.md
rename to packages/docs/components/carousel.md
index f4592b2e..10b207e4 100644
--- a/docs/components/carousel.md
+++ b/packages/docs/components/carousel.md
@@ -2,6 +2,7 @@
title: Vue Carousel Component
name: Carousel
description: Vue carousel is a slideshow component for cycling through elements—images or slides of text—like a carousel.
+other_frameworks: carousel
---
## How it works
@@ -196,8 +197,6 @@ Add `transition="crossfade"` to your carousel to animate slides with a fade tran
Add `dark` property to the `CCarousel` for darker controls, indicators, and captions. Controls have been inverted from their default white fill with the `filter` CSS property. Captions and controls have additional Sass variables that customize the `color` and `background-color`.
-
-
::: demo
@@ -225,6 +224,14 @@ Add `dark` property to the `CCarousel` for darker controls, indicators, and capt
```
+## Customizing
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/carousel/CCarousel.api.md)!!!
\ No newline at end of file
+!!!include(./api/carousel/CCarousel.api.md)!!!
+
+!!!include(./api/carousel/CCarouselItem.api.md)!!!
\ No newline at end of file
diff --git a/packages/docs/components/chart.md b/packages/docs/components/chart.md
new file mode 100644
index 00000000..181f6635
--- /dev/null
+++ b/packages/docs/components/chart.md
@@ -0,0 +1,668 @@
+---
+title: Vue Chart.js Component
+description: Vue wrapper for Chart.js 3.0, the most popular charting library.
+---
+
+## Installation
+
+If you want to use our Chart.js Vue wrapper you have to install an additional package.
+
+### Npm
+
+```bash
+npm install @coreui/vue-chartjs
+```
+
+### Yarn
+
+```bash
+yarn add @coreui/vue-chartjs
+```
+
+## Chart Types
+
+### Line Chart
+
+A line chart is a way of plotting data points on a line. Often, it is used to show trend data, or the comparison of two data sets.
+[Line Chart properties](https://www.chartjs.org/docs/latest/charts/line.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+```
+
+### Bar Chart
+
+A bar chart provides a way of showing data values represented as vertical bars. It is sometimes used to show trend data, and the comparison of multiple data sets side by side. [Bar Chart properties](https://www.chartjs.org/docs/latest/charts/bar.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+```
+
+### Radar Chart
+
+A radar chart is a way of showing multiple data points and the variation between them. They are often useful for comparing the points of two or more different data sets. [Radar Chart properties](https://www.chartjs.org/docs/latest/charts/radar.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+```
+
+### Doughnut and Pie Charts
+
+Pie and doughnut charts are probably the most commonly used charts. They are divided into segments, the arc of each segment shows the proportional value of each piece of data. [Doughnut and Pie Charts properties](https://www.chartjs.org/docs/latest/charts/doughnut.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+```
+
+::: demo
+
+:::
+```vue
+
+```
+
+### Polar Area Chart
+
+Polar area charts are similar to pie charts, but each segment has the same angle - the radius of the segment differs depending on the value. [Polar Area Chart properties](https://www.chartjs.org/docs/latest/charts/polar.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+```
+
+### Bubble Chart
+
+A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles. [Bubble Chart properties](https://www.chartjs.org/docs/latest/charts/bubble.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+```
+
+
+### Scatter Chart
+
+A bubble chart is used to display three dimensions of data at the same time. The location of the bubble is determined by the first two dimensions and the corresponding horizontal and vertical axes. The third dimension is represented by the size of the individual bubbles. [Scatter Chart properties](https://www.chartjs.org/docs/latest/charts/scatter.html#dataset-properties)
+
+::: demo
+
+:::
+```vue
+
+
+```
+
+
+
+## API
+
+!!!include(./api/CChart.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/close-button.md b/packages/docs/components/close-button.md
similarity index 91%
rename from docs/components/close-button.md
rename to packages/docs/components/close-button.md
index 46672949..d6c71301 100644
--- a/docs/components/close-button.md
+++ b/packages/docs/components/close-button.md
@@ -2,6 +2,7 @@
title: Vue Close Button Component
name: Close Button
description: A generic close button component for dismissing content like modals and alerts.
+other_frameworks: close-button
---
## Example
@@ -41,4 +42,4 @@ Change the default `` to be white with the `white` boolean propert
## API
-!!!include(./docs/api/close-button/CCloseButton.api.md)!!!
\ No newline at end of file
+!!!include(./api/close-button/CCloseButton.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/collapse.md b/packages/docs/components/collapse.md
similarity index 75%
rename from docs/components/collapse.md
rename to packages/docs/components/collapse.md
index 04af2c1b..50d879bc 100644
--- a/docs/components/collapse.md
+++ b/packages/docs/components/collapse.md
@@ -2,7 +2,7 @@
title: Vue Collapse Component
name: Collapse
description: Vue collapse component toggles the visibility of content across your project with a few classes and some scripts. Useful for a large amount of content.
-
+other_frameworks: collapse
---
@@ -52,6 +52,46 @@ You can use a link or a button component.
```
+## Horizontal
+
+The collapse plugin also supports horizontal collapsing. Add the `horizontal` property to transition the `width` instead of `height` and set a `width` on the immediate child element.
+
+:::demo
+Button
+
+
+
+
+ This is some placeholder content for a horizontal collapse. It's hidden by default and shown when triggered.
+
+
+
+
+:::
+```vue
+
+ Button
+
+
+
+
+ This is some placeholder content for a horizontal collapse. It's hidden by default and shown when triggered.
+
+
+
+
+
+
+```
+
## Multiple targets
A `` can show and hide multiple elements.
@@ -144,6 +184,7 @@ A `` can show and hide multiple elements.
data() {
return {
visible: false,
+ visibleHorizontal: false,
visibleA: false,
visibleB: false,
}
@@ -153,4 +194,4 @@ A `` can show and hide multiple elements.
## API
-!!!include(./docs/api/collapse/CCollapse.api.md)!!!
\ No newline at end of file
+!!!include(./api/collapse/CCollapse.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/dropdown.md b/packages/docs/components/dropdown.md
similarity index 85%
rename from docs/components/dropdown.md
rename to packages/docs/components/dropdown.md
index ced810f8..5f492c9d 100644
--- a/docs/components/dropdown.md
+++ b/packages/docs/components/dropdown.md
@@ -2,7 +2,7 @@
title: Vue Dropdown Component
name: Dropdown
description: Vue dropdown component allows you to toggle contextual overlays for displaying lists, links, and more html elements.
-
+other_frameworks: dropdown
---
## Overview
@@ -19,7 +19,16 @@ Bind the dropdown's toggle and the dropdown menu inside ``, or differ
Here's how you can put them to work with either `` elements:
::: demo
-
+
+ Dropdown Button
+
+ Action
+ Another action
+ Something else here
+
+
+
+
Dropdown Button
Action
@@ -27,9 +36,10 @@ Here's how you can put them to work with either `` elements:
Something else here
+
:::
```vue
-
+
Dropdown Button
Action
@@ -249,12 +259,10 @@ Opt into darker dropdowns to match a dark navbar or custom style by set `dark` p
```
-TODO: navbar
-
And putting it to use in a navbar:
::: demo
-
+
Navbar
@@ -273,7 +281,7 @@ And putting it to use in a navbar:
:::
```vue
-
+
Navbar
@@ -301,6 +309,39 @@ And putting it to use in a navbar:
+### Centered
+
+Make the dropdown menu centered below the toggle by adding `direction="center"` to the `` component.
+
+::: demo
+
+ Centered dropdown
+
+ Action
+ Another action
+ Something else here
+
+ Separated link
+
+
+:::
+```vue
+
+ Centered dropdown
+
+ Action
+ Another action
+ Something else here
+
+ Separated link
+
+
+```
+
+### Dropup
+
+Trigger dropdown menus above elements by adding `direction="dropup"` to the `` component.
+
::: demo
Dropup
@@ -348,7 +389,36 @@ And putting it to use in a navbar:
```
-### Dropright
+### Dropup centered
+
+Make the dropup menu centered above the toggle by adding `direction="dropup-center"` to the `` component.
+
+::: demo
+
+ Centered dropup
+
+ Action
+ Another action
+ Something else here
+
+ Separated link
+
+
+:::
+```vue
+
+ Centered dropup
+
+ Action
+ Another action
+ Something else here
+
+ Separated link
+
+
+```
+
+### Dropend
Trigger dropdown menus at the right of the elements by adding `direction="dropend"` to the `` component.
@@ -399,7 +469,7 @@ Trigger dropdown menus at the right of the elements by adding `direction="dropen
```
-### Dropleft
+### Dropstart
Trigger dropdown menus at the left of the elements by adding `direction="dropstart"` to the `` component.
@@ -623,14 +693,48 @@ Put a form within a dropdown menu, or make it into a dropdown menu.
Forgot password?
```
+## Customizing
+
+### CSS variables
+
+Vue dropdowns use local CSS variables on `.dropdown` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+Customization through CSS variables can be seen on the `.dropdown-menu-dark` class where we override specific values without adding duplicate CSS selectors.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
+Variables for the dark dropdown:
+
+
+
+Variables for the CSS-based carets that indicate a dropdown's interactivity:
+
+
+
## API
-!!!include(./docs/api/dropdown/CDropdown.api.md)!!!
+!!!include(./api/dropdown/CDropdown.api.md)!!!
-!!!include(./docs/api/dropdown/CDropdownHeader.api.md)!!!
+!!!include(./api/dropdown/CDropdownHeader.api.md)!!!
-!!!include(./docs/api/dropdown/CDropdownItem.api.md)!!!
+!!!include(./api/dropdown/CDropdownItem.api.md)!!!
-!!!include(./docs/api/dropdown/CDropdownMenu.api.md)!!!
+!!!include(./api/dropdown/CDropdownMenu.api.md)!!!
-!!!include(./docs/api/dropdown/CDropdownToggle.api.md)!!!
\ No newline at end of file
+!!!include(./api/dropdown/CDropdownToggle.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/footer.md b/packages/docs/components/footer.md
similarity index 59%
rename from docs/components/footer.md
rename to packages/docs/components/footer.md
index 6ff3ddd1..85333743 100644
--- a/docs/components/footer.md
+++ b/packages/docs/components/footer.md
@@ -2,7 +2,7 @@
title: Vue Footer Component
name: Footer
description: Vue footer component is an additional navigation used for displaying general information that a user might want to access from any page within your site. It is a place to display boilerplate text about the site, company info, copyrights, links to a contact form, sitemap, FAQ and other such resources.
-
+other_frameworks: footer
---
## Examples
@@ -32,6 +32,28 @@ description: Vue footer component is an additional navigation used for displayin
```
+## Customizing
+
+### CSS variables
+
+Vue footers use local CSS variables on `.footer` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/footer/CFooter.api.md)!!!
\ No newline at end of file
+!!!include(./api/footer/CFooter.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/header.md b/packages/docs/components/header.md
similarity index 86%
rename from docs/components/header.md
rename to packages/docs/components/header.md
index 77613162..a58ee2f7 100644
--- a/docs/components/header.md
+++ b/packages/docs/components/header.md
@@ -2,6 +2,7 @@
title: Vue Header Component
name: Header
description: Documentation and examples for the Header powerful, responsive navigation header. Includes support for branding, links, dropdowns, and more.
+other_frameworks: header
---
## Example
@@ -103,7 +104,7 @@ Here's an example of all the sub-components included in a responsive light-theme
export default {
data() {
return {
- visible: true,
+ visible: false,
}
}
}
@@ -114,16 +115,39 @@ Here's an example of all the sub-components included in a responsive light-theme
export default {
data() {
return {
- visible: true,
+ visible: false,
}
}
}
+
+## Customizing
+
+### CSS variables
+
+Vue headers use local CSS variables on `.header` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/header/CHeader.api.md)!!!
+!!!include(./api/header/CHeader.api.md)!!!
-!!!include(./docs/api/header/CHeaderBrand.api.md)!!!
+!!!include(./api/header/CHeaderBrand.api.md)!!!
-!!!include(./docs/api/header/CHeaderNav.api.md)!!!
\ No newline at end of file
+!!!include(./api/header/CHeaderNav.api.md)!!!
\ No newline at end of file
diff --git a/packages/docs/components/icon.md b/packages/docs/components/icon.md
new file mode 100644
index 00000000..c8d8a27e
--- /dev/null
+++ b/packages/docs/components/icon.md
@@ -0,0 +1,237 @@
+---
+title: Vue Icon Component
+name: Icon
+description: Official Vue.js component for CoreUI Icons and CoreUI Icons PRO.
+---
+
+## Installation
+
+If you want to use our icon component and our icons library you have to install two additional packages.
+
+### Npm
+
+```bash
+// CoreUI Icons library
+npm install @coreui/icons
+
+// CIcon component
+npm install @coreui/icons-vue
+```
+
+### Yarn
+
+```bash
+yarn add @coreui/icons
+yarn add @coreui/icons-vue
+```
+
+## Usage
+
+### Single icon
+
+::: demo
+
+
+:::
+```vue
+
+
+
+
+
+```
+
+### All icons
+
+```vue
+
+
+
+
+```
+
+### Icons object
+
+This way you import your needed icons once and pass them to $root object on 'icons' key
+
+```js
+// main.js / main.ts
+import { CIcon } from '@coreui/icons-vue';
+import {
+ cilArrowBottom,
+ cilArrowRight,
+ cilArrowTop,
+ cilBan,
+ cilBasket,
+ cilBell,
+ cilCalculator,
+ cilCalendar
+} from '@coreui/icons'
+
+const icons = {
+ cilArrowBottom,
+ cilArrowRight,
+ cilArrowTop,
+ cilBan,
+ cilBasket,
+ cilBell,
+ cilCalculator,
+ cilCalendar
+}
+
+const app = createApp(App)
+...
+app.provide('icons', icons)
+app.component('CIcon', CIcon)
+...
+app.mount('#app')
+
+```
+Later anywhere in the app:
+```vue
+
+
+```
+You can pass the name of the icon both in camelCase and kebab-case
+
+
+## Available icons
+
+CoreUI Icons package is delivered with more than 1500 icons in multiple formats SVG, PNG, and Webfonts. CoreUI Icons are beautifully crafted symbols for common actions and items. You can use them in your digital products for web or mobile app.
+
+
+
+ {tabPaneActiveKey = 1}"
+ >
+ Linear
+
+
+
+ {tabPaneActiveKey = 2}"
+ >
+ Brand
+
+
+
+ {tabPaneActiveKey = 3}"
+ >
+ Flags
+
+
+
+
+
+
+
+
+
+
+ {{i}}
+
+
+
+
+
+
+
+
+
+ {{i}}
+
+
+
+
+
+
+
+
+
+ {{i}}
+
+
+
+
+
+
+
+
+## API
+
+### CIcon
+
+```js
+import { CIcon } from '@coreui/icons-vue'
+```
+
+| Prop name | Description | Type | Values | Default |
+| --------------------- | ------------------------------------------------------------------------------------------------- | --------------------- | ------ | ------- |
+| **content** | Use `:icon="..."` instead of `@deprecated` since version 3.0 | string\|array | - | - |
+| **custom-class-name** | Use for replacing default CIcon component classes. Prop is overriding the 'size' prop. | string\|array\|object | - | - |
+| **icon** | Name of the icon placed in Vue object or SVG content. | string \| string[] | - | - |
+| **name** | Use `icon="..."` instead of `@deprecated` since version 3.0 | string | - | - |
+| **size** | Size of the icon. Available sizes: 'sm', 'lg', 'xl', 'xxl', '3xl...9xl', 'custom', 'custom-size'. | string | - | - |
+| **title** | Title tag content. | string | - | - |
+| **use** | If defined component will be rendered using 'use' tag. | string | - | - |
\ No newline at end of file
diff --git a/docs/components/image.md b/packages/docs/components/image.md
similarity index 96%
rename from docs/components/image.md
rename to packages/docs/components/image.md
index 6d9c0874..bce4f578 100644
--- a/docs/components/image.md
+++ b/packages/docs/components/image.md
@@ -2,6 +2,7 @@
title: Vue Image Component
name: Image
description: Vue image component with responsive behavior (so it's never become larger than their parent element) and special styles.
+other_frameworks: image
---
## Responsive images
@@ -68,4 +69,4 @@ Align images with the `align` property.
## API
-!!!include(./docs/api/image/CImage.api.md)!!!
\ No newline at end of file
+!!!include(./api/image/CImage.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/link.md b/packages/docs/components/link.md
similarity index 100%
rename from docs/components/link.md
rename to packages/docs/components/link.md
diff --git a/docs/components/list-group.md b/packages/docs/components/list-group.md
similarity index 85%
rename from docs/components/list-group.md
rename to packages/docs/components/list-group.md
index 95a0e412..27d4c98f 100644
--- a/docs/components/list-group.md
+++ b/packages/docs/components/list-group.md
@@ -2,6 +2,7 @@
title: Vue List Group Component
name: List group
description: Vue List Group component allows displaying a series of content. Learn how to use Vue list group to build complex list structure on your website.
+other_frameworks: list-group
---
## Basic example
@@ -287,8 +288,8 @@ Place CoreUI's checkboxes and radios within list group items and customize as ne
::: demo
-
-
+
+
@@ -296,15 +297,58 @@ Place CoreUI's checkboxes and radios within list group items and customize as ne
```vue
-
-
+
+
```
+And if you want ``s as the `.list-group-item` for large hit areas, you can do that, too.
+
+::: demo
+
+
+
+
+
+
+
+:::
+```vue
+
+
+
+
+
+
+
+```
+
+## Customizing
+
+### CSS variables
+
+Vue list groups use local CSS variables on `.list-group` for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.
+
+
+
+#### How to use CSS variables
+
+```js
+const vars = {
+ '--my-css-var': 10,
+ '--my-another-css-var': "red"
+}
+return ...
+```
+
+### SASS variables
+
+
+
## API
-!!!include(./docs/api/list-group/CListGroup.api.md)!!!
+!!!include(./api/list-group/CListGroup.api.md)!!!
-!!!include(./docs/api/list-group/CListGroupItem.api.md)!!!
\ No newline at end of file
+!!!include(./api/list-group/CListGroupItem.api.md)!!!
\ No newline at end of file
diff --git a/docs/components/modal.md b/packages/docs/components/modal.md
similarity index 85%
rename from docs/components/modal.md
rename to packages/docs/components/modal.md
index ac552761..f26f03bd 100644
--- a/docs/components/modal.md
+++ b/packages/docs/components/modal.md
@@ -2,17 +2,18 @@
title: Vue Modal Component
name: Modal
description: Vue Modal component offers a lightweight, multi-purpose popup to add dialogs to yours. Learn how to customize Vue CoreUI Modals easily. Multiple examples and tutorial.
+other_frameworks: modal
---
## Examples
### Modal components
-Below is a static modal example (meaning its `position` and `display` have been overridden). Included are the modal header, modal body (required for `padding`), and modal footer (optional). We ask that you include modal headers with dismiss actions whenever possible, or provide another explicit dismiss action.
+Below is a static modal example (meaning its `position` and `display` have been overridden). Included are the modal header, modal body (required for `padding`), and modal footer (optional). We ask that you include modal headers with actions whenever possible, or provide another explicit action.
::: demo
-
+
Modal title
Modal body text goes here.
@@ -23,8 +24,8 @@ Below is a static modal example (meaning its `position` and `display` have been
:::
``` vue
-
-
+
+
Modal title
Modal body text goes here.
@@ -42,8 +43,8 @@ Toggle a working modal demo by clicking the button below. It will slide down and
::: demo
{ visibleLiveDemo = true }">Launch demo modal
- { visibleLiveDemo = false }">
- { visibleLiveDemo = false }">
+ { visibleLiveDemo = false }">
+
Modal title
Woohoo, you're reading this text in a modal!
@@ -58,8 +59,8 @@ Toggle a working modal demo by clicking the button below. It will slide down and
``` vue
{ visibleLiveDemo = true }">Launch demo modal
- { visibleLiveDemo = false }">
- { visibleLiveDemo = false }">
+ { visibleLiveDemo = false }">
+
Modal title
Woohoo, you're reading this text in a modal!
@@ -81,16 +82,14 @@ Toggle a working modal demo by clicking the button below. It will slide down and
}
```
-
-
### Static backdrop
If you set `backdrop` property to `static`, your modal will behave as though the backdrop is static, meaning it will not close when clicking outside it. Click the button below to try it.
::: demo
{ visibleStaticBackdropDemo = true }">Launch static backdrop modal
- { visibleStaticBackdropDemo = false }">
- { visibleStaticBackdropDemo = false }">
+ { visibleStaticBackdropDemo = false }">
+
Modal title
Woohoo, you're reading this text in a modal!
@@ -105,8 +104,8 @@ If you set `backdrop` property to `static`, your modal will behave as though the
``` vue
{ visibleStaticBackdropDemo = true }">Launch demo modal
- { visibleStaticBackdropDemo = false }">
- { visibleStaticBackdropDemo = false }">
+ { visibleStaticBackdropDemo = false }">
+
Modal title
Woohoo, you're reading this text in a modal!
@@ -135,8 +134,8 @@ When modals become too long for the user's viewport or device, they scroll indep
::: demo
{ visibleScrollingLongContentDemo = true }">Launch static backdrop modal
- { visibleScrollingLongContentDemo = false }">
- { visibleScrollingLongContentDemo = false }">
+ { visibleScrollingLongContentDemo = false }">
+
Modal title
@@ -230,8 +229,8 @@ When modals become too long for the user's viewport or device, they scroll indep
``` vue
{ visibleScrollingLongContentDemo = true }">Launch demo modal
- { visibleScrollingLongContentDemo = false }">
- { visibleScrollingLongContentDemo = false }">
+ { visibleScrollingLongContentDemo = false }">
+
Modal title
@@ -337,8 +336,8 @@ You can also create a scrollable modal that allows scroll the modal body by addi
::: demo
{ visibleScrollableDemo = true }">Launch static backdrop modal
- { visibleScrollableDemo = false }">
- { visibleScrollableDemo = false }">
+ { visibleScrollableDemo = false }">
+
Modal title
@@ -432,8 +431,8 @@ You can also create a scrollable modal that allows scroll the modal body by addi
``` vue