@rocketui/vue 0.0.47 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rocket-ui-vue.cjs.js +1 -0
- package/dist/rocket-ui-vue.d.ts +1812 -0
- package/dist/rocket-ui-vue.es.js +9270 -0
- package/dist/rocket-ui-vue.umd.js +1 -0
- package/dist/style.css +2 -0
- package/package.json +7 -1
- package/.eslintrc.cjs +0 -79
- package/.gitattributes +0 -2
- package/.github/workflows/chromatic.yml +0 -28
- package/.github/workflows/publish-storybook.yml +0 -41
- package/.husky/pre-commit +0 -4
- package/.prettierrc.cjs +0 -10
- package/.storybook/Theme.js +0 -17
- package/.storybook/main.ts +0 -20
- package/.storybook/manager-head.html +0 -3
- package/.storybook/manager.js +0 -8
- package/.storybook/preview-head.html +0 -3
- package/.storybook/preview.ts +0 -36
- package/.storybook/source-panel/manager.js +0 -28
- package/.storybook/withSource.js +0 -91
- package/.vscode/extensions.json +0 -11
- package/.vscode/settings.json +0 -20
- package/index.html +0 -13
- package/lib/main.ts +0 -48
- package/postcss.config.cjs +0 -9
- package/resources/rocket-ui-logo-dark.svg +0 -27
- package/resources/rocket-ui-logo-light.svg +0 -27
- package/shims-rocketui.d.ts +0 -9
- package/src/App.vue +0 -15
- package/src/assets/blank-avatar.svg +0 -3
- package/src/assets/icons/mdi.js +0 -7302
- package/src/assets/logo.svg +0 -1
- package/src/components/Accordion/Accordion.mdx +0 -88
- package/src/components/Accordion/Accordion.stories.ts +0 -257
- package/src/components/Accordion/RAccordion.vue +0 -73
- package/src/components/Accordion/accordion.css +0 -75
- package/src/components/Accordion/accordion.spec.ts +0 -123
- package/src/components/Alert/Alert.mdx +0 -120
- package/src/components/Alert/Alert.stories.ts +0 -118
- package/src/components/Alert/RAlert.vue +0 -119
- package/src/components/Alert/alert.css +0 -136
- package/src/components/Alert/alert.spec.ts +0 -32
- package/src/components/Avatar/Avatar.mdx +0 -96
- package/src/components/Avatar/Avatar.stories.ts +0 -65
- package/src/components/Avatar/RAvatar.vue +0 -115
- package/src/components/Avatar/avatar.css +0 -82
- package/src/components/Avatar/avatar.spec.ts +0 -38
- package/src/components/Badge/Badge.mdx +0 -112
- package/src/components/Badge/Badge.stories.ts +0 -99
- package/src/components/Badge/RBadge.vue +0 -89
- package/src/components/Badge/badge.css +0 -63
- package/src/components/Badge/badge.spec.ts +0 -20
- package/src/components/Box/Box.mdx +0 -20
- package/src/components/Box/Box.stories.ts +0 -56
- package/src/components/Box/RBox.vue +0 -97
- package/src/components/Breadcrumb/Breadcrumb.stories.ts +0 -115
- package/src/components/Breadcrumb/RBreadcrumb.vue +0 -43
- package/src/components/Breadcrumb/breadcrumb.css +0 -29
- package/src/components/Button/Button.mdx +0 -148
- package/src/components/Button/Button.spec.ts +0 -29
- package/src/components/Button/Button.stories.ts +0 -118
- package/src/components/Button/RButton.vue +0 -179
- package/src/components/Button/button.css +0 -146
- package/src/components/Checkbox/Checkbox.mdx +0 -100
- package/src/components/Checkbox/Checkbox.stories.ts +0 -67
- package/src/components/Checkbox/RCheckbox.vue +0 -195
- package/src/components/Checkbox/checkbox.css +0 -67
- package/src/components/Checkbox/checkbox.spec.ts +0 -60
- package/src/components/Chips/Chip.mdx +0 -113
- package/src/components/Chips/Chip.stories.ts +0 -122
- package/src/components/Chips/RChip.vue +0 -125
- package/src/components/Chips/chip.css +0 -62
- package/src/components/Chips/chip.spec.ts +0 -40
- package/src/components/Dropdown/Dropdown.mdx +0 -135
- package/src/components/Dropdown/Dropdown.stories.ts +0 -84
- package/src/components/Dropdown/RDropdown.vue +0 -392
- package/src/components/Dropdown/dropdown.css +0 -113
- package/src/components/Dropdown/dropdown.spec.ts +0 -98
- package/src/components/Flex/Flex.mdx +0 -20
- package/src/components/Flex/Flex.stories.js +0 -127
- package/src/components/Flex/RFlex.vue +0 -91
- package/src/components/Grid/Grid.mdx +0 -20
- package/src/components/Grid/Grid.stories.js +0 -107
- package/src/components/Grid/RGrid.vue +0 -138
- package/src/components/Icon/Icon.mdx +0 -68
- package/src/components/Icon/Icon.stories.ts +0 -33
- package/src/components/Icon/RIcon.vue +0 -56
- package/src/components/Icon/icon.spec.ts +0 -25
- package/src/components/ItemGroup/ItemGroup.stories.ts +0 -91
- package/src/components/ItemGroup/RItem.vue +0 -74
- package/src/components/ItemGroup/RItemGroup.vue +0 -122
- package/src/components/ItemGroup/__snapshots__/itemgroup.spec.ts.snap +0 -13
- package/src/components/ItemGroup/itemgroup.spec.ts +0 -67
- package/src/components/Label/Label.mdx +0 -50
- package/src/components/Label/Label.stories.ts +0 -38
- package/src/components/Label/RLabel.vue +0 -42
- package/src/components/Label/label.css +0 -0
- package/src/components/Modal/Modal.mdx +0 -91
- package/src/components/Modal/Modal.stories.ts +0 -125
- package/src/components/Modal/RModal.vue +0 -130
- package/src/components/Modal/modal.css +0 -41
- package/src/components/Modal/modal.spec.ts +0 -25
- package/src/components/Pagination/Pagination.stories.ts +0 -24
- package/src/components/Pagination/RPagination.vue +0 -103
- package/src/components/Pagination/pagination.css +0 -47
- package/src/components/Pagination/pagination.spec.ts +0 -17
- package/src/components/ProgressBar/ProgressBar.stories.ts +0 -34
- package/src/components/ProgressBar/RProgressBar.vue +0 -21
- package/src/components/ProgressBar/progressbar.css +0 -24
- package/src/components/ProgressBar/progressbar.spec.ts +0 -17
- package/src/components/Shared/Enums.ts +0 -1
- package/src/components/Sidebar/RSidebar.vue +0 -27
- package/src/components/Sidebar/Sidebar.mdx +0 -31
- package/src/components/Sidebar/Sidebar.stories.ts +0 -34
- package/src/components/Sidebar/sidebar.css +0 -18
- package/src/components/Sidebar/sidebar.spec.ts +0 -33
- package/src/components/Snackbar/RSnackbar.vue +0 -136
- package/src/components/Snackbar/Snackbar.mdx +0 -126
- package/src/components/Snackbar/Snackbar.stories.ts +0 -93
- package/src/components/Snackbar/snackbar.css +0 -99
- package/src/components/Snackbar/snackbar.spec.ts +0 -56
- package/src/components/Switch/RSwitch.vue +0 -147
- package/src/components/Switch/Switch.mdx +0 -102
- package/src/components/Switch/Switch.stories.ts +0 -79
- package/src/components/Switch/switch.css +0 -102
- package/src/components/Switch/switch.spec.ts +0 -31
- package/src/components/TabItem/RTabItem.vue +0 -175
- package/src/components/TabItem/TabItem.mdx +0 -95
- package/src/components/TabItem/TabItem.spec.ts +0 -29
- package/src/components/TabItem/TabItem.stories.ts +0 -97
- package/src/components/TabItem/common.ts +0 -6
- package/src/components/TabItem/tab-item.css +0 -29
- package/src/components/Tabs/RTabs.vue +0 -94
- package/src/components/Tabs/Tabs.mdx +0 -78
- package/src/components/Tabs/Tabs.spec.ts +0 -28
- package/src/components/Tabs/Tabs.stories.ts +0 -191
- package/src/components/Tabs/tabs.css +0 -13
- package/src/components/Tabs/types.ts +0 -11
- package/src/components/TextArea/RTextArea.vue +0 -142
- package/src/components/TextArea/TextArea.mdx +0 -108
- package/src/components/TextArea/TextArea.stories.ts +0 -55
- package/src/components/TextArea/textarea.css +0 -51
- package/src/components/TextArea/textarea.spec.ts +0 -36
- package/src/components/Textfield/RTextfield.vue +0 -372
- package/src/components/Textfield/Textfield.mdx +0 -159
- package/src/components/Textfield/Textfield.stories.ts +0 -121
- package/src/components/Textfield/textfield.css +0 -81
- package/src/components/Textfield/textfield.spec.ts +0 -34
- package/src/components/Tooltip/RTooltip.vue +0 -325
- package/src/components/Tooltip/Tooltip.mdx +0 -111
- package/src/components/Tooltip/Tooltip.stories.ts +0 -203
- package/src/components/Tooltip/common.ts +0 -91
- package/src/components/Tooltip/tooltip.css +0 -34
- package/src/components/Tooltip/tooltip.spec.ts +0 -81
- package/src/components/Typography/Typography.mdx +0 -109
- package/src/components/Typography/typography.css +0 -128
- package/src/directives/index.ts +0 -19
- package/src/index.css +0 -241
- package/src/main.ts +0 -5
- package/src/scripts/buildIcons.js +0 -21
- package/src/stories/Colors.mdx +0 -355
- package/src/stories/GettingStarted.mdx +0 -121
- package/src/stories/Layout.mdx +0 -15
- package/tailwind.config.cjs +0 -16
- package/tsconfig.json +0 -24
- package/vite.config.ts +0 -39
- package/vitest.config.ts +0 -12
- /package/{public → dist}/design-tokens.source.json +0 -0
- /package/{public → dist}/favicon.ico +0 -0
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import Icon from '../Icon/RIcon.vue';
|
|
3
|
-
import { computed } from 'vue';
|
|
4
|
-
import './tab-item.css';
|
|
5
|
-
import { TabItemVariants, type TabItemVariant } from './common';
|
|
6
|
-
export interface IProps {
|
|
7
|
-
/**
|
|
8
|
-
* Id of the tab item
|
|
9
|
-
* @type string | number
|
|
10
|
-
* @default ''
|
|
11
|
-
* @example
|
|
12
|
-
* <TabItem id="1" />
|
|
13
|
-
*/
|
|
14
|
-
id: string | number;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Variant of the tab item
|
|
18
|
-
* @type TabItemVariant
|
|
19
|
-
* @default TabItemVariants.DEFAULT
|
|
20
|
-
* @example
|
|
21
|
-
* <TabItem variant="default" />
|
|
22
|
-
*/
|
|
23
|
-
variant?: TabItemVariant;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Label of the tab item
|
|
27
|
-
* @type string
|
|
28
|
-
* @default ''
|
|
29
|
-
* @example
|
|
30
|
-
* <TabItem label="Label" />
|
|
31
|
-
*/
|
|
32
|
-
label?: string;
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* prependIcon of the tab item
|
|
36
|
-
* @type string
|
|
37
|
-
* @default ''
|
|
38
|
-
* @example
|
|
39
|
-
* <TabItem prependIcon="prependIcon" />
|
|
40
|
-
*/
|
|
41
|
-
prependIcon?: string;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* appendIcon of the tab item
|
|
45
|
-
* @type string
|
|
46
|
-
* @default ''
|
|
47
|
-
* @example
|
|
48
|
-
* <TabItem appendIcon="appendIcon" />
|
|
49
|
-
*/
|
|
50
|
-
appendIcon?: string;
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Disabled state of the tab item
|
|
54
|
-
* @type ButtonHTMLAttributes['disabled']
|
|
55
|
-
* @default false
|
|
56
|
-
* @example
|
|
57
|
-
* <TabItem disabled />
|
|
58
|
-
*/
|
|
59
|
-
disabled?: boolean;
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Model value of the tab item
|
|
63
|
-
* @type string | number
|
|
64
|
-
* @default ''
|
|
65
|
-
* @example
|
|
66
|
-
* <TabItem v-model="model" />
|
|
67
|
-
*/
|
|
68
|
-
modelValue?: string | number;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Tile state of the tab item
|
|
72
|
-
* @type boolean
|
|
73
|
-
* @default false
|
|
74
|
-
* @example
|
|
75
|
-
* <TabItem tile />
|
|
76
|
-
*/
|
|
77
|
-
tile?: boolean;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Block state of the tab item
|
|
81
|
-
* @type boolean
|
|
82
|
-
* @default false
|
|
83
|
-
* @example
|
|
84
|
-
* <TabItem block />
|
|
85
|
-
*/
|
|
86
|
-
block?: boolean;
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Color of the tab item
|
|
90
|
-
* @type string
|
|
91
|
-
* @default ''
|
|
92
|
-
* @example
|
|
93
|
-
* <TabItem color="" />
|
|
94
|
-
*/
|
|
95
|
-
color?: string;
|
|
96
|
-
}
|
|
97
|
-
const props = withDefaults(defineProps<IProps>(), {
|
|
98
|
-
label: '',
|
|
99
|
-
variant: TabItemVariants.DEFAULT,
|
|
100
|
-
prependIcon: '',
|
|
101
|
-
appendIcon: '',
|
|
102
|
-
disabled: false,
|
|
103
|
-
modelValue: '',
|
|
104
|
-
tile: false,
|
|
105
|
-
block: false,
|
|
106
|
-
color: '',
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const emit = defineEmits(['update:modelValue', 'click:icon']);
|
|
110
|
-
|
|
111
|
-
const classes = computed(() => {
|
|
112
|
-
return {
|
|
113
|
-
'tab-item': true,
|
|
114
|
-
[`tab-item--${props.variant}`]: true,
|
|
115
|
-
'tab-item--tile': props.tile,
|
|
116
|
-
'tab-item--block': props.block,
|
|
117
|
-
};
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
const style = computed(() => {
|
|
121
|
-
return {
|
|
122
|
-
color: props.color,
|
|
123
|
-
};
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* @description Fires when the tab is clicked
|
|
128
|
-
* @param {id} id - The id of the tab
|
|
129
|
-
* @returns {void}
|
|
130
|
-
*/
|
|
131
|
-
function handleTab(id: number | string): void {
|
|
132
|
-
emit('update:modelValue', id);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* @description Fires when the icon is clicked
|
|
137
|
-
* @returns {void}
|
|
138
|
-
*/
|
|
139
|
-
function handleIconClick(): void {
|
|
140
|
-
emit('click:icon');
|
|
141
|
-
}
|
|
142
|
-
</script>
|
|
143
|
-
<template>
|
|
144
|
-
<button
|
|
145
|
-
:aria-disabled="props.disabled"
|
|
146
|
-
:aria-selected="props.modelValue === props.id"
|
|
147
|
-
:class="classes"
|
|
148
|
-
:style="style"
|
|
149
|
-
:disabled="props.disabled"
|
|
150
|
-
@click.stop="handleTab(props.id)"
|
|
151
|
-
>
|
|
152
|
-
<slot name="prepend">
|
|
153
|
-
<Icon
|
|
154
|
-
v-if="props.variant !== TabItemVariants.TEXT && props.prependIcon"
|
|
155
|
-
class="tab-item__prepend-icon"
|
|
156
|
-
:name="props.prependIcon"
|
|
157
|
-
:size="16"
|
|
158
|
-
/>
|
|
159
|
-
</slot>
|
|
160
|
-
|
|
161
|
-
<span v-if="props.variant !== TabItemVariants.ICON" class="tab-item__label">
|
|
162
|
-
{{ props.label }}
|
|
163
|
-
</span>
|
|
164
|
-
|
|
165
|
-
<slot name="append">
|
|
166
|
-
<Icon
|
|
167
|
-
v-if="props.variant !== TabItemVariants.TEXT && props.appendIcon"
|
|
168
|
-
class="tab-item__append-icon"
|
|
169
|
-
:name="props.appendIcon"
|
|
170
|
-
:size="16"
|
|
171
|
-
@click.stop="handleIconClick"
|
|
172
|
-
/>
|
|
173
|
-
</slot>
|
|
174
|
-
</button>
|
|
175
|
-
</template>
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { Canvas, Meta, Story, Controls } from '@storybook/blocks';
|
|
2
|
-
import * as TabItemStories from './TabItem.stories';
|
|
3
|
-
|
|
4
|
-
<Meta of={TabItemStories} />
|
|
5
|
-
|
|
6
|
-
# TabItem
|
|
7
|
-
|
|
8
|
-
The TabItem component is a child component of the Tabs component. It is used to create a single tab within a set of tabs.
|
|
9
|
-
|
|
10
|
-
- [Overview](#overview)
|
|
11
|
-
|
|
12
|
-
- [Playground](#playground)
|
|
13
|
-
|
|
14
|
-
- [Usage with props](#usage)
|
|
15
|
-
|
|
16
|
-
- [Stories](#stories)
|
|
17
|
-
|
|
18
|
-
- [Tips](#tips)
|
|
19
|
-
|
|
20
|
-
## Overview <a id="overview" />
|
|
21
|
-
|
|
22
|
-
The TabItem component is responsible for displaying the content associated with a specific tab. It accepts a variety of props, including variant, id, label, disabled, and active, which can be used to customize the appearance and behavior of the tab.
|
|
23
|
-
|
|
24
|
-
💡 To use the TabItem component, it is first necessary to wrap it within a Tabs component. The TabItem component should then be passed a unique id prop, which is used to identify the tab and its associated content.
|
|
25
|
-
|
|
26
|
-
<Canvas>
|
|
27
|
-
<Story of={TabItemStories.Overview} />
|
|
28
|
-
</Canvas>
|
|
29
|
-
|
|
30
|
-
### Playground
|
|
31
|
-
|
|
32
|
-
> Changes you make in the controls will be reflected in the example above.
|
|
33
|
-
|
|
34
|
-
<Controls
|
|
35
|
-
of={TabItemStories.Overview}
|
|
36
|
-
exclude={/^(select|custom-icon|update.*)$/}
|
|
37
|
-
/>
|
|
38
|
-
|
|
39
|
-
## Usage with props <a id="usage" />
|
|
40
|
-
|
|
41
|
-
### variant (optional)
|
|
42
|
-
|
|
43
|
-
The **variant** props allows to change the style of the tab item.
|
|
44
|
-
|
|
45
|
-
### id (required)
|
|
46
|
-
|
|
47
|
-
The **id** props is a unique identifier for the tab.
|
|
48
|
-
|
|
49
|
-
### label (optional)
|
|
50
|
-
|
|
51
|
-
The **label** props is the text to be displayed on the tab.
|
|
52
|
-
|
|
53
|
-
### disabled (optional)
|
|
54
|
-
|
|
55
|
-
The **disabled** props indicates whether the tab should be disabled or not.
|
|
56
|
-
|
|
57
|
-
### active (optional)
|
|
58
|
-
|
|
59
|
-
The **active** props indicated whether the tab should be set as active or not.
|
|
60
|
-
|
|
61
|
-
## Stories <a id="stories" />
|
|
62
|
-
|
|
63
|
-
### Default
|
|
64
|
-
|
|
65
|
-
<Canvas>
|
|
66
|
-
<Story of={TabItemStories.Default} />
|
|
67
|
-
</Canvas>
|
|
68
|
-
|
|
69
|
-
### Icon Only
|
|
70
|
-
|
|
71
|
-
<Canvas>
|
|
72
|
-
<Story of={TabItemStories.Icon} />
|
|
73
|
-
</Canvas>
|
|
74
|
-
|
|
75
|
-
### Text Only
|
|
76
|
-
|
|
77
|
-
<Canvas>
|
|
78
|
-
<Story of={TabItemStories.Text} />
|
|
79
|
-
</Canvas>
|
|
80
|
-
|
|
81
|
-
### Tips <a id="tips" />
|
|
82
|
-
|
|
83
|
-
💡 Make sure to provide a unique id prop for each TabItem, as this is used to identify the tab and its associated content.
|
|
84
|
-
|
|
85
|
-
💡 Use the label prop to clearly label each tab, making it easy for users to understand the purpose of each tab.
|
|
86
|
-
|
|
87
|
-
💡 Use the active prop to set the default active tab when the component is first rendered.
|
|
88
|
-
|
|
89
|
-
💡 Use the disabled prop to disable tabs that are not currently in use or that the user should not have access to.
|
|
90
|
-
|
|
91
|
-
💡 The variant prop can be used to change the visual style of the tab.
|
|
92
|
-
|
|
93
|
-
💡 Use the onClick event to handle when the user clicks on a tab, if you want to perform some action in this event.
|
|
94
|
-
|
|
95
|
-
💡 Using the TabItem component within Tabs component will give you a better accessibility, by providing the necessary ARIA roles and attributes.
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { mount } from '@vue/test-utils';
|
|
4
|
-
|
|
5
|
-
import TabItem from './RTabItem.vue';
|
|
6
|
-
|
|
7
|
-
describe('TabItem', () => {
|
|
8
|
-
it('renders properly', () => {
|
|
9
|
-
const wrapper = mount(TabItem, {
|
|
10
|
-
props: {
|
|
11
|
-
id: 'tab-1',
|
|
12
|
-
label: 'Tab 1',
|
|
13
|
-
icon: 'face',
|
|
14
|
-
active: true,
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
expect(wrapper.exists()).toBe(true);
|
|
18
|
-
expect(wrapper.find('button').exists()).toBe(true);
|
|
19
|
-
expect(wrapper.find('button').html().includes('Tab 1'));
|
|
20
|
-
expect(
|
|
21
|
-
wrapper
|
|
22
|
-
.find('button')
|
|
23
|
-
.trigger('click')
|
|
24
|
-
.then(() => {
|
|
25
|
-
expect(wrapper.emitted('select')).toBeTruthy();
|
|
26
|
-
})
|
|
27
|
-
);
|
|
28
|
-
});
|
|
29
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
2
|
-
import TabItem from './RTabItem.vue';
|
|
3
|
-
|
|
4
|
-
const DefaultArgTypes = {
|
|
5
|
-
variant: {
|
|
6
|
-
type: 'select',
|
|
7
|
-
options: ['default', 'icon', 'text'],
|
|
8
|
-
},
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
const DefaultArgs = {
|
|
12
|
-
id: 'tab-1',
|
|
13
|
-
label: 'Tab 1',
|
|
14
|
-
prependIcon: 'mdiHome',
|
|
15
|
-
appendIcon: '',
|
|
16
|
-
disabled: false,
|
|
17
|
-
variant: 'default',
|
|
18
|
-
tile: false,
|
|
19
|
-
block: false,
|
|
20
|
-
modelValue: '',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const TabItemStory = {
|
|
24
|
-
title: 'Components/TabItem',
|
|
25
|
-
component: TabItem,
|
|
26
|
-
setup(args: typeof TabItem) {
|
|
27
|
-
return { args };
|
|
28
|
-
},
|
|
29
|
-
template: `
|
|
30
|
-
<TabItem v-bind="args"/>
|
|
31
|
-
`,
|
|
32
|
-
args: DefaultArgs,
|
|
33
|
-
argTypes: {
|
|
34
|
-
...DefaultArgTypes,
|
|
35
|
-
'onUpdate:modelValue': { action: 'update:modelValue' },
|
|
36
|
-
'onClick:icon': { action: 'onClick:icon' },
|
|
37
|
-
},
|
|
38
|
-
} as Meta<typeof TabItem>;
|
|
39
|
-
|
|
40
|
-
export default TabItemStory;
|
|
41
|
-
|
|
42
|
-
type Story = StoryObj<typeof TabItemStory>;
|
|
43
|
-
|
|
44
|
-
export const Overview: Story = {
|
|
45
|
-
args: {
|
|
46
|
-
variant: 'default',
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
export const Default: Story = {
|
|
51
|
-
args: {
|
|
52
|
-
variant: 'default',
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
export const Icon: Story = {
|
|
57
|
-
args: {
|
|
58
|
-
variant: 'icon',
|
|
59
|
-
},
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
export const Text: Story = {
|
|
63
|
-
args: {
|
|
64
|
-
variant: 'text',
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
export const Disabled: Story = {
|
|
69
|
-
args: {
|
|
70
|
-
disabled: true,
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export const Tile: Story = {
|
|
75
|
-
args: {
|
|
76
|
-
tile: true,
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const Block: Story = {
|
|
81
|
-
args: {
|
|
82
|
-
block: true,
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export const Active: Story = {
|
|
87
|
-
args: {
|
|
88
|
-
modelValue: 'tab-1',
|
|
89
|
-
},
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
export const TwoIcons: Story = {
|
|
93
|
-
args: {
|
|
94
|
-
prependIcon: 'mdiHome',
|
|
95
|
-
appendIcon: 'mdiPlusCircle',
|
|
96
|
-
},
|
|
97
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
@import '../../index.css';
|
|
2
|
-
|
|
3
|
-
.tab-item {
|
|
4
|
-
@apply transition-all gap-2 min-w-fit py-3 px-6 bg-transparent flex justify-center items-center text-[var(--neutral-500)] text-sm font-medium cursor-pointer;
|
|
5
|
-
|
|
6
|
-
&:disabled {
|
|
7
|
-
@apply cursor-not-allowed bg-inherit opacity-50;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
&[aria-selected='true'] {
|
|
11
|
-
@apply text-[var(--primary-500)] border-b-2 border-[var(--primary-500)];
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
&--text-only {
|
|
15
|
-
@apply block;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
&--tile {
|
|
19
|
-
@apply border-none py-2.5 px-7 text-[var(--neutral-900)];
|
|
20
|
-
|
|
21
|
-
&[aria-selected='true'] {
|
|
22
|
-
@apply bg-white rounded-md shadow-sm text-[var(--neutral-900)];
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
&--block {
|
|
27
|
-
@apply w-full;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, ref, watch } from 'vue';
|
|
3
|
-
import './tabs.css';
|
|
4
|
-
import type { Tab } from './types';
|
|
5
|
-
import TabItem from '../TabItem/RTabItem.vue';
|
|
6
|
-
import { emit } from 'process';
|
|
7
|
-
|
|
8
|
-
export interface IProps {
|
|
9
|
-
/**
|
|
10
|
-
* Tabs of the tabs
|
|
11
|
-
* @type Tab[]
|
|
12
|
-
* @default []
|
|
13
|
-
* @example
|
|
14
|
-
* <Tabs :tabs="[]" />
|
|
15
|
-
*/
|
|
16
|
-
tabs?: Tab[];
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Block state of the tabs
|
|
20
|
-
* @type boolean
|
|
21
|
-
* @default false
|
|
22
|
-
* @example
|
|
23
|
-
* <Tabs block />
|
|
24
|
-
*/
|
|
25
|
-
block?: boolean;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Active tab of the tabs
|
|
29
|
-
* @type number | string
|
|
30
|
-
* @default tabs[0].id
|
|
31
|
-
* @example
|
|
32
|
-
* <Tabs v-model="activeTab" />
|
|
33
|
-
*/
|
|
34
|
-
modelValue?: number | string;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Tile state of the tabs
|
|
38
|
-
* @type boolean
|
|
39
|
-
* @default false
|
|
40
|
-
* @example
|
|
41
|
-
* <Tabs tile />
|
|
42
|
-
*/
|
|
43
|
-
tile?: boolean;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const props = withDefaults(defineProps<IProps>(), {
|
|
47
|
-
tabs: () => [],
|
|
48
|
-
block: false,
|
|
49
|
-
modelValue: '',
|
|
50
|
-
tile: false,
|
|
51
|
-
});
|
|
52
|
-
const emits = defineEmits(['update:modelValue', 'click:icon']);
|
|
53
|
-
const activeTab = ref(props.modelValue || props.tabs[0].id);
|
|
54
|
-
|
|
55
|
-
const tabsClasses = computed(() => {
|
|
56
|
-
return {
|
|
57
|
-
tabs: true,
|
|
58
|
-
'tabs--block': props.block,
|
|
59
|
-
'tabs--tile': props.tile,
|
|
60
|
-
};
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
watch(
|
|
64
|
-
() => activeTab.value,
|
|
65
|
-
() => {
|
|
66
|
-
emits('update:modelValue', activeTab.value);
|
|
67
|
-
}
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
const handleIconClick = () => {
|
|
71
|
-
emits('click:icon');
|
|
72
|
-
};
|
|
73
|
-
</script>
|
|
74
|
-
<template>
|
|
75
|
-
<div :class="tabsClasses">
|
|
76
|
-
<slot>
|
|
77
|
-
<TabItem
|
|
78
|
-
v-for="(tab, index) in props.tabs"
|
|
79
|
-
:id="tab.id"
|
|
80
|
-
:key="index"
|
|
81
|
-
v-model="activeTab"
|
|
82
|
-
:active="index === activeTab"
|
|
83
|
-
:disabled="tab.disabled"
|
|
84
|
-
:prependIcon="tab.prependIcon"
|
|
85
|
-
:appendIcon="tab.appendIcon"
|
|
86
|
-
:label="tab.label"
|
|
87
|
-
:variant="tab.variant"
|
|
88
|
-
:tile="tile"
|
|
89
|
-
:block="block"
|
|
90
|
-
@click:icon="handleIconClick"
|
|
91
|
-
/>
|
|
92
|
-
</slot>
|
|
93
|
-
</div>
|
|
94
|
-
</template>
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { Canvas, Meta, Story, Controls } from '@storybook/blocks';
|
|
2
|
-
import * as TabsStories from './Tabs.stories';
|
|
3
|
-
|
|
4
|
-
<Meta of={TabsStories} />
|
|
5
|
-
|
|
6
|
-
# Tabs
|
|
7
|
-
|
|
8
|
-
Tabs are a user interface component that allows users to navigate through different sections of content. They are commonly used to organize and structure content in a clear and intuitive way.
|
|
9
|
-
|
|
10
|
-
- [Overview](#overview)
|
|
11
|
-
|
|
12
|
-
- [Playground](#playground)
|
|
13
|
-
|
|
14
|
-
- [Usage](#usage)
|
|
15
|
-
|
|
16
|
-
- [Stories](#stories)
|
|
17
|
-
|
|
18
|
-
- [Tips](#tips)
|
|
19
|
-
|
|
20
|
-
## Overview <a id="overview" />
|
|
21
|
-
|
|
22
|
-
Tabs are typically composed of a series of tab buttons, each of which corresponds to a different section of content. When a user clicks on one of the tab buttons, the corresponding content is displayed. Tabs can be designed in a variety of styles and configurations, but they all serve the same basic purpose: to help users navigate through different sections of content.
|
|
23
|
-
|
|
24
|
-
<Canvas>
|
|
25
|
-
<Story of={TabsStories.Overview} />
|
|
26
|
-
</Canvas>
|
|
27
|
-
|
|
28
|
-
### Playground <a id="playground" />
|
|
29
|
-
|
|
30
|
-
> Changes you make in the controls will be reflected in the example above.
|
|
31
|
-
|
|
32
|
-
<Controls of={TabsStories.Overview} exclude={/^(click|on.*)/} />
|
|
33
|
-
|
|
34
|
-
## Usage <a id="usage" />
|
|
35
|
-
|
|
36
|
-
To implement a Tabs component, you will need to define the tab buttons and their corresponding content sections. You can choose to include a scrollable prop which allows the user to scroll through the tabs if there are too many to fit on the screen. Additionally, you can choose to display the tabs with icon and text as a default, with icon only or text only.
|
|
37
|
-
|
|
38
|
-
## Stories <a id="stories" />
|
|
39
|
-
|
|
40
|
-
### Default
|
|
41
|
-
|
|
42
|
-
<Canvas>
|
|
43
|
-
<Story of={TabsStories.Default} />
|
|
44
|
-
</Canvas>
|
|
45
|
-
|
|
46
|
-
### Icon Only
|
|
47
|
-
|
|
48
|
-
<Canvas>
|
|
49
|
-
<Story of={TabsStories.Icon} />
|
|
50
|
-
</Canvas>
|
|
51
|
-
|
|
52
|
-
### Text Only
|
|
53
|
-
|
|
54
|
-
<Canvas>
|
|
55
|
-
<Story of={TabsStories.Text} />
|
|
56
|
-
</Canvas>
|
|
57
|
-
|
|
58
|
-
### Tile
|
|
59
|
-
|
|
60
|
-
<Canvas>
|
|
61
|
-
<Story of={TabsStories.Tile} />
|
|
62
|
-
</Canvas>
|
|
63
|
-
|
|
64
|
-
### Tips <a id="tips" />
|
|
65
|
-
|
|
66
|
-
💡 Too many tabs can make the interface confusing and overwhelming for users. Try to keep the number of tabs to a maximum of 5-7, and use sub-navigation or dropdown menus to organize additional content.
|
|
67
|
-
|
|
68
|
-
💡 The labels on the tab buttons should be short, descriptive, and easy to understand. Avoid using technical jargon or complex language.
|
|
69
|
-
|
|
70
|
-
💡 Icons can be a great way to add visual interest and make it easier for users to quickly identify different tabs. However, make sure that the icons are meaningful and add context to the tab's label.
|
|
71
|
-
|
|
72
|
-
💡 All tabs should have a consistent design to make it clear that they are related to each other. This includes the color, shape, size, and font of the tabs.
|
|
73
|
-
|
|
74
|
-
💡 Use horizontal tabs for primary navigation and vertical tabs for secondary navigation or when space is limited. Use bottom tabs for mobile navigation.
|
|
75
|
-
|
|
76
|
-
💡 Make it clear which tab is currently selected by using a different color, bold text, or an underline.
|
|
77
|
-
|
|
78
|
-
💡 Make sure that tabs are accessible to keyboard users and screen readers. This means providing clear labels, proper focus management, and ARIA attributes.
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import { mount } from '@vue/test-utils';
|
|
4
|
-
|
|
5
|
-
import Tabs from './RTabs.vue';
|
|
6
|
-
|
|
7
|
-
describe('Tabs', () => {
|
|
8
|
-
it('renders properly', () => {
|
|
9
|
-
const wrapper = mount(Tabs, {
|
|
10
|
-
props: {
|
|
11
|
-
tabs: [{ id: 0, label: 'Tab 1', icon: 'face' }],
|
|
12
|
-
scrollable: true,
|
|
13
|
-
},
|
|
14
|
-
});
|
|
15
|
-
expect(wrapper.exists()).toBe(true);
|
|
16
|
-
expect(wrapper.find('.tabs-wrapper').exists()).toBe(true);
|
|
17
|
-
expect(wrapper.find('.tab-item').element.innerHTML.includes('Tab 1'));
|
|
18
|
-
expect(wrapper.find('.tab-item').element.innerHTML.includes('face'));
|
|
19
|
-
expect(
|
|
20
|
-
wrapper
|
|
21
|
-
.find('.tab-item')
|
|
22
|
-
.trigger('click')
|
|
23
|
-
.then(() => {
|
|
24
|
-
expect(wrapper.emitted('select')).toBeTruthy();
|
|
25
|
-
})
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
});
|