@rocketui/vue 0.0.46 → 0.0.47

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.
Files changed (168) hide show
  1. package/.eslintrc.cjs +79 -0
  2. package/.gitattributes +2 -0
  3. package/.github/workflows/chromatic.yml +28 -0
  4. package/.github/workflows/publish-storybook.yml +41 -0
  5. package/.husky/pre-commit +4 -0
  6. package/.prettierrc.cjs +10 -0
  7. package/.storybook/Theme.js +17 -0
  8. package/.storybook/main.ts +20 -0
  9. package/.storybook/manager-head.html +3 -0
  10. package/.storybook/manager.js +8 -0
  11. package/.storybook/preview-head.html +3 -0
  12. package/.storybook/preview.ts +36 -0
  13. package/.storybook/source-panel/manager.js +28 -0
  14. package/.storybook/withSource.js +91 -0
  15. package/.vscode/extensions.json +11 -0
  16. package/.vscode/settings.json +20 -0
  17. package/index.html +13 -0
  18. package/lib/main.ts +48 -0
  19. package/package.json +2 -8
  20. package/postcss.config.cjs +9 -0
  21. package/resources/rocket-ui-logo-dark.svg +27 -0
  22. package/resources/rocket-ui-logo-light.svg +27 -0
  23. package/shims-rocketui.d.ts +9 -0
  24. package/src/App.vue +15 -0
  25. package/src/assets/blank-avatar.svg +3 -0
  26. package/src/assets/icons/mdi.js +7302 -0
  27. package/src/assets/logo.svg +1 -0
  28. package/src/components/Accordion/Accordion.mdx +88 -0
  29. package/src/components/Accordion/Accordion.stories.ts +257 -0
  30. package/src/components/Accordion/RAccordion.vue +73 -0
  31. package/src/components/Accordion/accordion.css +75 -0
  32. package/src/components/Accordion/accordion.spec.ts +123 -0
  33. package/src/components/Alert/Alert.mdx +120 -0
  34. package/src/components/Alert/Alert.stories.ts +118 -0
  35. package/src/components/Alert/RAlert.vue +119 -0
  36. package/src/components/Alert/alert.css +136 -0
  37. package/src/components/Alert/alert.spec.ts +32 -0
  38. package/src/components/Avatar/Avatar.mdx +96 -0
  39. package/src/components/Avatar/Avatar.stories.ts +65 -0
  40. package/src/components/Avatar/RAvatar.vue +115 -0
  41. package/src/components/Avatar/avatar.css +82 -0
  42. package/src/components/Avatar/avatar.spec.ts +38 -0
  43. package/src/components/Badge/Badge.mdx +112 -0
  44. package/src/components/Badge/Badge.stories.ts +99 -0
  45. package/src/components/Badge/RBadge.vue +89 -0
  46. package/src/components/Badge/badge.css +63 -0
  47. package/src/components/Badge/badge.spec.ts +20 -0
  48. package/src/components/Box/Box.mdx +20 -0
  49. package/src/components/Box/Box.stories.ts +56 -0
  50. package/src/components/Box/RBox.vue +97 -0
  51. package/src/components/Breadcrumb/Breadcrumb.stories.ts +115 -0
  52. package/src/components/Breadcrumb/RBreadcrumb.vue +43 -0
  53. package/src/components/Breadcrumb/breadcrumb.css +29 -0
  54. package/src/components/Button/Button.mdx +148 -0
  55. package/src/components/Button/Button.spec.ts +29 -0
  56. package/src/components/Button/Button.stories.ts +118 -0
  57. package/src/components/Button/RButton.vue +179 -0
  58. package/src/components/Button/button.css +146 -0
  59. package/src/components/Checkbox/Checkbox.mdx +100 -0
  60. package/src/components/Checkbox/Checkbox.stories.ts +67 -0
  61. package/src/components/Checkbox/RCheckbox.vue +195 -0
  62. package/src/components/Checkbox/checkbox.css +67 -0
  63. package/src/components/Checkbox/checkbox.spec.ts +60 -0
  64. package/src/components/Chips/Chip.mdx +113 -0
  65. package/src/components/Chips/Chip.stories.ts +122 -0
  66. package/src/components/Chips/RChip.vue +125 -0
  67. package/src/components/Chips/chip.css +62 -0
  68. package/src/components/Chips/chip.spec.ts +40 -0
  69. package/src/components/Dropdown/Dropdown.mdx +135 -0
  70. package/src/components/Dropdown/Dropdown.stories.ts +84 -0
  71. package/src/components/Dropdown/RDropdown.vue +392 -0
  72. package/src/components/Dropdown/dropdown.css +113 -0
  73. package/src/components/Dropdown/dropdown.spec.ts +98 -0
  74. package/src/components/Flex/Flex.mdx +20 -0
  75. package/src/components/Flex/Flex.stories.js +127 -0
  76. package/src/components/Flex/RFlex.vue +91 -0
  77. package/src/components/Grid/Grid.mdx +20 -0
  78. package/src/components/Grid/Grid.stories.js +107 -0
  79. package/src/components/Grid/RGrid.vue +138 -0
  80. package/src/components/Icon/Icon.mdx +68 -0
  81. package/src/components/Icon/Icon.stories.ts +33 -0
  82. package/src/components/Icon/RIcon.vue +56 -0
  83. package/src/components/Icon/icon.spec.ts +25 -0
  84. package/src/components/ItemGroup/ItemGroup.stories.ts +91 -0
  85. package/src/components/ItemGroup/RItem.vue +74 -0
  86. package/src/components/ItemGroup/RItemGroup.vue +122 -0
  87. package/src/components/ItemGroup/__snapshots__/itemgroup.spec.ts.snap +13 -0
  88. package/src/components/ItemGroup/itemgroup.spec.ts +67 -0
  89. package/src/components/Label/Label.mdx +50 -0
  90. package/src/components/Label/Label.stories.ts +38 -0
  91. package/src/components/Label/RLabel.vue +42 -0
  92. package/src/components/Label/label.css +0 -0
  93. package/src/components/Modal/Modal.mdx +91 -0
  94. package/src/components/Modal/Modal.stories.ts +125 -0
  95. package/src/components/Modal/RModal.vue +130 -0
  96. package/src/components/Modal/modal.css +41 -0
  97. package/src/components/Modal/modal.spec.ts +25 -0
  98. package/src/components/Pagination/Pagination.stories.ts +24 -0
  99. package/src/components/Pagination/RPagination.vue +103 -0
  100. package/src/components/Pagination/pagination.css +47 -0
  101. package/src/components/Pagination/pagination.spec.ts +17 -0
  102. package/src/components/ProgressBar/ProgressBar.stories.ts +34 -0
  103. package/src/components/ProgressBar/RProgressBar.vue +21 -0
  104. package/src/components/ProgressBar/progressbar.css +24 -0
  105. package/src/components/ProgressBar/progressbar.spec.ts +17 -0
  106. package/src/components/Shared/Enums.ts +1 -0
  107. package/src/components/Sidebar/RSidebar.vue +27 -0
  108. package/src/components/Sidebar/Sidebar.mdx +31 -0
  109. package/src/components/Sidebar/Sidebar.stories.ts +34 -0
  110. package/src/components/Sidebar/sidebar.css +18 -0
  111. package/src/components/Sidebar/sidebar.spec.ts +33 -0
  112. package/src/components/Snackbar/RSnackbar.vue +136 -0
  113. package/src/components/Snackbar/Snackbar.mdx +126 -0
  114. package/src/components/Snackbar/Snackbar.stories.ts +93 -0
  115. package/src/components/Snackbar/snackbar.css +99 -0
  116. package/src/components/Snackbar/snackbar.spec.ts +56 -0
  117. package/src/components/Switch/RSwitch.vue +147 -0
  118. package/src/components/Switch/Switch.mdx +102 -0
  119. package/src/components/Switch/Switch.stories.ts +79 -0
  120. package/src/components/Switch/switch.css +102 -0
  121. package/src/components/Switch/switch.spec.ts +31 -0
  122. package/src/components/TabItem/RTabItem.vue +175 -0
  123. package/src/components/TabItem/TabItem.mdx +95 -0
  124. package/src/components/TabItem/TabItem.spec.ts +29 -0
  125. package/src/components/TabItem/TabItem.stories.ts +97 -0
  126. package/src/components/TabItem/common.ts +6 -0
  127. package/src/components/TabItem/tab-item.css +29 -0
  128. package/src/components/Tabs/RTabs.vue +94 -0
  129. package/src/components/Tabs/Tabs.mdx +78 -0
  130. package/src/components/Tabs/Tabs.spec.ts +28 -0
  131. package/src/components/Tabs/Tabs.stories.ts +191 -0
  132. package/src/components/Tabs/tabs.css +13 -0
  133. package/src/components/Tabs/types.ts +11 -0
  134. package/src/components/TextArea/RTextArea.vue +142 -0
  135. package/src/components/TextArea/TextArea.mdx +108 -0
  136. package/src/components/TextArea/TextArea.stories.ts +55 -0
  137. package/src/components/TextArea/textarea.css +51 -0
  138. package/src/components/TextArea/textarea.spec.ts +36 -0
  139. package/src/components/Textfield/RTextfield.vue +372 -0
  140. package/src/components/Textfield/Textfield.mdx +159 -0
  141. package/src/components/Textfield/Textfield.stories.ts +121 -0
  142. package/src/components/Textfield/textfield.css +81 -0
  143. package/src/components/Textfield/textfield.spec.ts +34 -0
  144. package/src/components/Tooltip/RTooltip.vue +325 -0
  145. package/src/components/Tooltip/Tooltip.mdx +111 -0
  146. package/src/components/Tooltip/Tooltip.stories.ts +203 -0
  147. package/src/components/Tooltip/common.ts +91 -0
  148. package/src/components/Tooltip/tooltip.css +34 -0
  149. package/src/components/Tooltip/tooltip.spec.ts +81 -0
  150. package/src/components/Typography/Typography.mdx +109 -0
  151. package/src/components/Typography/typography.css +128 -0
  152. package/src/directives/index.ts +19 -0
  153. package/src/index.css +241 -0
  154. package/src/main.ts +5 -0
  155. package/src/scripts/buildIcons.js +21 -0
  156. package/src/stories/Colors.mdx +355 -0
  157. package/src/stories/GettingStarted.mdx +121 -0
  158. package/src/stories/Layout.mdx +15 -0
  159. package/tailwind.config.cjs +16 -0
  160. package/tsconfig.json +24 -0
  161. package/vite.config.ts +39 -0
  162. package/vitest.config.ts +12 -0
  163. package/dist/rocket-ui-vue.js +0 -9381
  164. package/dist/rocket-ui-vue.umd.cjs +0 -1
  165. package/dist/style.css +0 -2
  166. package/dist/types/main.d.ts +0 -25
  167. /package/{dist → public}/design-tokens.source.json +0 -0
  168. /package/{dist → public}/favicon.ico +0 -0
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69" xmlns:v="https://vecta.io/nano"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
@@ -0,0 +1,88 @@
1
+ import { Canvas, Meta, Story, Controls } from '@storybook/blocks';
2
+ import * as AccordionStories from './Accordion.stories';
3
+
4
+ <Meta of={AccordionStories} />
5
+
6
+ # Accordion
7
+
8
+ The Accordion component is a UI element that allows the user to show and hide content within an expandable and collapsible section. It consists of a container that holds multiple panels, where each panel has a header and a body. When a panel's header is clicked, the corresponding body is shown or hidden.
9
+
10
+ - [Overview](#overview)
11
+
12
+ - [Playground](#playground)
13
+
14
+ - [Usage with props](#usage)
15
+
16
+ - [Stories](#stories)
17
+
18
+ - [Customizable Slots](#customizable-slots)
19
+
20
+ - [Tips](#tips)
21
+
22
+ ## Overview <a id="overview" />
23
+
24
+ The Accordion component provides a compact way of displaying large amounts of information in a small space. It is particularly useful for displaying hierarchical data, where each panel represents a different level of information. The Accordion component is also a good way to present frequently asked questions (FAQs) as it makes it easy for users to find the information they are looking for.
25
+
26
+ <Canvas>
27
+ <Story of={AccordionStories.Overview} />
28
+ </Canvas>
29
+
30
+ ## Playground <a id="playground" />
31
+
32
+ > Changes you make in the controls will be reflected in the example above. Try it yourself!
33
+
34
+ <Controls of={AccordionStories.Overview} exclude={/^(default|update.*)$/} />
35
+
36
+ ## Usage with props <a id="usage" />
37
+
38
+ ### accordions (required)
39
+
40
+ The **accordions** prop is an array that holds the data for each panel in the accordion component. Each panel is an object with properties such as header and body.
41
+
42
+ ### modelValue (optional)
43
+
44
+ The **modelValue** prop is a boolean that determines whether the accordion component is in an expanded or collapsed state. A value of true indicates that the accordion component is expanded, and a value of false indicates that it is collapsed.
45
+
46
+ ### accordions: title (required)
47
+
48
+ The **title** prop is a string that is used as the header for each panel in the accordion component.
49
+
50
+ ### accordions: content (required)
51
+
52
+ The **content** prop is a string that is used as the body for each panel in the accordion component.
53
+
54
+ ### accordions: open (optional)
55
+
56
+ The **open** prop is a boolean that determines whether the panel is in an expanded or collapsed state. A value of true indicates that the panel is expanded, and a value of false indicates that it is collapsed.
57
+
58
+ ### accordions: disabled (optional)
59
+
60
+ The **disabled** prop is a boolean that determines whether the panel is disabled. A value of true indicates that the panel is disabled, and a value of false indicates that it is enabled.
61
+
62
+ ## Stories <a id="stories" />
63
+
64
+ ### Single Collapse
65
+
66
+ <Canvas>
67
+ <Story of={AccordionStories.SingleCollapse} />
68
+ </Canvas>
69
+
70
+ ### Accordion
71
+
72
+ <Canvas>
73
+ <Story of={AccordionStories.Accordion1} />
74
+ </Canvas>
75
+
76
+ ## Customizable Slots <a id="customizable-slots" />
77
+
78
+ ### Tips <a id="tips" />
79
+
80
+ 💡 Use clear and concise headings for each panel's header to help users quickly understand the content within each panel.
81
+
82
+ 💡 Consider using icons or graphics within the header to make the accordion more visually appealing.
83
+
84
+ 💡 Make sure that the accordion is accessible to users who may be using assistive technologies, such as screen readers.
85
+
86
+ 💡 Use the modelValue prop wisely to control the default state of the accordion. For example, you might want to set the modelValue prop to true for the panel that contains the most important information.
87
+
88
+ 💡 Try to limit the amount of content within each panel to ensure that the accordion remains compact and easy to use.
@@ -0,0 +1,257 @@
1
+ import type { Meta, StoryObj } from '@storybook/vue3';
2
+ import Accordion from './RAccordion.vue';
3
+
4
+ const DefaultArgs = {
5
+ accordions: [
6
+ {
7
+ title: 'Accordion 1',
8
+ content: 'Accordion 1 content',
9
+ },
10
+ ],
11
+ };
12
+
13
+ const AccordionStory = {
14
+ title: 'Components/Accordion',
15
+ component: Accordion,
16
+ setup: (args: typeof Accordion) => {
17
+ return { args };
18
+ },
19
+ template: `<Accordion v-bind="args" @update="update"/>`,
20
+ args: DefaultArgs,
21
+ } as Meta<typeof Accordion>;
22
+
23
+ export default AccordionStory;
24
+
25
+ type Story = StoryObj<typeof AccordionStory>;
26
+
27
+ export const Overview: Story = {
28
+ args: {
29
+ accordions: [
30
+ {
31
+ title: 'Accordion 1',
32
+ content: 'Accordion 1 content',
33
+ },
34
+ ],
35
+ },
36
+ };
37
+
38
+ export const SingleCollapse: Story = {
39
+ args: {
40
+ accordions: [
41
+ {
42
+ title: 'Accordion 1',
43
+ content: 'Accordion 1 content',
44
+ },
45
+ ],
46
+ },
47
+ };
48
+
49
+ export const Accordion1: Story = {
50
+ args: {
51
+ accordions: [
52
+ {
53
+ title: 'Accordion 1',
54
+ content: 'Accordion 1 content',
55
+ open: true,
56
+ },
57
+ {
58
+ title: 'Accordion 2',
59
+ content: `Lorem ipsum dolor sit amet, consectetur adipiscing elit.
60
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
61
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
62
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
63
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
64
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
65
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
66
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
67
+ ut tristique massa nisl nec elit.
68
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
69
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
70
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
71
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
72
+ facilisi.
73
+
74
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
75
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
76
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio`,
77
+ },
78
+ {
79
+ title: 'Lorem ipsum',
80
+ content: `
81
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
82
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
83
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
84
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
85
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
86
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
87
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
88
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
89
+ ut tristique massa nisl nec elit.
90
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
91
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
92
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
93
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
94
+ facilisi.
95
+
96
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
97
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
98
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
99
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
100
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
101
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
102
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
103
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
104
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
105
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
106
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
107
+ ut tristique massa nisl nec elit.
108
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
109
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
110
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
111
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
112
+ facilisi.
113
+
114
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
115
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
116
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
117
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
118
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
119
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
120
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
121
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
122
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
123
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
124
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
125
+ ut tristique massa nisl nec elit.
126
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
127
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
128
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
129
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
130
+ facilisi.
131
+
132
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
133
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
134
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
135
+ `,
136
+ },
137
+ {
138
+ title: 'Lorem ipsum over 600px',
139
+ content: `
140
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
141
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
142
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
143
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
144
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
145
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
146
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
147
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
148
+ ut tristique massa nisl nec elit.
149
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
150
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
151
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
152
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
153
+ facilisi.
154
+
155
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
156
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
157
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
158
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
159
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
160
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
161
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
162
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
163
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
164
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
165
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
166
+ ut tristique massa nisl nec elit.
167
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
168
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
169
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
170
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
171
+ facilisi.
172
+
173
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
174
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
175
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
176
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
177
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
178
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
179
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
180
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
181
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
182
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
183
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
184
+ ut tristique massa nisl nec elit.
185
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
186
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
187
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
188
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
189
+ facilisi.
190
+
191
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
192
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
193
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
194
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
195
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
196
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
197
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
198
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
199
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
200
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
201
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
202
+ ut tristique massa nisl nec elit.
203
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
204
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
205
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
206
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
207
+ facilisi.
208
+
209
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
210
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
211
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
212
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
213
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
214
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
215
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
216
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
217
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
218
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
219
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
220
+ ut tristique massa nisl nec elit.
221
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
222
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
223
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
224
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
225
+ facilisi.
226
+
227
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
228
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
229
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
230
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
231
+ Nulla nec purus feugiat, molestie ipsum et, consequat nibh.
232
+ Etiam non elit dui. Nullam vel eros sit amet arcu vestibulum accumsan in in leo.
233
+ Fusce euismod magna et sapien varius, ut ultricies enim scelerisque.
234
+ Fusce ultrices euismod lobortis. Nullam faucibus aliquet feugiat.
235
+ Curabitur ut augue finibus, luctus tortor at, ornare erat.
236
+ Donec auctor ipsum ut tellus ultrices, vel tincidunt ipsum posuere.
237
+ Nullam euismod, lorem vitae aliquam facilisis, elit nunc aliquet nunc,
238
+ ut tristique massa nisl nec elit.
239
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
240
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
241
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
242
+ aliquam mauris, quis ultrices nisl velit quis nunc. Nulla facilisi. Nulla
243
+ facilisi.
244
+
245
+ Donec euismod, mauris ut ultricies ultrices, nunc ipsum aliquam libero,
246
+ vitae venenatis eros eros vel arcu. Donec ut porta libero. Sed ut erat ut
247
+ nunc fermentum aliquam. Donec auctor, eros eget ultrices mollis, ipsum odio
248
+ `,
249
+ },
250
+ {
251
+ title: 'Accordion 4',
252
+ content: 'Accordion 4 content',
253
+ disabled: true,
254
+ },
255
+ ],
256
+ },
257
+ };
@@ -0,0 +1,73 @@
1
+ <script setup lang="ts">
2
+ import { reactive } from 'vue';
3
+ import Icon from '../Icon/RIcon.vue';
4
+ import './accordion.css';
5
+
6
+ export type Accordion = {
7
+ title: string;
8
+ content: string;
9
+ open?: boolean;
10
+ disabled?: boolean;
11
+ };
12
+
13
+ export interface AccordionProps {
14
+ /**
15
+ * Accordion list
16
+ * @default []
17
+ * @type Accordion[]
18
+ * @example
19
+ * ```html
20
+ * <r-accordion :accordions="[
21
+ * { title: 'Accordion 1', content: 'Content 1' },
22
+ * ]" />
23
+ * ```
24
+ */
25
+ accordions: Accordion[];
26
+ }
27
+
28
+ const props = defineProps<AccordionProps>();
29
+
30
+ const accordions = reactive(
31
+ props.accordions.map(({ title, content }, index) => ({
32
+ title,
33
+ content,
34
+ open: props.accordions[index].open || false,
35
+ disabled: props.accordions[index].disabled || false,
36
+ }))
37
+ );
38
+
39
+ function handleAccordion(selectedIndex: number) {
40
+ if (accordions[selectedIndex].disabled) return;
41
+ accordions.forEach((_, index) => {
42
+ accordions[index].open =
43
+ index === selectedIndex ? !accordions[index].open : false;
44
+ });
45
+ }
46
+ </script>
47
+ <template>
48
+ <div
49
+ v-for="(accordion, index) in accordions"
50
+ :key="index"
51
+ :class="{
52
+ 'r-accordion': true,
53
+ 'r-accordion--disabled': accordion.disabled,
54
+ }"
55
+ :data-state="accordion.open ? 'opened' : 'closed'"
56
+ >
57
+ <div class="r-accordion__header" @click="handleAccordion(index)">
58
+ <slot name="title">
59
+ <div class="r-accordion__title">{{ accordion.title }}</div>
60
+ </slot>
61
+ <div class="r-accordion__icon">
62
+ <Icon name="mdiChevronUp" />
63
+ </div>
64
+ </div>
65
+ <div class="r-accordion__content">
66
+ <slot name="content">
67
+ <span>
68
+ {{ accordion.content }}
69
+ </span>
70
+ </slot>
71
+ </div>
72
+ </div>
73
+ </template>
@@ -0,0 +1,75 @@
1
+ @import '../../index.css';
2
+
3
+ .r-accordion {
4
+ @apply rounded-lg px-4 py-3 border-[var(--neutral-200)] border mb-6;
5
+
6
+ &:hover:not(&--disabled) {
7
+ @apply border-[var(--primary-500)];
8
+ }
9
+
10
+ &--disabled {
11
+ @apply cursor-not-allowed bg-[var(--neutral-100)];
12
+ }
13
+
14
+ &--disabled &__header {
15
+ @apply cursor-not-allowed;
16
+
17
+ & .accordion__title {
18
+ @apply text-[var(--neutral-500)];
19
+ }
20
+
21
+ & .accordion__icon {
22
+ @apply text-[var(--neutral-500)];
23
+ }
24
+ }
25
+
26
+ &__header {
27
+ @apply flex items-center justify-between cursor-pointer;
28
+ }
29
+
30
+ &__title {
31
+ @apply text-[var(--neutral-900)] font-medium text-sm;
32
+ }
33
+
34
+ &__icon {
35
+ @apply text-[var(--neutral-900)] grid items-center;
36
+ }
37
+
38
+ &__content {
39
+ @apply max-h-0 overflow-y-auto text-[var(--neutral-500)] font-normal text-sm transition-all;
40
+ }
41
+
42
+ &[data-state='opened'] {
43
+ @apply border-[var(--primary-500)] ring-inset ring-2 ring-[var(--primary-200)];
44
+ }
45
+
46
+ &[data-state='opened'] &__icon {
47
+ @apply transform rotate-180 text-[var(--primary-500)];
48
+ }
49
+
50
+ &[data-state='opened'] &__content {
51
+ @apply max-h-[var(--accordion-content-max-height)] mt-3 animate-[slideDown] duration-300;
52
+ }
53
+
54
+ &[data-state='closed'] &__content {
55
+ @apply max-h-0 mt-0 animate-[slideUp] duration-300 overflow-hidden;
56
+ }
57
+ }
58
+
59
+ @keyframes slideDown {
60
+ from {
61
+ height: 0;
62
+ }
63
+ to {
64
+ height: var(--accordion-content-max-height);
65
+ }
66
+ }
67
+
68
+ @keyframes slideUp {
69
+ from {
70
+ height: var(--accordion-content-max-height);
71
+ }
72
+ to {
73
+ height: 0;
74
+ }
75
+ }
@@ -0,0 +1,123 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { mount } from '@vue/test-utils';
3
+ import Accordion from './RAccordion.vue';
4
+
5
+ describe('Accordion', () => {
6
+ it('should render correctly', () => {
7
+ const wrapper = mount(Accordion, {
8
+ props: {
9
+ accordions: [
10
+ {
11
+ title: 'Accordion Title',
12
+ content: 'Accordion Description',
13
+ },
14
+ ],
15
+ },
16
+ });
17
+
18
+ expect(wrapper.exists()).toBe(true);
19
+ expect(wrapper.find('.accordion__title').text()).toBe('Accordion Title');
20
+ expect(wrapper.find('.accordion__content').text()).toBe(
21
+ 'Accordion Description'
22
+ );
23
+ expect(
24
+ wrapper
25
+ .find('.accordion__header')
26
+ .trigger('click')
27
+ .then(() => {
28
+ expect(wrapper.emitted('update:modelValue')).toBeTruthy();
29
+ })
30
+ );
31
+ });
32
+
33
+ it('should render correctly with multiple accordions', () => {
34
+ const wrapper = mount(Accordion, {
35
+ props: {
36
+ accordions: [
37
+ {
38
+ title: 'Accordion Title 1',
39
+ content: 'Accordion Description 1',
40
+ },
41
+ {
42
+ title: 'Accordion Title 2',
43
+ content: 'Accordion Description 2',
44
+ },
45
+ ],
46
+ },
47
+ });
48
+
49
+ expect(wrapper.exists()).toBe(true);
50
+ expect(wrapper.findAll('.accordion__title').length).toBe(2);
51
+ expect(wrapper.findAll('.accordion__content').length).toBe(2);
52
+ expect(wrapper.findAll('.accordion__title')[0].text()).toBe(
53
+ 'Accordion Title 1'
54
+ );
55
+ expect(wrapper.findAll('.accordion__content')[0].text()).toBe(
56
+ 'Accordion Description 1'
57
+ );
58
+ expect(wrapper.findAll('.accordion__title')[1].text()).toBe(
59
+ 'Accordion Title 2'
60
+ );
61
+ expect(wrapper.findAll('.accordion__content')[1].text()).toBe(
62
+ 'Accordion Description 2'
63
+ );
64
+ });
65
+
66
+ it('should render correctly with multiple accordions and one expanded', () => {
67
+ const wrapper = mount(Accordion, {
68
+ props: {
69
+ accordions: [
70
+ {
71
+ title: 'Accordion Title 1',
72
+ content: 'Accordion Description 1',
73
+ isExpanded: true,
74
+ },
75
+ {
76
+ title: 'Accordion Title 2',
77
+ content: 'Accordion Description 2',
78
+ },
79
+ ],
80
+ },
81
+ });
82
+
83
+ expect(wrapper.exists()).toBe(true);
84
+ expect(wrapper.findAll('.accordion__title').length).toBe(2);
85
+ expect(wrapper.findAll('.accordion__content').length).toBe(2);
86
+
87
+ expect(wrapper.findAll('.accordion')[0].classes()).toContain(
88
+ 'accordion--expanded'
89
+ );
90
+ expect(wrapper.findAll('.accordion')[1].classes()).not.toContain(
91
+ 'accordion--expanded'
92
+ );
93
+ });
94
+
95
+ it('should render correctly with multiple accordions and one expanded and one disabled', () => {
96
+ const wrapper = mount(Accordion, {
97
+ props: {
98
+ accordions: [
99
+ {
100
+ title: 'Accordion Title 1',
101
+ content: 'Accordion Description 1',
102
+ isExpanded: true,
103
+ },
104
+ {
105
+ title: 'Accordion Title 2',
106
+ content: 'Accordion Description 2',
107
+ isDisabled: true,
108
+ },
109
+ ],
110
+ },
111
+ });
112
+
113
+ expect(wrapper.exists()).toBe(true);
114
+ expect(wrapper.findAll('.accordion__title').length).toBe(2);
115
+ expect(wrapper.findAll('.accordion__content').length).toBe(2);
116
+ expect(wrapper.findAll('.accordion')[0].classes()).toContain(
117
+ 'accordion--expanded'
118
+ );
119
+ expect(wrapper.findAll('.accordion')[1].classes()).toContain(
120
+ 'accordion--disabled'
121
+ );
122
+ });
123
+ });