Playground.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <!-- Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/ -->
  2. <!-- eslint-disable zammad/zammad-detect-translatable-string -->
  3. <script setup lang="ts">
  4. import { computed, onMounted, ref, watch } from 'vue'
  5. import { reset } from '@formkit/core'
  6. import CommonAlert from '#shared/components/CommonAlert/CommonAlert.vue'
  7. import Form from '#shared/components/Form/Form.vue'
  8. import type { FormValues } from '#shared/components/Form/types.ts'
  9. import CommonButton from '#desktop/components/CommonButton/CommonButton.vue'
  10. import CommonButtonGroup from '#desktop/components/CommonButtonGroup/CommonButtonGroup.vue'
  11. import CommonProgressBar from '#desktop/components/CommonProgressBar/CommonProgressBar.vue'
  12. import type { CommonButtonItem } from '#desktop/components/CommonButtonGroup/types.ts'
  13. const alphabetOptions = computed(() =>
  14. [...Array(26).keys()].map((i) => ({
  15. value: i,
  16. label: `Item ${String.fromCharCode(65 + i)}`,
  17. disabled: Math.random() < 0.5,
  18. })),
  19. )
  20. const longOption = ref({
  21. value: 999,
  22. label:
  23. 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, nullam pulvinar nunc sapien, vitae malesuada justo interdum feugiat, mauris odio, mattis et malesuada quis, vulputate vitae enim',
  24. })
  25. const treeselectOptions = [
  26. {
  27. value: 0,
  28. label: 'Item A',
  29. children: [
  30. {
  31. value: 1,
  32. label: 'Item 1',
  33. children: [
  34. {
  35. value: 2,
  36. label: 'Item I',
  37. },
  38. {
  39. value: 3,
  40. label: 'Item II',
  41. },
  42. {
  43. value: 4,
  44. label: 'Item III',
  45. },
  46. ],
  47. },
  48. {
  49. value: 5,
  50. label: 'Item 2',
  51. children: [
  52. ...[longOption.value],
  53. {
  54. value: 6,
  55. label: 'Item IV',
  56. },
  57. ],
  58. },
  59. {
  60. value: 7,
  61. label: 'Item 3',
  62. },
  63. ],
  64. },
  65. {
  66. value: 8,
  67. label: 'Item B',
  68. },
  69. {
  70. value: 9,
  71. label: 'Ítem C',
  72. },
  73. ]
  74. const buttonGroupOptions: CommonButtonItem[] = [
  75. {
  76. label: 'Button 1',
  77. variant: 'primary',
  78. icon: 'logo-flat',
  79. onActionClick: () => console.debug('Button 1 clicked'),
  80. },
  81. {
  82. label: 'Button 2',
  83. variant: 'secondary',
  84. },
  85. {
  86. label: 'Button 3',
  87. variant: 'tertiary',
  88. },
  89. {
  90. label: 'Button 4',
  91. variant: 'submit',
  92. },
  93. {
  94. label: 'Button 5',
  95. variant: 'danger',
  96. },
  97. ]
  98. const formSchema = [
  99. {
  100. isLayout: true,
  101. element: 'div',
  102. attrs: {
  103. class: 'grid md:grid-cols-2 gap-y-2.5 gap-x-3',
  104. },
  105. children: [
  106. {
  107. name: 'select_0',
  108. label: 'Column select',
  109. type: 'select',
  110. outerClass: 'col-span-1',
  111. props: {
  112. maxLength: 150,
  113. options: [...alphabetOptions.value, ...[longOption.value]],
  114. clearable: true,
  115. },
  116. },
  117. {
  118. name: 'toggle_1',
  119. label: 'Column toggle',
  120. type: 'toggle',
  121. outerClass: 'col-span-1',
  122. wrapperClass: 'md:mt-6',
  123. props: {
  124. variants: {
  125. true: 'yes',
  126. false: 'no',
  127. },
  128. },
  129. },
  130. {
  131. name: 'toggle_2',
  132. label: 'Row toggle',
  133. type: 'toggle',
  134. props: {
  135. variants: {
  136. true: 'yes',
  137. false: 'no',
  138. },
  139. },
  140. },
  141. ],
  142. },
  143. {
  144. name: 'group_permission_0',
  145. label: 'Group permissions',
  146. type: 'groupPermissions',
  147. props: {
  148. options: [
  149. {
  150. value: 1,
  151. label: 'Users',
  152. },
  153. {
  154. value: 2,
  155. label: 'some_group1',
  156. children: [
  157. {
  158. value: 3,
  159. label: 'Nested group',
  160. },
  161. ],
  162. },
  163. ],
  164. },
  165. },
  166. {
  167. type: 'select',
  168. name: 'select_1',
  169. label: 'Single select',
  170. clearable: true,
  171. props: {
  172. options: [...alphabetOptions.value, ...[longOption.value]],
  173. link: '/',
  174. linkIcon: 'person-add',
  175. },
  176. },
  177. {
  178. type: 'select',
  179. name: 'select_2',
  180. label: 'Multi select',
  181. clearable: true,
  182. props: {
  183. multiple: true,
  184. options: [...alphabetOptions.value, ...[longOption.value]],
  185. },
  186. },
  187. {
  188. type: 'treeselect',
  189. name: 'treeselect_1',
  190. label: 'Single treeselect',
  191. clearable: true,
  192. props: {
  193. options: treeselectOptions,
  194. },
  195. },
  196. {
  197. type: 'treeselect',
  198. name: 'treeselect_2',
  199. label: 'Multi treeselect',
  200. clearable: true,
  201. props: {
  202. multiple: true,
  203. options: treeselectOptions,
  204. },
  205. },
  206. {
  207. type: 'toggleList',
  208. name: 'roles',
  209. label: 'Roles',
  210. props: {
  211. options: [
  212. { value: 3, label: 'name only' },
  213. { value: 1, label: 'Long name', description: 'Note here' },
  214. {
  215. value: 1111,
  216. label: 'Another long name',
  217. description: 'Note here again',
  218. },
  219. ],
  220. },
  221. },
  222. ]
  223. const formInitialValues: FormValues = { roles: [3, 1] }
  224. const progressBarValue = ref(0)
  225. const increaseProgressBar = () => {
  226. progressBarValue.value += 25
  227. }
  228. onMounted(() => {
  229. setInterval(increaseProgressBar, 2000)
  230. })
  231. watch(progressBarValue, (newValue) => {
  232. if (newValue < 100) return
  233. setTimeout(() => {
  234. progressBarValue.value = 0
  235. }, 1000)
  236. })
  237. </script>
  238. <template>
  239. <div class="w-1/2 ltr:ml-2 rtl:mr-2">
  240. <h2 class="text-xl">Buttons</h2>
  241. <h3>Text only</h3>
  242. <div class="space-x-3 py-2 flex">
  243. <CommonButton variant="primary" />
  244. <CommonButton variant="secondary" />
  245. <CommonButton variant="tertiary" />
  246. <CommonButton variant="submit" />
  247. <CommonButton variant="danger" />
  248. </div>
  249. <h3>With icon</h3>
  250. <div class="space-x-3 py-2 flex">
  251. <CommonButton variant="primary" prefix-icon="logo-flat" />
  252. <CommonButton variant="secondary" prefix-icon="logo-flat" />
  253. <CommonButton variant="tertiary" prefix-icon="logo-flat" />
  254. <CommonButton variant="submit" prefix-icon="logo-flat" />
  255. <CommonButton variant="danger" prefix-icon="logo-flat" />
  256. </div>
  257. <h3>Icon only</h3>
  258. <div class="space-x-3 py-2 flex items-center">
  259. <CommonButton variant="primary" icon="logo-flat" />
  260. <CommonButton variant="secondary" icon="logo-flat" />
  261. <CommonButton variant="tertiary" icon="logo-flat" />
  262. <CommonButton variant="submit" icon="logo-flat" />
  263. <CommonButton variant="danger" icon="logo-flat" />
  264. <CommonButton variant="primary" icon="logo-flat" size="medium" />
  265. <CommonButton variant="secondary" icon="logo-flat" size="medium" />
  266. <CommonButton variant="tertiary" icon="logo-flat" size="medium" />
  267. <CommonButton variant="submit" icon="logo-flat" size="medium" />
  268. <CommonButton variant="danger" icon="logo-flat" size="medium" />
  269. <CommonButton variant="primary" icon="logo-flat" size="large" />
  270. <CommonButton variant="secondary" icon="logo-flat" size="large" />
  271. <CommonButton variant="tertiary" icon="logo-flat" size="large" />
  272. <CommonButton variant="submit" icon="logo-flat" size="large" />
  273. <CommonButton variant="danger" icon="logo-flat" size="large" />
  274. </div>
  275. <h3>Misc</h3>
  276. <div class="space-x-3 space-y-2 py-2 flex-wrap">
  277. <CommonButton variant="submit" block>Block button</CommonButton>
  278. <CommonButton variant="primary" disabled>Disabled button</CommonButton>
  279. <CommonButton variant="secondary" disabled>Disabled button</CommonButton>
  280. <CommonButton variant="tertiary" disabled>Disabled button</CommonButton>
  281. <CommonButton variant="submit" disabled>Disabled button</CommonButton>
  282. <CommonButton variant="danger" disabled>Disabled button</CommonButton>
  283. </div>
  284. <h3>Group</h3>
  285. <div class="w-1/2 space-x-3 space-y-2 py-2">
  286. <CommonButtonGroup :items="buttonGroupOptions" />
  287. </div>
  288. </div>
  289. <div class="w-1/2 ltr:ml-2 rtl:mr-2">
  290. <h2 class="text-xl">Alerts</h2>
  291. <CommonAlert
  292. variant="info"
  293. dismissible
  294. link="https://youtu.be/U6n2NcJ7rLc"
  295. link-text="Party 🎉"
  296. class="mb-2.5"
  297. >It's Friday!</CommonAlert
  298. >
  299. <CommonAlert variant="success" class="mb-2.5"
  300. >Hooray! Ticket got updated.</CommonAlert
  301. >
  302. <CommonAlert variant="warning" class="mb-2.5"
  303. >Heee! You're typing too fast.</CommonAlert
  304. >
  305. <CommonAlert variant="danger" class="mb-2.5"
  306. >Ooops! You broke it.</CommonAlert
  307. >
  308. </div>
  309. <div class="ltr:ml-2 rtl:mr-2">
  310. <h2>Labels</h2>
  311. <CommonLabel size="small" prefix-icon="logo" suffix-icon="logo-flat"
  312. >Small</CommonLabel
  313. >
  314. <br />
  315. <CommonLabel size="medium" prefix-icon="logo" suffix-icon="logo-flat"
  316. >Medium</CommonLabel
  317. >
  318. <br />
  319. <CommonLabel size="large" prefix-icon="logo" suffix-icon="logo-flat"
  320. >Large</CommonLabel
  321. >
  322. <br />
  323. <CommonLabel size="xl" prefix-icon="logo" suffix-icon="logo-flat"
  324. >Extra large</CommonLabel
  325. >
  326. </div>
  327. <div class="ltr:ml-2 rtl:mr-2">
  328. <h2>Badges</h2>
  329. <CommonBadge class="ltr:mr-2 rtl:ml-2" variant="neutral"
  330. >Neutral</CommonBadge
  331. >
  332. <CommonBadge class="ltr:mr-2 rtl:ml-2" variant="info">Info</CommonBadge>
  333. <CommonBadge class="ltr:mr-2 rtl:ml-2" variant="success"
  334. >Success</CommonBadge
  335. >
  336. <CommonBadge class="ltr:mr-2 rtl:ml-2" variant="warning"
  337. >Warning</CommonBadge
  338. >
  339. <CommonBadge class="ltr:mr-2 rtl:ml-2" variant="danger">Danger</CommonBadge>
  340. <CommonBadge
  341. class="ltr:mr-2 rtl:ml-2 dark:bg-pink-300 bg-pink-300 text-white"
  342. variant="custom"
  343. >Custom</CommonBadge
  344. >
  345. </div>
  346. <div class="w-1/5 ltr:ml-2 rtl:mr-2">
  347. <h2>Progress Bar</h2>
  348. <div class="flex flex-col gap-3">
  349. <div class="flex flex-col gap-2">
  350. <CommonLabel size="small">What is the meaning of life?</CommonLabel>
  351. <CommonProgressBar />
  352. </div>
  353. <div class="flex items-end gap-2">
  354. <div class="mb-1 grow flex flex-col gap-1">
  355. <div class="flex justify-between">
  356. <CommonLabel size="small">Organizations</CommonLabel>
  357. <CommonLabel
  358. class="text-stone-200 dark:text-neutral-500"
  359. size="small"
  360. >
  361. {{ progressBarValue }} of 100
  362. </CommonLabel>
  363. </div>
  364. <CommonProgressBar :value="progressBarValue.toString()" max="100" />
  365. </div>
  366. <CommonIcon
  367. class="shrink-0 fill-green-500"
  368. :class="progressBarValue !== 100 ? 'invisible' : undefined"
  369. name="check2"
  370. size="tiny"
  371. decorative
  372. />
  373. </div>
  374. </div>
  375. </div>
  376. <div class="w-1/2 ltr:ml-2 rtl:mr-2">
  377. <h2 class="text-lg">Form</h2>
  378. <Form
  379. id="playground-form"
  380. class="mb-96"
  381. form-class="mb-2.5 space-y-2.5"
  382. :schema="formSchema"
  383. :initial-values="formInitialValues"
  384. @submit="console.debug($event)"
  385. >
  386. <template #after-fields>
  387. <div class="mt-5 flex justify-end items-center gap-2">
  388. <CommonButton
  389. variant="secondary"
  390. size="medium"
  391. @click="reset('playground-form')"
  392. >
  393. Reset
  394. </CommonButton>
  395. <CommonButton variant="submit" type="submit" size="medium">
  396. Submit
  397. </CommonButton>
  398. </div>
  399. </template>
  400. </Form>
  401. </div>
  402. </template>