diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 1846284b..00000000 --- a/.eslintignore +++ /dev/null @@ -1,3 +0,0 @@ -/dist/** -/docs/** -.eslintrc.js \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index a0662dcd..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * 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 = { - root: true, // So parent files don't get applied - env: { - es6: true, - browser: true, - node: true, - }, - parser: '@typescript-eslint/parser', // Specifies the ESLint parser - parserOptions: { - ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features - sourceType: 'module', // Allows for the use of imports - extraFileExtensions: ['.vue'], - }, - extends: [ - 'eslint:recommended', - 'plugin:vue/vue3-recommended', - 'plugin:prettier/recommended', - 'plugin:unicorn/recommended', - '@vue/eslint-config-typescript/recommended', - '@vue/eslint-config-prettier', - ], - rules: { - 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', - 'unicorn/filename-case': 'off', - 'unicorn/no-array-for-each': 'off', - 'unicorn/no-null': 'off', - 'unicorn/prefer-dom-node-append': 'off', - 'unicorn/prefer-export-from': 'off', - 'unicorn/prefer-query-selector': 'off', - 'unicorn/prevent-abbreviations': 'off', - 'vue/require-default-prop': 'off', - }, - overrides: [ - { - files: ['**/*.mjs'], - env: { - browser: false, - node: true, - }, - parserOptions: { - sourceType: 'module', - }, - }, - { - files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'], - env: { - jest: true, - }, - }, - { - files: ['packages/docs/build/**'], - env: { - browser: false, - node: true, - }, - parserOptions: { - sourceType: 'script', - }, - rules: { - 'no-console': 'off', - strict: 'error', - }, - }, - ], -} diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 415ca057..00000000 --- a/.prettierrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - semi: false, - trailingComma: "all", - singleQuote: true, - printWidth: 100, - tabWidth: 2 -}; \ No newline at end of file diff --git a/LICENSE b/LICENSE index f19fc729..fbb053e0 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021 creativeLabs Łukasz Holeczek +Copyright (c) 2025 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 @@ -18,4 +18,4 @@ 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 +SOFTWARE. diff --git a/README.md b/README.md index e21d4f28..86647480 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ Several quick start options are available: -- [Download the latest release](https://github.com/coreui/coreui-vue/archive/v5.4.1.zip) +- [Download the latest release](https://github.com/coreui/coreui-vue/archive/v5.5.0.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` @@ -227,4 +227,4 @@ CoreUI is an MIT-licensed open source project and is completely free to use. How ## Copyright and license -Copyright 2024 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/). +Copyright 2025 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/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 00000000..15164bf5 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,76 @@ +import eslint from '@eslint/js' +import eslintPluginUnicorn from 'eslint-plugin-unicorn' +import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended' +import eslintPluginVue from 'eslint-plugin-vue' +import globals from 'globals' +import typescriptEslint from 'typescript-eslint' + +export default typescriptEslint.config( + { ignores: ['**/*.d.ts', '**/coverage', '**/dist', '**/docs'] }, + { + extends: [ + eslint.configs.recommended, + ...typescriptEslint.configs.recommended, + ...eslintPluginVue.configs['flat/recommended'], + eslintPluginUnicorn.configs['flat/recommended'], + ], + files: ['packages/**/src/**/*.{js,ts,tsx}'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + globals: globals.browser, + parserOptions: { + parser: typescriptEslint.parser, + }, + }, + rules: { + 'no-console': 'off', + 'no-debugger': 'off', + 'unicorn/filename-case': 'off', + 'unicorn/no-array-for-each': 'off', + 'unicorn/no-null': 'off', + 'unicorn/prefer-dom-node-append': 'off', + 'unicorn/prefer-export-from': 'off', + 'unicorn/prefer-query-selector': 'off', + 'unicorn/prevent-abbreviations': 'off', + 'vue/require-default-prop': 'off', + }, + }, + { + files: ['**/*.mjs'], + languageOptions: { + globals: { + ...Object.fromEntries(Object.entries(globals.browser).map(([key]) => [key, 'off'])), + ...globals.node, + }, + + ecmaVersion: 'latest', + sourceType: 'module', + }, + }, + { + files: ['**/__tests__/*.{j,t}s?(x)', '**/tests/unit/**/*.spec.{j,t}s?(x)'], + languageOptions: { + globals: { + ...globals.jest, + }, + }, + }, + { + files: ['packages/docs/build/**'], + languageOptions: { + globals: { + ...Object.fromEntries(Object.entries(globals.browser).map(([key]) => [key, 'off'])), + ...globals.node, + }, + + ecmaVersion: 5, + sourceType: 'commonjs', + }, + rules: { + 'no-console': 'off', + strict: 'error', + }, + }, + eslintPluginPrettierRecommended, +) diff --git a/lerna.json b/lerna.json index 6fea4400..8b1ec4d7 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "npmClient": "yarn", "packages": ["packages/*"], - "version": "5.4.1", + "version": "5.5.0", "$schema": "node_modules/lerna/schemas/lerna-schema.json" } diff --git a/package.json b/package.json index a8e640de..7b5343e7 100644 --- a/package.json +++ b/package.json @@ -17,23 +17,21 @@ "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}\"", + "lint": "eslint", "test": "npm-run-all charts:test icons:test lib:test", "test:update": "npm-run-all charts:test:update icons:test:update lib:test:update" }, "devDependencies": { - "@typescript-eslint/eslint-plugin": "^8.6.0", - "@typescript-eslint/parser": "^8.6.0", - "@vue/eslint-config-prettier": "^9.0.0", - "@vue/eslint-config-typescript": "^13.0.0", "@vue/vue3-jest": "29.2.6", - "eslint": "8.57.0", - "eslint-plugin-prettier": "^5.2.1", - "eslint-plugin-vue": "^9.28.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-unicorn": "^55.0.0", - "lerna": "^8.1.8", + "eslint": "^9.28.0", + "eslint-config-prettier": "^10.1.5", + "eslint-plugin-prettier": "^5.4.1", + "eslint-plugin-unicorn": "^59.0.1", + "eslint-plugin-vue": "^10.1.0", + "globals": "^16.2.0", + "lerna": "^8.2.2", "npm-run-all": "^4.1.5", - "prettier": "^3.3.3" + "prettier": "^3.5.3", + "typescript-eslint": "^8.33.1" } } diff --git a/packages/coreui-vue/README.md b/packages/coreui-vue/README.md index d422298c..a1cfd697 100644 --- a/packages/coreui-vue/README.md +++ b/packages/coreui-vue/README.md @@ -46,7 +46,7 @@ Several quick start options are available: -- [Download the latest release](https://github.com/coreui/coreui-vue/archive/v5.4.1.zip) +- [Download the latest release](https://github.com/coreui/coreui-vue/archive/v5.5.0.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` diff --git a/packages/coreui-vue/package.json b/packages/coreui-vue/package.json index 02a7b5e2..39b08b3a 100644 --- a/packages/coreui-vue/package.json +++ b/packages/coreui-vue/package.json @@ -1,6 +1,6 @@ { "name": "@coreui/vue", - "version": "5.4.1", + "version": "5.5.0", "description": "UI Components Library for Vue.js", "keywords": [ "vue", @@ -41,25 +41,25 @@ "test:update": "jest --coverage --updateSnapshot" }, "dependencies": { - "@coreui/coreui": "^5.2.0", + "@coreui/coreui": "^5.4.0", "@popperjs/core": "^2.11.8" }, "devDependencies": { - "@rollup/plugin-commonjs": "^28.0.1", - "@rollup/plugin-node-resolve": "^15.3.0", - "@rollup/plugin-typescript": "^12.1.1", + "@rollup/plugin-commonjs": "^28.0.3", + "@rollup/plugin-node-resolve": "^16.0.1", + "@rollup/plugin-typescript": "^12.1.2", "@types/jest": "^29.5.14", "@vue/test-utils": "^2.4.6", "@vue/vue3-jest": "29.2.6", "cross-env": "^7.0.3", "jest": "^29.7.0", "jest-environment-jsdom": "^29.7.0", - "rollup": "^4.24.2", + "rollup": "^4.41.1", "rollup-plugin-vue": "^6.0.0", - "ts-jest": "^29.2.5", - "typescript": "^5.6.3", - "vue": "^3.5.12", - "vue-types": "^5.1.3" + "ts-jest": "^29.3.4", + "typescript": "^5.8.3", + "vue": "^3.5.16", + "vue-types": "^6.0.0" }, "peerDependencies": { "vue": "^3.5.0" diff --git a/packages/coreui-vue/src/components/accordion/CAccordionBody.ts b/packages/coreui-vue/src/components/accordion/CAccordionBody.ts index 4a8d83ff..c8907021 100644 --- a/packages/coreui-vue/src/components/accordion/CAccordionBody.ts +++ b/packages/coreui-vue/src/components/accordion/CAccordionBody.ts @@ -4,11 +4,12 @@ import { CCollapse } from '../collapse/CCollapse' const CAccordionBody = defineComponent({ name: 'CAccordionBody', setup(_, { slots }) { + const id = inject('id') const visible = inject('visible') as Ref return () => h( CCollapse, - { class: 'accordion-collapse', visible: visible.value }, + { class: 'accordion-collapse', id, visible: visible.value }, { default: () => h('div', { class: ['accordion-body'] }, slots.default && slots.default()), }, diff --git a/packages/coreui-vue/src/components/accordion/CAccordionButton.ts b/packages/coreui-vue/src/components/accordion/CAccordionButton.ts index 69ab7a00..f9820b4a 100644 --- a/packages/coreui-vue/src/components/accordion/CAccordionButton.ts +++ b/packages/coreui-vue/src/components/accordion/CAccordionButton.ts @@ -3,6 +3,7 @@ import { defineComponent, h, inject, Ref } from 'vue' const CAccordionButton = defineComponent({ name: 'CAccordionButton', setup(_, { slots }) { + const id = inject('id') as string const toggleVisibility = inject('toggleVisibility') as () => void const visible = inject('visible') as Ref @@ -11,7 +12,8 @@ const CAccordionButton = defineComponent({ 'button', { type: 'button', - 'aria-expanded': !visible.value, + 'aria-control': id, + 'aria-expanded': visible.value, class: ['accordion-button', { ['collapsed']: !visible.value }], onClick: () => toggleVisibility(), }, diff --git a/packages/coreui-vue/src/components/accordion/CAccordionItem.ts b/packages/coreui-vue/src/components/accordion/CAccordionItem.ts index 20575085..f2ebe594 100644 --- a/packages/coreui-vue/src/components/accordion/CAccordionItem.ts +++ b/packages/coreui-vue/src/components/accordion/CAccordionItem.ts @@ -1,8 +1,12 @@ -import { defineComponent, h, inject, provide, ref, watch, Ref } from 'vue' +import { defineComponent, h, inject, provide, ref, watch, Ref, useId } from 'vue' const CAccordionItem = defineComponent({ name: 'CAccordionItem', props: { + /** + * The id global attribute defines an identifier (ID) that must be unique in the whole document. + */ + id: String, /** * The item key. */ @@ -13,16 +17,20 @@ const CAccordionItem = defineComponent({ 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 id = props.id ?? useId() + const itemKey = ref(props.itemKey ?? id) 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) + if (!alwaysOpen && visible) { + setActiveItemKey(itemKey.value) + } } + provide('id', id) provide('visible', visible) provide('toggleVisibility', toggleVisibility) diff --git a/packages/coreui-vue/src/components/button/CButton.ts b/packages/coreui-vue/src/components/button/CButton.ts index 287bfd12..70f7e90d 100644 --- a/packages/coreui-vue/src/components/button/CButton.ts +++ b/packages/coreui-vue/src/components/button/CButton.ts @@ -93,9 +93,9 @@ export const CButton = defineComponent({ { class: [ 'btn', + props.variant && props.color ? `btn-${props.variant}-${props.color}` : `btn-${props.variant}`, { [`btn-${props.color}`]: props.color && !props.variant, - [`btn-${props.variant}-${props.color}`]: props.color && props.variant, [`btn-${props.size}`]: props.size, active: props.active, disabled: props.disabled, diff --git a/packages/coreui-vue/src/components/form/CFormControlWrapper.ts b/packages/coreui-vue/src/components/form/CFormControlWrapper.ts index bdecc2ff..0ed3d195 100644 --- a/packages/coreui-vue/src/components/form/CFormControlWrapper.ts +++ b/packages/coreui-vue/src/components/form/CFormControlWrapper.ts @@ -7,6 +7,7 @@ import { CFormText } from './CFormText' import type { ComponentProps } from '../../utils/ComponentProps' interface CFormControlWrapperProps extends ComponentProps { + floatingClassName?: string floatingLabel?: string id?: string label?: string @@ -18,6 +19,12 @@ const CFormControlWrapper = defineComponent({ inheritAttrs: false, props: { ...CFormControlValidation.props, + /** + * A string of all className you want applied to the floating label wrapper. + * + * @since 5.5.0 + */ + floatingClassName: String, /** * Provide valuable, actionable valid feedback when using standard HTML form validation which applied two CSS pseudo-classes, `:invalid` and `:valid`. * @@ -69,29 +76,36 @@ const CFormControlWrapper = defineComponent({ 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( + CFormFloating, + { + class: props.floatingClassName, + }, + () => [ + slots.default && slots.default(), h( - CFormText, + CFormLabel, { - id: props.describedby, + for: props.id, }, { - default: () => (slots.text && slots.text()) || props.text, + default: () => + (slots.label && slots.label()) || props.label || props.floatingLabel, }, ), - formControlValidation(), - ]) + (props.text || slots.text) && + h( + CFormText, + { + id: props.describedby, + }, + { + default: () => (slots.text && slots.text()) || props.text, + }, + ), + formControlValidation(), + ], + ) : [ (props.label || slots.label) && h( diff --git a/packages/coreui-vue/src/components/nav/CNav.ts b/packages/coreui-vue/src/components/nav/CNav.ts index 922603e9..6b5b7384 100644 --- a/packages/coreui-vue/src/components/nav/CNav.ts +++ b/packages/coreui-vue/src/components/nav/CNav.ts @@ -24,12 +24,12 @@ const CNav = defineComponent({ /** * Set the nav variant to tabs or pills. * - * @values 'pills', 'tabs', 'underline', 'underline-border' + * @values 'enclosed', 'enclosed-pills', 'pills', 'tabs', 'underline', 'underline-border' */ variant: { type: String, validator: (value: string) => { - return ['pills', 'tabs', 'underline', 'underline-border'].includes(value) + return ['enclosed', 'enclosed-pills', 'pills', 'tabs', 'underline', 'underline-border'].includes(value) }, }, }, @@ -40,6 +40,7 @@ const CNav = defineComponent({ { class: [ 'nav', + props.variant === 'enclosed-pills' && 'nav-enclosed', { [`nav-${props.layout}`]: props.layout, [`nav-${props.variant}`]: props.variant, diff --git a/packages/coreui-vue/src/components/nav/CNavGroup.ts b/packages/coreui-vue/src/components/nav/CNavGroup.ts index 2c83ccdf..7c45bd7c 100644 --- a/packages/coreui-vue/src/components/nav/CNavGroup.ts +++ b/packages/coreui-vue/src/components/nav/CNavGroup.ts @@ -41,7 +41,10 @@ const CNavGroup = defineComponent({ onMounted(() => { visible.value = props.visible - props.visible && navGroupRef.value.classList.add('show') + if (props.visible) { + navGroupRef.value.classList.add('show') + } + emit('visible-change', visible.value) }) @@ -60,7 +63,8 @@ const CNavGroup = defineComponent({ emit('visible-change', visible.value) }) - const handleTogglerClick = () => { + const handleTogglerClick = (event: Event) => { + event.preventDefault() visible.value = !visible.value emit('visible-change', visible.value) } @@ -111,6 +115,7 @@ const CNavGroup = defineComponent({ 'a', { class: ['nav-link', 'nav-group-toggle'], + href: '#', onClick: handleTogglerClick, }, slots.togglerContent && slots.togglerContent(), diff --git a/packages/coreui-vue/src/components/nav/CNavItem.ts b/packages/coreui-vue/src/components/nav/CNavItem.ts index 48290ba7..e660c01a 100644 --- a/packages/coreui-vue/src/components/nav/CNavItem.ts +++ b/packages/coreui-vue/src/components/nav/CNavItem.ts @@ -5,10 +5,12 @@ import type { ComponentProps } from '../../utils/ComponentProps' interface CNavItemProps extends ComponentProps { as: string + class: string } const CNavItem = defineComponent({ name: 'CNavItem', + inheritAttrs: false, props: { /** * Toggle the active state for the component. @@ -21,6 +23,10 @@ const CNavItem = defineComponent({ type: String, default: 'li', }, + /** + * A string of all className you want applied to the component. + */ + class: String, /** * Toggle the disabled state for the component. */ @@ -30,17 +36,18 @@ const CNavItem = defineComponent({ */ href: String, }, - setup(props: CNavItemProps, { slots }) { + setup(props: CNavItemProps, { attrs, slots }) { return () => h( props.as, { - class: 'nav-item', + class: ['nav-item', props.class], }, props.href ? h( CNavLink, { + ...attrs, active: props.active, disabled: props.disabled, href: props.href, diff --git a/packages/coreui-vue/src/components/tabs/CTabList.ts b/packages/coreui-vue/src/components/tabs/CTabList.ts index 63b720f2..d73bb17d 100644 --- a/packages/coreui-vue/src/components/tabs/CTabList.ts +++ b/packages/coreui-vue/src/components/tabs/CTabList.ts @@ -18,12 +18,12 @@ const CTabList = defineComponent({ /** * Set the nav variant to tabs or pills. * - * @values 'pills', 'tabs', 'underline', 'underline-border' + * @values 'enclosed', 'enclosed-pills', 'pills', 'tabs', 'underline', 'underline-border' */ variant: { type: String, validator: (value: string) => { - return ['pills', 'tabs', 'underline', 'underline-border'].includes(value) + return ['enclosed', 'enclosed-pills', 'pills', 'tabs', 'underline', 'underline-border'].includes(value) }, }, }, @@ -72,6 +72,7 @@ const CTabList = defineComponent({ { class: [ 'nav', + props.variant === 'enclosed-pills' && 'nav-enclosed', { [`nav-${props.layout}`]: props.layout, [`nav-${props.variant}`]: props.variant, diff --git a/packages/docs/.prettierrc b/packages/docs/.prettierrc new file mode 100644 index 00000000..53e4559d --- /dev/null +++ b/packages/docs/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": false, + "trailingComma": "es5", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2 + +} diff --git a/packages/docs/api/accordion/CAccordionItem.api.md b/packages/docs/api/accordion/CAccordionItem.api.md index 753acd83..3e07d5aa 100644 --- a/packages/docs/api/accordion/CAccordionItem.api.md +++ b/packages/docs/api/accordion/CAccordionItem.api.md @@ -8,6 +8,7 @@ import CAccordionItem from '@coreui/vue/src/components/accordion/CAccordionItem' #### Props -| Prop name | Description | Type | Values | Default | -| ------------ | ------------- | -------------- | ------ | ------- | -| **item-key** | The item key. | number\|string | - | - | +| Prop name | Description | Type | Values | Default | +| ------------ | --------------------------------------------------------------------------------------------- | -------------- | ------ | ------- | +| **id** | The id global attribute defines an identifier (ID) that must be unique in the whole document. | string | - | - | +| **item-key** | The item key. | number\|string | - | - | diff --git a/packages/docs/api/form/CFormControlWrapper.api.md b/packages/docs/api/form/CFormControlWrapper.api.md index c4d97891..ebce3a46 100644 --- a/packages/docs/api/form/CFormControlWrapper.api.md +++ b/packages/docs/api/form/CFormControlWrapper.api.md @@ -8,8 +8,9 @@ import CFormControlWrapper from '@coreui/vue/src/components/form/CFormControlWra #### 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 | - | - | +| Prop name | Description | Type | Values | Default | +| ---------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | ------ | ------- | +| **floating-class-name**
5.5.0+
| A string of all className you want applied to the floating label wrapper. | 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 | - | - | +| **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/nav/CNav.api.md b/packages/docs/api/nav/CNav.api.md index deda7877..37c9f02c 100644 --- a/packages/docs/api/nav/CNav.api.md +++ b/packages/docs/api/nav/CNav.api.md @@ -8,8 +8,8 @@ import CNav from '@coreui/vue/src/components/nav/CNav' #### Props -| Prop name | Description | Type | Values | Default | -| ----------- | --------------------------------------------------------------------------------------- | ------ | -------------------------------------------------------- | ------- | -| **as** | 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 | `'pills'`, `'tabs'`, `'underline'`, `'underline-border'` | - | +| Prop name | Description | Type | Values | Default | +| ----------- | --------------------------------------------------------------------------------------- | ------ | ------------------------------------------------------------------------------------------ | ------- | +| **as** | 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 | `'enclosed'`, `'enclosed-pills'`, `'pills'`, `'tabs'`, `'underline'`, `'underline-border'` | - | diff --git a/packages/docs/api/nav/CNavItem.api.md b/packages/docs/api/nav/CNavItem.api.md index bba531c6..788b3792 100644 --- a/packages/docs/api/nav/CNavItem.api.md +++ b/packages/docs/api/nav/CNavItem.api.md @@ -12,4 +12,5 @@ import CNavItem from '@coreui/vue/src/components/nav/CNavItem' | ------------ | --------------------------------------------------------------------------------------- | ------- | ------ | ------- | | **active** | Toggle the active state for the component. | boolean | - | - | | **as** | Component used for the root node. Either a string to use a HTML element or a component. | string | - | 'li' | +| **class** | A string of all className you want applied to the component. | string | - | - | | **disabled** | Toggle the disabled state for the component. | boolean | - | - | diff --git a/packages/docs/api/stepper/CStepper.api.md b/packages/docs/api/stepper/CStepper.api.md new file mode 100644 index 00000000..e13e9c9a --- /dev/null +++ b/packages/docs/api/stepper/CStepper.api.md @@ -0,0 +1,22 @@ +### CStepper + +```jsx +import { CStepper } from '@coreui/vue' +// or +import CStepper from '@coreui/vue/src/components/stepper/CStepper' +``` + +#### Props + +| Prop name | Description | Type | Values | Default | +| --------- | ----------- | ---- | ------ | ------- | + +#### Events + +| Event name | Description | Properties | +| ---------------------------- | ----------- | ---------- | +| **update:modelValue** | | +| **finish** | | +| **reset** | | +| **step-change** | | +| **step-validation-complete** | | diff --git a/packages/docs/api/tabs/CTabList.api.md b/packages/docs/api/tabs/CTabList.api.md index 68b9ca46..c12138af 100644 --- a/packages/docs/api/tabs/CTabList.api.md +++ b/packages/docs/api/tabs/CTabList.api.md @@ -8,7 +8,7 @@ import CTabList from '@coreui/vue/src/components/tabs/CTabList' #### Props -| Prop name | Description | Type | Values | Default | -| ----------- | ------------------------------------- | ------ | -------------------------------------------------------- | ------- | -| **layout** | Specify a layout type for component. | string | `'fill'`, `'justified'` | - | -| **variant** | Set the nav variant to tabs or pills. | string | `'pills'`, `'tabs'`, `'underline'`, `'underline-border'` | - | +| Prop name | Description | Type | Values | Default | +| ----------- | ------------------------------------- | ------ | ------------------------------------------------------------------------------------------ | ------- | +| **layout** | Specify a layout type for component. | string | `'fill'`, `'justified'` | - | +| **variant** | Set the nav variant to tabs or pills. | string | `'enclosed'`, `'enclosed-pills'`, `'pills'`, `'tabs'`, `'underline'`, `'underline-border'` | - | diff --git a/packages/docs/components/button.md b/packages/docs/components/button.md index 0f9a8428..fe592e77 100644 --- a/packages/docs/components/button.md +++ b/packages/docs/components/button.md @@ -63,7 +63,27 @@ If you're using `` component as `` elements that are used to trigger ## Outline buttons -If you need a button, but without the strong background colors. Set `variant="outline"` prop to remove all background colors. +### Base outline style + +The `variant="outline` property provides a neutral outline button style without any color modifiers. It’s useful as a foundation for minimal buttons without background color or strong visual emphasis. + +::: demo +Base outline button +Active state +Disabled state +::: +```vue +Base outline button +Active state +Disabled state +``` + +These Vue buttons use a transparent background, subtle border, and inherit text color from the parent context. They’re best suited for minimalist UI elements like modals, toolbars, or secondary actions. + + +### Themed outline variants + +If you need a button, but without the strong background colors, set `color` and `variant=" outline"` props to remove all background colors. ::: demo Primary @@ -86,10 +106,31 @@ If you need a button, but without the strong background colors. Set `variant="ou Dark ``` +These outline variants of our Vue.js buttons retain transparent backgrounds by default, but display a background tint on hover or focus to indicate interactivity. They’re ideal for secondary actions when you want to differentiate from the standard buttons visually. + ## Ghost buttons +### Base ghost style + +Use the `variant="ghost"` property to create ultra-minimalist buttons with no borders and a fully transparent background. These Vue buttons rely solely on text color for visibility and apply a background highlight when hovered over or in an active state. + +They’re perfect for interfaces where you want buttons to be present but visually unobtrusive—such as action buttons in modals, cards, or toolbars. + If you need a ghost variant of button, set `variant="ghost"` prop to remove all background colors. +::: demo +Base ghost button +Active state +Disabled state +::: +```vue +Base ghost button +Active state +Disabled state +``` + +To apply theme colors to Vue ghost buttons, use the `color` and `variant="ghost"` properties. By default, these variants color only the text. On hover or focus, they add a background that corresponds to the theme color. + ::: demo Primary Secondary diff --git a/packages/docs/components/navs-tabs.md b/packages/docs/components/navs-tabs.md index 1452f180..9ad84051 100644 --- a/packages/docs/components/navs-tabs.md +++ b/packages/docs/components/navs-tabs.md @@ -402,6 +402,96 @@ Take that same code, but use `variant="underline-border"` instead: ``` +### Enclosed + +Use the `variant="enclosed"` class to give your navigation items a subtle border and rounded styling. + +::: demo + + + + Active + + + + Link + + + Link + + + + Disabled + + + +::: +```vue + + + + Active + + + + Link + + + Link + + + + Disabled + + + +``` + +### Enclosed pills + +Use the `variant="enclosed-pills"` to achieve a pill-style appearance for each nav item, using pill-shaped borders and smoother outlines. + +::: 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. diff --git a/packages/docs/components/tabs.md b/packages/docs/components/tabs.md index fcb3dd2a..33b8a72d 100644 --- a/packages/docs/components/tabs.md +++ b/packages/docs/components/tabs.md @@ -275,6 +275,112 @@ Take that same code, but use `variant="underline-border"` instead: ``` +### Enclosed + +Use the `variant="enclosed"` class to give your tab items a subtle border and rounded styling. + +::: demo + + + Home + Profile + Contact + Disabled + + + + Home tab content + + + Profile tab content + + + Contact tab content + + + Disabled tab content + + + +::: +```vue + + + Home + Profile + Contact + Disabled + + + + Home tab content + + + Profile tab content + + + Contact tab content + + + Disabled tab content + + + +``` + +### Enclosed pills + +Use the `variant="enclosed-pills"` to achieve a pill-style appearance for each tab item, using pill-shaped borders and smoother outlines. + +::: demo + + + Home + Profile + Contact + Disabled + + + + Home tab content + + + Profile tab content + + + Contact tab content + + + Disabled tab content + + + +::: +```vue + + + Home + Profile + Contact + Disabled + + + + Home tab content + + + Profile tab content + + + Contact tab content + + + Disabled tab content + + + +``` + ### Fill and justify Force your ``'s contents to extend the full available width one of two modifier classes. To proportionately fill all available space use `layout="fill"`. Notice that all horizontal space is occupied, but not every nav item has the same width. diff --git a/packages/docs/package.json b/packages/docs/package.json index 43b43f9c..e190d802 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,6 +1,6 @@ { "name": "@coreui/vue-docs", - "version": "5.4.1", + "version": "5.5.0", "scripts": { "api": "vue-docgen -c build/docgen.config.js", "dev": "vuepress dev --clean-cache", @@ -9,28 +9,28 @@ "license": "MIT", "devDependencies": { "@coreui/chartjs": "^4.0.0", - "@coreui/coreui": "^5.2.0", + "@coreui/coreui": "^5.4.0", "@coreui/icons": "^3.0.1", "@coreui/icons-vue": "^2.2.0", "@coreui/utils": "^2.0.2", "@coreui/vue-chartjs": "^3.0.0", - "@docsearch/css": "^3.6.2", - "@docsearch/js": "^3.6.2", - "@vuepress/bundler-vite": "2.0.0-rc.18", - "@vuepress/bundler-webpack": "2.0.0-rc.18", - "@vuepress/plugin-active-header-links": "2.0.0-rc.55", - "@vuepress/plugin-git": "2.0.0-rc.56", - "@vuepress/plugin-markdown-container": "2.0.0-rc.54", + "@docsearch/css": "^3.9.0", + "@docsearch/js": "^3.9.0", + "@vuepress/bundler-vite": "2.0.0-rc.19", + "@vuepress/bundler-webpack": "2.0.0-rc.19", + "@vuepress/plugin-active-header-links": "2.0.0-rc.69", + "@vuepress/plugin-git": "2.0.0-rc.68", + "@vuepress/plugin-markdown-container": "2.0.0-rc.66", "@vuepress/plugin-prismjs": "2.0.0-rc.37", - "@vuepress/plugin-theme-data": "2.0.0-rc.57", - "@vuepress/plugin-register-components": "2.0.0-rc.54", - "@vuepress/plugin-toc": "2.0.0-rc.55", - "@vuepress/shared": "2.0.0-rc.18", - "@vuepress/utils": "2.0.0-rc.18", + "@vuepress/plugin-theme-data": "2.0.0-rc.69", + "@vuepress/plugin-register-components": "2.0.0-rc.66", + "@vuepress/plugin-toc": "2.0.0-rc.66", + "@vuepress/shared": "2.0.0-rc.19", + "@vuepress/utils": "2.0.0-rc.19", "markdown-it-anchor": "^9.2.0", "markdown-it-include": "^2.0.0", - "sass": "^1.80.4", + "sass": "^1.89.1", "vue-docgen-cli": "^4.79.0", - "vuepress": "2.0.0-rc.18" + "vuepress": "2.0.0-rc.19" } } diff --git a/prettier.config.mjs b/prettier.config.mjs new file mode 100644 index 00000000..c901ceaf --- /dev/null +++ b/prettier.config.mjs @@ -0,0 +1,13 @@ +/** + * @see https://prettier.io/docs/en/configuration.html + * @type {import("prettier").Config} + */ +const config = { + printWidth: 100, + semi: false, + singleQuote: true, + tabWidth: 2, + trailingComma: 'es5', +} + +export default config