@veritree/ui 0.69.0 → 0.72.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +17 -0
- package/.vscode/settings.json +19 -1
- package/index.js +29 -166
- package/mixins/form-control.js +6 -4
- package/nuxt.js +3 -0
- package/package.json +16 -10
- package/src/components/Badge/VTBadgeNew.vue +13 -0
- package/src/components/Breadcrumb/VTBreadcrumbItem.vue +11 -0
- package/src/components/Breadcrumb/VTBreadcrumbLink.vue +28 -0
- package/src/components/Breadcrumb/VTBreadcrumbList.vue +11 -0
- package/src/components/Breadcrumb/VTBreadcrumbRoot.vue +11 -0
- package/src/components/Breadcrumb/VTBreadcrumbSeparator.vue +19 -0
- package/src/components/Button/VTButton.vue +23 -22
- package/src/components/Dialog/VTDialogContent.vue +1 -1
- package/src/components/Disclosure/VTDisclosureContent.vue +2 -2
- package/src/components/Popover/VTPopoverDivider.vue +1 -1
- package/src/components/Separator/VTSeparator.vue +13 -0
- package/src/components/Switch/VTSwitch.vue +58 -0
- package/stylelint.config.js +26 -0
- package/tailwind.config.js +9 -0
- package/test/switch.test.js +125 -0
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
root: true,
|
|
3
|
+
env: {
|
|
4
|
+
browser: true,
|
|
5
|
+
node: true,
|
|
6
|
+
},
|
|
7
|
+
parserOptions: {
|
|
8
|
+
parser: '@babel/eslint-parser',
|
|
9
|
+
requireConfigFile: false,
|
|
10
|
+
},
|
|
11
|
+
extends: ['plugin:nuxt/recommended', 'prettier'],
|
|
12
|
+
plugins: [],
|
|
13
|
+
// add your custom rules here
|
|
14
|
+
rules: {
|
|
15
|
+
camelcase: 'off',
|
|
16
|
+
},
|
|
17
|
+
};
|
package/.vscode/settings.json
CHANGED
|
@@ -1 +1,19 @@
|
|
|
1
|
-
{
|
|
1
|
+
{
|
|
2
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
3
|
+
"editor.formatOnSave": true,
|
|
4
|
+
"editor.formatOnPaste": false,
|
|
5
|
+
"[vue]": {
|
|
6
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
7
|
+
"editor.formatOnSave": true,
|
|
8
|
+
"editor.tabSize": 2
|
|
9
|
+
},
|
|
10
|
+
"[javascript]": {
|
|
11
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
12
|
+
"editor.formatOnSave": true,
|
|
13
|
+
"editor.tabSize": 2
|
|
14
|
+
},
|
|
15
|
+
"editor.tabSize": 2,
|
|
16
|
+
"prettier.tabWidth": 2,
|
|
17
|
+
"typescript.validate.enable": false,
|
|
18
|
+
"javascript.validate.enable": false
|
|
19
|
+
}
|
package/index.js
CHANGED
|
@@ -1,167 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import VTImageHover from './src/components/Image/VTImageHover.vue';
|
|
10
|
-
import VTDropdownMenu from './src/components/DropdownMenu/VTDropdownMenu.vue';
|
|
11
|
-
import VTDropdownMenuContent from './src/components/DropdownMenu/VTDropdownMenuContent.vue';
|
|
12
|
-
import VTDropdownMenuDivider from './src/components/DropdownMenu/VTDropdownMenuDivider.vue';
|
|
13
|
-
import VTDropdownMenuGroup from './src/components/DropdownMenu/VTDropdownMenuGroup.vue';
|
|
14
|
-
import VTDropdownMenuItem from './src/components/DropdownMenu/VTDropdownMenuItem.vue';
|
|
15
|
-
import VTDropdownMenuLabel from './src/components/DropdownMenu/VTDropdownMenuLabel.vue';
|
|
16
|
-
import VTDropdownMenuTrigger from './src/components/DropdownMenu/VTDropdownMenuTrigger.vue';
|
|
17
|
-
import VTPopover from './src/components/Popover/VTPopover.vue';
|
|
18
|
-
import VTPopoverContent from './src/components/Popover/VTPopoverContent.vue';
|
|
19
|
-
import VTPopoverDivider from './src/components/Popover/VTPopoverDivider.vue';
|
|
20
|
-
import VTPopoverGroup from './src/components/Popover/VTPopoverGroup.vue';
|
|
21
|
-
import VTPopoverItem from './src/components/Popover/VTPopoverItem.vue';
|
|
22
|
-
import VTPopoverTrigger from './src/components/Popover/VTPopoverTrigger.vue';
|
|
23
|
-
import VTForm from './src/components/Form/VTForm.vue';
|
|
24
|
-
import VTFormRow from './src/components/Form/VTFormRow.vue';
|
|
25
|
-
import VTFormCol from './src/components/Form/VTFormCol.vue';
|
|
26
|
-
import VTFieldset from './src/components/Form/VTFieldset.vue';
|
|
27
|
-
import VTLegend from './src/components/Form/VTLegend.vue';
|
|
28
|
-
import VTFormFeedback from './src/components/Form/VTFormFeedback.vue';
|
|
29
|
-
import VTFormGroup from './src/components/Form/VTFormGroup.vue';
|
|
30
|
-
import VTInput from './src/components/Form/VTInput.vue';
|
|
31
|
-
import VTInputIcon from './src/components/Form/VTInputIcon.vue';
|
|
32
|
-
import VTInputPassword from './src/components/Form/VTInputPassword.vue';
|
|
33
|
-
import VTListbox from './src/components/Listbox/VTListbox.vue';
|
|
34
|
-
import VTListboxContent from './src/components/Listbox/VTListboxContent.vue';
|
|
35
|
-
import VTListboxDivider from './src/components/Listbox/VTListboxDivider.vue';
|
|
36
|
-
import VTListboxGroup from './src/components/Listbox/VTListboxGroup.vue';
|
|
37
|
-
import VTListboxItem from './src/components/Listbox/VTListboxItem.vue';
|
|
38
|
-
import VTListboxLabel from './src/components/Listbox/VTListboxLabel.vue';
|
|
39
|
-
import VTListboxList from './src/components/Listbox/VTListboxList.vue';
|
|
40
|
-
import VTListboxSearch from './src/components/Listbox/VTListboxSearch.vue';
|
|
41
|
-
import VTListboxTrigger from './src/components/Listbox/VTListboxTrigger.vue';
|
|
42
|
-
import VTListboxViewport from './src/components/Listbox/VTListboxViewport.vue';
|
|
43
|
-
import VTListboxPlaceholder from './src/components/Listbox/VTListboxPlaceholder.vue';
|
|
44
|
-
import VTSpinner from './src/components/Spinner/VTSpinner.vue';
|
|
45
|
-
import VTInputDate from './src/components/Input/VTInputDate.vue';
|
|
46
|
-
import VTInputFile from './src/components/Input/VTInputFile.vue';
|
|
47
|
-
import VTInputUpload from './src/components/Input/VTInputUpload.vue';
|
|
48
|
-
import VTProgressBar from './src/components/ProgressBar/VTProgressBar.vue';
|
|
49
|
-
import VTTextarea from './src/components/Textarea/VTTextarea.vue';
|
|
50
|
-
import VTModal from './src/components/Modal/VTModal.vue';
|
|
51
|
-
import VTTab from './src/components/Tabs/VTTab.vue';
|
|
52
|
-
import VTTabGroup from './src/components/Tabs/VTTabGroup.vue';
|
|
53
|
-
import VTTabList from './src/components/Tabs/VTTabList.vue';
|
|
54
|
-
import VTTabPanel from './src/components/Tabs/VTTabPanel.vue';
|
|
55
|
-
import VTTabPanels from './src/components/Tabs/VTTabPanels.vue';
|
|
56
|
-
import VTDialog from './src/components/Dialog/VTDialog.vue';
|
|
57
|
-
import VTDialogClose from './src/components/Dialog/VTDialogClose.vue';
|
|
58
|
-
import VTDialogContent from './src/components/Dialog/VTDialogContent.vue';
|
|
59
|
-
import VTDialogFooter from './src/components/Dialog/VTDialogFooter.vue';
|
|
60
|
-
import VTDialogHeader from './src/components/Dialog/VTDialogHeader.vue';
|
|
61
|
-
import VTDialogMain from './src/components/Dialog/VTDialogMain.vue';
|
|
62
|
-
import VTDialogOverlay from './src/components/Dialog/VTDialogOverlay.vue';
|
|
63
|
-
import VTDialogTitle from './src/components/Dialog/VTDialogTitle.vue';
|
|
64
|
-
import VTDrawer from './src/components/Drawer/VTDrawer.vue';
|
|
65
|
-
import VTDrawerClose from './src/components/Drawer/VTDrawerClose.vue';
|
|
66
|
-
import VTDrawerContent from './src/components/Drawer/VTDrawerContent.vue';
|
|
67
|
-
import VTDrawerFooter from './src/components/Drawer/VTDrawerFooter.vue';
|
|
68
|
-
import VTDrawerHeader from './src/components/Drawer/VTDrawerHeader.vue';
|
|
69
|
-
import VTDrawerTitle from './src/components/Drawer/VTDrawerTitle.vue';
|
|
70
|
-
import VTDrawerMain from './src/components/Drawer/VTDrawerMain.vue';
|
|
71
|
-
import VTDrawerOverlay from './src/components/Drawer/VTDrawerOverlay.vue';
|
|
72
|
-
import VTDisclosure from './src/components/Disclosure/VTDisclosure.vue';
|
|
73
|
-
import VTDisclosureDetails from './src/components/Disclosure/VTDisclosureDetails.vue';
|
|
74
|
-
import VTDisclosureHeader from './src/components/Disclosure/VTDisclosureHeader.vue';
|
|
75
|
-
import VTDisclosureIcon from './src/components/Disclosure/VTDisclosureIcon.vue';
|
|
76
|
-
import VTDisclosureContent from './src/components/Disclosure/VTDisclosureContent.vue';
|
|
77
|
-
import VTSkeleton from './src/components/Skeleton/VTSkeleton.vue';
|
|
78
|
-
import VTSkeletonItem from './src/components/Skeleton/VTSkeletonItem.vue';
|
|
79
|
-
import VTCarousel from './src/components/Carousel/VTCarousel.vue';
|
|
80
|
-
import VTCarouselBackward from './src/components/Carousel/VTCarouselBackward.vue';
|
|
81
|
-
import VTCarouselForward from './src/components/Carousel/VTCarouselForward.vue';
|
|
82
|
-
import VTCarouselTracker from './src/components/Carousel/VTCarouselTracker.vue';
|
|
1
|
+
/**
|
|
2
|
+
* Dynamically imports all Vue components from the specified directory and its subdirectories.
|
|
3
|
+
*
|
|
4
|
+
* @param {Function} r - The require.context function.
|
|
5
|
+
* @returns {Object} An object containing all imported Vue components, where the keys are the component names.
|
|
6
|
+
*/
|
|
7
|
+
function importAll(r) {
|
|
8
|
+
const components = {};
|
|
83
9
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
VTPopoverTrigger,
|
|
106
|
-
VTForm,
|
|
107
|
-
VTFormCol,
|
|
108
|
-
VTFormFeedback,
|
|
109
|
-
VTFormGroup,
|
|
110
|
-
VTFormRow,
|
|
111
|
-
VTFieldset,
|
|
112
|
-
VTLegend,
|
|
113
|
-
VTListbox,
|
|
114
|
-
VTListboxContent,
|
|
115
|
-
VTListboxDivider,
|
|
116
|
-
VTListboxGroup,
|
|
117
|
-
VTListboxItem,
|
|
118
|
-
VTListboxLabel,
|
|
119
|
-
VTListboxList,
|
|
120
|
-
VTListboxSearch,
|
|
121
|
-
VTListboxTrigger,
|
|
122
|
-
VTListboxPlaceholder,
|
|
123
|
-
VTListboxViewport,
|
|
124
|
-
VTButton,
|
|
125
|
-
VTInput,
|
|
126
|
-
VTInputIcon,
|
|
127
|
-
VTInputPassword,
|
|
128
|
-
VTInputDate,
|
|
129
|
-
VTInputFile,
|
|
130
|
-
VTInputUpload,
|
|
131
|
-
VTProgressBar,
|
|
132
|
-
VTTextarea,
|
|
133
|
-
VTModal,
|
|
134
|
-
VTTab,
|
|
135
|
-
VTTabGroup,
|
|
136
|
-
VTTabList,
|
|
137
|
-
VTTabPanel,
|
|
138
|
-
VTTabPanels,
|
|
139
|
-
VTDrawer,
|
|
140
|
-
VTDrawerClose,
|
|
141
|
-
VTDrawerContent,
|
|
142
|
-
VTDrawerFooter,
|
|
143
|
-
VTDrawerHeader,
|
|
144
|
-
VTDrawerTitle,
|
|
145
|
-
VTDrawerMain,
|
|
146
|
-
VTDrawerOverlay,
|
|
147
|
-
VTDialog,
|
|
148
|
-
VTDialogClose,
|
|
149
|
-
VTDialogContent,
|
|
150
|
-
VTDialogFooter,
|
|
151
|
-
VTDialogHeader,
|
|
152
|
-
VTDialogMain,
|
|
153
|
-
VTDialogOverlay,
|
|
154
|
-
VTDialogTitle,
|
|
155
|
-
VTDisclosure,
|
|
156
|
-
VTDisclosureDetails,
|
|
157
|
-
VTDisclosureHeader,
|
|
158
|
-
VTDisclosureIcon,
|
|
159
|
-
VTDisclosureContent,
|
|
160
|
-
VTSkeleton,
|
|
161
|
-
VTSkeletonItem,
|
|
162
|
-
VTChip,
|
|
163
|
-
VTCarousel,
|
|
164
|
-
VTCarouselBackward,
|
|
165
|
-
VTCarouselForward,
|
|
166
|
-
VTCarouselTracker
|
|
167
|
-
};
|
|
10
|
+
r.keys().forEach((key) => {
|
|
11
|
+
const componentName = key.replace(/^.+\/([^/]+)\.vue$/, '$1');
|
|
12
|
+
components[componentName] = r(key).default;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return components;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The components object containing all imported Vue components.
|
|
20
|
+
*
|
|
21
|
+
* @type {Object}
|
|
22
|
+
*/
|
|
23
|
+
const components = importAll(
|
|
24
|
+
require.context('./src/components/', true, /\.vue$/),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Export each component individually
|
|
28
|
+
Object.entries(components).forEach(([componentName, component]) => {
|
|
29
|
+
module.exports[componentName] = component;
|
|
30
|
+
});
|
package/mixins/form-control.js
CHANGED
|
@@ -21,7 +21,7 @@ export const formControlMixin = {
|
|
|
21
21
|
type: [String, Object, Function],
|
|
22
22
|
default: '',
|
|
23
23
|
},
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
/**
|
|
26
26
|
* Specifies the size of the button
|
|
27
27
|
*
|
|
@@ -73,7 +73,7 @@ export const formControlStyleMixin = {
|
|
|
73
73
|
return [
|
|
74
74
|
this.headless
|
|
75
75
|
? `${this.name}`
|
|
76
|
-
: 'leading-0 bg-white disabled:bg-gray-200 flex w-full max-w-full relative appearance-none placeholder:font-light placeholder:text-gray-500 items-center justify-between rounded border border-solid px-3 py-2 font-inherit
|
|
76
|
+
: 'leading-0 bg-white disabled:bg-gray-200 flex w-full max-w-full relative appearance-none placeholder:font-light placeholder:text-gray-500 items-center justify-between rounded border border-solid px-3 py-2 font-inherit text-inherit file:hidden focus:border-gray-600 focus:placeholder:text-gray-400 disabled:text-gray-500',
|
|
77
77
|
// variant styles
|
|
78
78
|
this.headless
|
|
79
79
|
? `${this.name}--${this.variant}`
|
|
@@ -87,12 +87,14 @@ export const formControlStyleMixin = {
|
|
|
87
87
|
? null
|
|
88
88
|
: this.name === 'textarea'
|
|
89
89
|
? 'min-h-10' // limit it because input type number height can be different from other input types
|
|
90
|
-
: this.size === 'small'
|
|
90
|
+
: this.size === 'small'
|
|
91
|
+
? 'h-8 text-sm'
|
|
92
|
+
: 'h-10 text-base',
|
|
91
93
|
// disabled styles
|
|
92
94
|
this.disabled
|
|
93
95
|
? this.headless
|
|
94
96
|
? `${this.name}--disabled`
|
|
95
|
-
:
|
|
97
|
+
: null
|
|
96
98
|
: null,
|
|
97
99
|
];
|
|
98
100
|
},
|
package/nuxt.js
CHANGED
|
@@ -3,6 +3,7 @@ import { join } from 'path';
|
|
|
3
3
|
const components = [
|
|
4
4
|
'src/components/Alert',
|
|
5
5
|
'src/components/Avatar',
|
|
6
|
+
'src/components/Badge',
|
|
6
7
|
'src/components/Button',
|
|
7
8
|
'src/components/Carousel',
|
|
8
9
|
'src/components/Chip',
|
|
@@ -19,6 +20,8 @@ const components = [
|
|
|
19
20
|
'src/components/Spinner',
|
|
20
21
|
'src/components/Tabs',
|
|
21
22
|
'src/components/Tooltip',
|
|
23
|
+
'src/components/Switch',
|
|
24
|
+
'src/components/Separator',
|
|
22
25
|
];
|
|
23
26
|
|
|
24
27
|
export default function () {
|
package/package.json
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@veritree/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.72.1",
|
|
4
4
|
"description": "veritree ui library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"repository": "https://github.com/tentree-org/veritree-ui.git",
|
|
8
8
|
"author": "cyroveritree <cyro@veritree.com>",
|
|
9
|
-
"license": "MIT",
|
|
10
|
-
"publishConfig": {
|
|
11
|
-
"registry": "https://registry.npmjs.org"
|
|
12
|
-
},
|
|
13
9
|
"scripts": {
|
|
14
10
|
"test": "vitest",
|
|
15
11
|
"coverage": "vitest run --coverage",
|
|
@@ -21,13 +17,23 @@
|
|
|
21
17
|
"@veritree/icons": "^0.60.0"
|
|
22
18
|
},
|
|
23
19
|
"devDependencies": {
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
20
|
+
"@babel/eslint-parser": "^7.23.10",
|
|
21
|
+
"eslint": "^8.57.0",
|
|
22
|
+
"eslint-config-prettier": "^9.1.0",
|
|
23
|
+
"eslint-plugin-vue": "^9.23.0",
|
|
24
|
+
"jsdom": "^24.0.0",
|
|
25
|
+
"np": "^10.0.2",
|
|
26
|
+
"prettier": "^3.2.5",
|
|
27
|
+
"prettier-plugin-tailwindcss": "^0.5.12",
|
|
28
|
+
"stylelint": "^16.2.1",
|
|
29
|
+
"stylelint-config-prettier": "^9.0.5",
|
|
30
|
+
"stylelint-config-recommended-vue": "^1.5.0",
|
|
31
|
+
"stylelint-config-standard": "^36.0.0",
|
|
27
32
|
"tailwindcss": "^3.4.1"
|
|
28
33
|
},
|
|
29
34
|
"engines": {
|
|
30
35
|
"npm": ">=8.0.0",
|
|
31
36
|
"node": ">=18.0.0"
|
|
32
|
-
}
|
|
33
|
-
|
|
37
|
+
},
|
|
38
|
+
"packageManager": "yarn@4.1.1"
|
|
39
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component :is="as" :href="href" :to="to" class="link-base link-underlined">
|
|
3
|
+
<slot />
|
|
4
|
+
</component>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
export default {
|
|
9
|
+
name: 'BreadcrumbLink',
|
|
10
|
+
|
|
11
|
+
props: {
|
|
12
|
+
href: {
|
|
13
|
+
type: String,
|
|
14
|
+
default: null,
|
|
15
|
+
},
|
|
16
|
+
to: {
|
|
17
|
+
type: String,
|
|
18
|
+
default: null,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
computed: {
|
|
23
|
+
as() {
|
|
24
|
+
return this.href ? 'a' : this.to ? 'NuxtLink' : 'button';
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<li>
|
|
3
|
+
<slot>
|
|
4
|
+
<IconChevronRight />
|
|
5
|
+
</slot>
|
|
6
|
+
</li>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script>
|
|
10
|
+
import { IconChevronRight } from '@veritree/icons';
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
name: 'BreadcrumbSeparator',
|
|
14
|
+
|
|
15
|
+
components: {
|
|
16
|
+
IconChevronRight,
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
</script>
|
|
@@ -11,36 +11,37 @@
|
|
|
11
11
|
headless
|
|
12
12
|
? 'button'
|
|
13
13
|
: isIcon
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
? 'relative inline-flex items-center justify-center rounded-full [&_svg]:max-h-full [&_svg]:max-w-full'
|
|
15
|
+
: 'relative inline-flex rounded border border-solid px-4 text-sm font-semibold leading-none no-underline transition-all',
|
|
16
16
|
// variant styles
|
|
17
17
|
headless
|
|
18
18
|
? `button--${variant}`
|
|
19
19
|
: isPrimary
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
? 'bg-secondary-400 hover:bg-secondary-500 focus:bg-secondary-600 active:bg-secondary-600 border-transparent text-white disabled:bg-gray-200 disabled:text-gray-400'
|
|
21
|
+
: isSecondary
|
|
22
|
+
? isGhost
|
|
23
|
+
? 'border-gray-500 text-gray-100 hover:bg-white hover:text-gray-700'
|
|
24
|
+
: 'border-gray-400 bg-white text-gray-700 hover:bg-gray-100 focus:bg-gray-200 active:bg-gray-200 disabled:border-gray-300 disabled:text-gray-400'
|
|
25
|
+
: isTertiary
|
|
26
|
+
? 'border-transparent text-gray-600 hover:text-gray-800 focus:text-gray-800 active:text-gray-800 disabled:text-gray-400'
|
|
27
|
+
: isDark
|
|
28
|
+
? 'border-transparent bg-gray-800 text-white hover:bg-gray-700 active:bg-gray-600 disabled:bg-gray-200 disabled:text-gray-400'
|
|
29
|
+
: isIcon
|
|
30
|
+
? 'text-primary-100 focus-within:bg-gray-200 hover:bg-gray-200 active:bg-gray-300 disabled:bg-gray-200 disabled:text-gray-400'
|
|
31
|
+
: null,
|
|
32
32
|
// sizes styles
|
|
33
33
|
headless
|
|
34
34
|
? `button--${size}`
|
|
35
35
|
: isLarge
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
? isIcon
|
|
37
|
+
? 'h-8 w-8'
|
|
38
|
+
: 'h-10'
|
|
39
|
+
: isSmall
|
|
40
|
+
? isIcon
|
|
41
|
+
? 'h-6 w-6 p-1'
|
|
42
|
+
: 'h-8'
|
|
43
|
+
: null,
|
|
44
|
+
isDisabled ? (isIcon ? '[&_svg]:text-gray-400' : null) : null,
|
|
44
45
|
]"
|
|
45
46
|
v-on="$listeners"
|
|
46
47
|
>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
:class="
|
|
16
16
|
headless
|
|
17
17
|
? 'dialog-content'
|
|
18
|
-
: `relative m-auto flex flex-col overflow-auto rounded bg-white px-4 focus:outline-none
|
|
18
|
+
: `relative m-auto flex flex-col overflow-auto rounded bg-white px-4 focus:outline-none md:px-6 ${classes}`
|
|
19
19
|
"
|
|
20
20
|
tabindex="-1"
|
|
21
21
|
@keydown.esc.stop="onEsc"
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="relative flex w-11 h-6 px-0.5 items-center">
|
|
3
|
+
<input
|
|
4
|
+
ref="input"
|
|
5
|
+
:checked="checkedComputed"
|
|
6
|
+
:disabled="disabled"
|
|
7
|
+
:value="valueComputed"
|
|
8
|
+
class="absolute inset-0 appearance-none peer rounded-full transition-colors bg-gray-400 checked:bg-secondary-300 disabled:bg-gray-200"
|
|
9
|
+
role="switch"
|
|
10
|
+
type="checkbox"
|
|
11
|
+
@change="onChange"
|
|
12
|
+
/>
|
|
13
|
+
<span
|
|
14
|
+
class="size-5 rounded-full bg-white transition-transform translate-x-0 peer-checked:translate-x-full pointer-events-none peer-disabled:bg-gray-400"
|
|
15
|
+
/>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script>
|
|
20
|
+
export default {
|
|
21
|
+
model: {
|
|
22
|
+
prop: 'value',
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
props: {
|
|
26
|
+
disabled: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: null,
|
|
29
|
+
},
|
|
30
|
+
value: {
|
|
31
|
+
type: [Array, Boolean, Number, String],
|
|
32
|
+
default: false,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
computed: {
|
|
37
|
+
checkedComputed() {
|
|
38
|
+
return this.value;
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
valueComputed: {
|
|
42
|
+
get() {
|
|
43
|
+
return this.value;
|
|
44
|
+
},
|
|
45
|
+
set(newVal) {
|
|
46
|
+
this.$emit('input', newVal);
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
methods: {
|
|
52
|
+
onChange(event) {
|
|
53
|
+
this.valueComputed = !Boolean(this.valueComputed);
|
|
54
|
+
this.$emit('change', event);
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
</script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
customSyntax: 'postcss-html',
|
|
3
|
+
extends: [
|
|
4
|
+
'stylelint-config-standard',
|
|
5
|
+
'stylelint-config-recommended-vue',
|
|
6
|
+
'stylelint-config-prettier',
|
|
7
|
+
],
|
|
8
|
+
// add your custom config here
|
|
9
|
+
// https://stylelint.io/user-guide/configuration
|
|
10
|
+
rules: {
|
|
11
|
+
'selector-class-pattern': null,
|
|
12
|
+
'selector-anb-no-unmatchable': null,
|
|
13
|
+
'at-rule-no-unknown': [
|
|
14
|
+
true,
|
|
15
|
+
{
|
|
16
|
+
ignoreAtRules: [
|
|
17
|
+
'tailwind',
|
|
18
|
+
'apply',
|
|
19
|
+
'variants',
|
|
20
|
+
'responsive',
|
|
21
|
+
'screen',
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { mount } from '@vue/test-utils';
|
|
2
|
+
import VTSwitch from '@/components/Switch/VTSwitch.vue';
|
|
3
|
+
|
|
4
|
+
describe('VTSwitch.vue', () => {
|
|
5
|
+
it('renders root div with correct classes', () => {
|
|
6
|
+
const wrapper = mount(VTSwitch);
|
|
7
|
+
const rootDiv = wrapper.find('div');
|
|
8
|
+
|
|
9
|
+
expect(rootDiv.classes()).toContain(
|
|
10
|
+
'relative',
|
|
11
|
+
'flex',
|
|
12
|
+
'w-11',
|
|
13
|
+
'h-6',
|
|
14
|
+
'px-0.5',
|
|
15
|
+
'items-center',
|
|
16
|
+
);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('renders checkbox input with correct attributes and classes', () => {
|
|
20
|
+
const wrapper = mount(VTSwitch);
|
|
21
|
+
const checkboxInput = wrapper.find('input[type="checkbox"]');
|
|
22
|
+
|
|
23
|
+
expect(checkboxInput.classes()).toContain(
|
|
24
|
+
'absolute',
|
|
25
|
+
'inset-0',
|
|
26
|
+
'appearance-none',
|
|
27
|
+
'peer',
|
|
28
|
+
'rounded-full',
|
|
29
|
+
'transition-colors',
|
|
30
|
+
'bg-gray-400',
|
|
31
|
+
'checked:bg-secondary-300',
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('renders span element with correct classes', () => {
|
|
36
|
+
const wrapper = mount(VTSwitch);
|
|
37
|
+
const spanElement = wrapper.find('span');
|
|
38
|
+
|
|
39
|
+
expect(spanElement.classes()).toContain(
|
|
40
|
+
'size-5',
|
|
41
|
+
'rounded-full',
|
|
42
|
+
'bg-white',
|
|
43
|
+
'transition-transform',
|
|
44
|
+
'translate-x-0',
|
|
45
|
+
'peer-checked:translate-x-full',
|
|
46
|
+
'pointer-events-none',
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('emits change event and updates value when checkbox is toggled', async () => {
|
|
51
|
+
const wrapper = mount(VTSwitch, {
|
|
52
|
+
propsData: {
|
|
53
|
+
value: false,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
const checkboxInput = wrapper.find('input[type="checkbox"]');
|
|
57
|
+
|
|
58
|
+
// Simulate a change event on the checkbox input
|
|
59
|
+
await checkboxInput.trigger('change');
|
|
60
|
+
|
|
61
|
+
// Toggle the value prop
|
|
62
|
+
await wrapper.setProps({ value: !wrapper.props().value });
|
|
63
|
+
|
|
64
|
+
expect(wrapper.vm.valueComputed).toBe(true);
|
|
65
|
+
|
|
66
|
+
// Verify that the change event is emitted
|
|
67
|
+
expect(wrapper.emitted()).toHaveProperty('change');
|
|
68
|
+
|
|
69
|
+
// Verify that the value prop is updated to true
|
|
70
|
+
expect(wrapper.props().value).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('updates checkedComputed property when checkbox is toggled', async () => {
|
|
74
|
+
// Mount the component with value prop set to true
|
|
75
|
+
const wrapper = mount(VTSwitch, {
|
|
76
|
+
propsData: {
|
|
77
|
+
value: false,
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Verify that the checkedComputed computed property is true
|
|
82
|
+
expect(wrapper.vm.checkedComputed).toBe(false);
|
|
83
|
+
|
|
84
|
+
const checkboxInput = wrapper.find('input[type="checkbox"]');
|
|
85
|
+
|
|
86
|
+
// Simulate a change event on the checkbox input
|
|
87
|
+
await checkboxInput.trigger('change');
|
|
88
|
+
|
|
89
|
+
// Toggle the value prop
|
|
90
|
+
await wrapper.setProps({ value: !wrapper.props().value });
|
|
91
|
+
|
|
92
|
+
// Verify that the checkedComputed computed property is true
|
|
93
|
+
expect(wrapper.vm.checkedComputed).toBe(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('renders a disabled checkbox when disabled prop is true', async () => {
|
|
97
|
+
// Mount the component with disabled prop set to true
|
|
98
|
+
const wrapper = mount(VTSwitch, {
|
|
99
|
+
propsData: {
|
|
100
|
+
disabled: true,
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// Find the checkbox input element
|
|
105
|
+
const checkboxInput = wrapper.find('input[type="checkbox"]');
|
|
106
|
+
|
|
107
|
+
// Verify that the checkbox is disabled
|
|
108
|
+
expect(checkboxInput.attributes('disabled')).toBe('disabled');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('renders an enabled checkbox when disabled prop is false', async () => {
|
|
112
|
+
// Mount the component with disabled prop set to false
|
|
113
|
+
const wrapper = mount(VTSwitch, {
|
|
114
|
+
propsData: {
|
|
115
|
+
disabled: false,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Find the checkbox input element
|
|
120
|
+
const checkboxInput = wrapper.find('input[type="checkbox"]');
|
|
121
|
+
|
|
122
|
+
// Verify that the checkbox is enabled
|
|
123
|
+
expect(checkboxInput.attributes('disabled')).toBeUndefined();
|
|
124
|
+
});
|
|
125
|
+
});
|