@caipira/tamandua 0.0.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.
Files changed (295) hide show
  1. package/.editorconfig +12 -0
  2. package/.prettierrc +5 -0
  3. package/.storybook/main.ts +25 -0
  4. package/.storybook/preview-body.html +3 -0
  5. package/.storybook/preview.ts +24 -0
  6. package/App.vue +1 -0
  7. package/Dockerfile +21 -0
  8. package/LICENSE +674 -0
  9. package/README.md +11 -0
  10. package/assets/icons/account.svg +1 -0
  11. package/assets/icons/alert-octagon-outline.svg +1 -0
  12. package/assets/icons/alert-octagon.svg +1 -0
  13. package/assets/icons/archive-outline.svg +1 -0
  14. package/assets/icons/archive.svg +1 -0
  15. package/assets/icons/arrow-left.svg +1 -0
  16. package/assets/icons/arrow-right.svg +1 -0
  17. package/assets/icons/bank-outline.svg +1 -0
  18. package/assets/icons/bank.svg +1 -0
  19. package/assets/icons/camera.svg +1 -0
  20. package/assets/icons/cards-outline.svg +1 -0
  21. package/assets/icons/cards-variant.svg +1 -0
  22. package/assets/icons/cart-outline.svg +1 -0
  23. package/assets/icons/chart-box-outline.svg +1 -0
  24. package/assets/icons/chart-box.svg +1 -0
  25. package/assets/icons/check-circle-outline.svg +1 -0
  26. package/assets/icons/check-circle.svg +1 -0
  27. package/assets/icons/check.svg +1 -0
  28. package/assets/icons/checkbox-dark.svg +1 -0
  29. package/assets/icons/checkbox-indeterminate-dark.svg +1 -0
  30. package/assets/icons/checkbox-indeterminate.svg +1 -0
  31. package/assets/icons/checkbox.svg +1 -0
  32. package/assets/icons/chevron-down.svg +1 -0
  33. package/assets/icons/chevron-left.svg +1 -0
  34. package/assets/icons/chevron-right.svg +1 -0
  35. package/assets/icons/chevron-up.svg +1 -0
  36. package/assets/icons/circle.svg +1 -0
  37. package/assets/icons/clock.svg +1 -0
  38. package/assets/icons/close-circle-outline.svg +1 -0
  39. package/assets/icons/close-circle.svg +1 -0
  40. package/assets/icons/close.svg +1 -0
  41. package/assets/icons/cog.svg +1 -0
  42. package/assets/icons/color-fill.svg +1 -0
  43. package/assets/icons/copy.svg +1 -0
  44. package/assets/icons/credit-card-plus.svg +1 -0
  45. package/assets/icons/credit-card.svg +1 -0
  46. package/assets/icons/currency.svg +1 -0
  47. package/assets/icons/database.svg +1 -0
  48. package/assets/icons/dots-grid.svg +1 -0
  49. package/assets/icons/dots-vertical.svg +1 -0
  50. package/assets/icons/email-open-outline.svg +1 -0
  51. package/assets/icons/email-outline.svg +1 -0
  52. package/assets/icons/eye-off.svg +1 -0
  53. package/assets/icons/eye.svg +1 -0
  54. package/assets/icons/file-document-plus-outline.svg +1 -0
  55. package/assets/icons/filmstrip.svg +1 -0
  56. package/assets/icons/filter.svg +1 -0
  57. package/assets/icons/fullscreen-exit.svg +1 -0
  58. package/assets/icons/fullscreen.svg +1 -0
  59. package/assets/icons/group.svg +1 -0
  60. package/assets/icons/image-album-outline.svg +1 -0
  61. package/assets/icons/image-album.svg +1 -0
  62. package/assets/icons/image-outline.svg +1 -0
  63. package/assets/icons/image.svg +1 -0
  64. package/assets/icons/info-outline.svg +1 -0
  65. package/assets/icons/key-chain.svg +1 -0
  66. package/assets/icons/key-variant.svg +1 -0
  67. package/assets/icons/key.svg +1 -0
  68. package/assets/icons/listbox-outline.svg +1 -0
  69. package/assets/icons/loading.svg +1 -0
  70. package/assets/icons/lock-outline.svg +1 -0
  71. package/assets/icons/lock.svg +1 -0
  72. package/assets/icons/logout.svg +1 -0
  73. package/assets/icons/menu-down.svg +1 -0
  74. package/assets/icons/menu-left.svg +1 -0
  75. package/assets/icons/menu-right.svg +1 -0
  76. package/assets/icons/menu.svg +1 -0
  77. package/assets/icons/minus-circle-outline.svg +1 -0
  78. package/assets/icons/minus-circle.svg +1 -0
  79. package/assets/icons/minus.svg +1 -0
  80. package/assets/icons/moon.svg +1 -0
  81. package/assets/icons/open-in-new.svg +1 -0
  82. package/assets/icons/pencil.svg +1 -0
  83. package/assets/icons/people.svg +1 -0
  84. package/assets/icons/piggy-bank-outline.svg +1 -0
  85. package/assets/icons/plus-circle-outline.svg +1 -0
  86. package/assets/icons/plus-circle.svg +1 -0
  87. package/assets/icons/plus.svg +1 -0
  88. package/assets/icons/qrcode-scan.svg +1 -0
  89. package/assets/icons/radio-dark.svg +1 -0
  90. package/assets/icons/radio.svg +1 -0
  91. package/assets/icons/refresh.svg +1 -0
  92. package/assets/icons/save.svg +1 -0
  93. package/assets/icons/search.svg +1 -0
  94. package/assets/icons/spotlight.svg +1 -0
  95. package/assets/icons/store-outline.svg +1 -0
  96. package/assets/icons/sun.svg +1 -0
  97. package/assets/icons/swap-horizontal.svg +1 -0
  98. package/assets/icons/swap-left.svg +1 -0
  99. package/assets/icons/swap-right.svg +1 -0
  100. package/assets/icons/swap.svg +1 -0
  101. package/assets/icons/system-theme.svg +1 -0
  102. package/assets/icons/tag-outline.svg +1 -0
  103. package/assets/icons/trash-can-outline.svg +1 -0
  104. package/assets/icons/trash-can.svg +1 -0
  105. package/assets/icons/upload.svg +1 -0
  106. package/assets/icons/user-circle.svg +1 -0
  107. package/assets/icons/zip-box.svg +1 -0
  108. package/assets/images/fs/apk.svg +11 -0
  109. package/assets/images/fs/bmp.svg +7 -0
  110. package/assets/images/fs/css.svg +8 -0
  111. package/assets/images/fs/doc.svg +9 -0
  112. package/assets/images/fs/docx.svg +9 -0
  113. package/assets/images/fs/folder-adwaita.svg +8 -0
  114. package/assets/images/fs/folder-black.svg +8 -0
  115. package/assets/images/fs/folder-brown.svg +8 -0
  116. package/assets/images/fs/folder-grey.svg +8 -0
  117. package/assets/images/fs/folder-nordic.svg +8 -0
  118. package/assets/images/fs/folder-orange.svg +8 -0
  119. package/assets/images/fs/folder-palebrown.svg +8 -0
  120. package/assets/images/fs/folder-paleorange.svg +8 -0
  121. package/assets/images/fs/folder-teal.svg +8 -0
  122. package/assets/images/fs/folder-white.svg +8 -0
  123. package/assets/images/fs/folder-yellow.svg +8 -0
  124. package/assets/images/fs/gif.svg +7 -0
  125. package/assets/images/fs/go.svg +9 -0
  126. package/assets/images/fs/ics.svg +24 -0
  127. package/assets/images/fs/iso.svg +10 -0
  128. package/assets/images/fs/jpeg.svg +7 -0
  129. package/assets/images/fs/jpg.svg +7 -0
  130. package/assets/images/fs/js.svg +9 -0
  131. package/assets/images/fs/json.svg +9 -0
  132. package/assets/images/fs/lua.svg +9 -0
  133. package/assets/images/fs/m4v.svg +7 -0
  134. package/assets/images/fs/md.svg +10 -0
  135. package/assets/images/fs/mov.svg +7 -0
  136. package/assets/images/fs/mp3.svg +9 -0
  137. package/assets/images/fs/mp4.svg +7 -0
  138. package/assets/images/fs/pdf.svg +9 -0
  139. package/assets/images/fs/pgp.svg +8 -0
  140. package/assets/images/fs/php.svg +9 -0
  141. package/assets/images/fs/png.svg +7 -0
  142. package/assets/images/fs/ppt.svg +9 -0
  143. package/assets/images/fs/py.svg +9 -0
  144. package/assets/images/fs/rar.svg +20 -0
  145. package/assets/images/fs/rpm.svg +7 -0
  146. package/assets/images/fs/rs.svg +9 -0
  147. package/assets/images/fs/sh.svg +9 -0
  148. package/assets/images/fs/tar.svg +20 -0
  149. package/assets/images/fs/txt.svg +8 -0
  150. package/assets/images/fs/unknown.svg +8 -0
  151. package/assets/images/fs/xls.svg +9 -0
  152. package/assets/images/fs/xlsx.svg +9 -0
  153. package/assets/images/fs/xml.svg +8 -0
  154. package/assets/images/fs/yaml.svg +9 -0
  155. package/assets/images/fs/zip.svg +20 -0
  156. package/components/Avatar/Avatar.story.ts +55 -0
  157. package/components/Avatar/Avatar.vue +82 -0
  158. package/components/Avatar/index.ts +12 -0
  159. package/components/Backdrop/Backdrop.vue +27 -0
  160. package/components/Backdrop/index.ts +12 -0
  161. package/components/Button/Button.story.ts +74 -0
  162. package/components/Button/Button.vue +230 -0
  163. package/components/Button/index.ts +12 -0
  164. package/components/ButtonCopy/ButtonCopy.vue +61 -0
  165. package/components/ButtonCopy/index.ts +12 -0
  166. package/components/Drawer/Drawer.vue +102 -0
  167. package/components/Drawer/index.ts +12 -0
  168. package/components/Dropdown/Dropdown.vue +258 -0
  169. package/components/Dropdown/index.ts +12 -0
  170. package/components/EventListener/EventListener.vue +12 -0
  171. package/components/FileDrop/FileDrop.vue +116 -0
  172. package/components/FileDrop/index.ts +12 -0
  173. package/components/Form/Form.spec.ts +72 -0
  174. package/components/Form/Form.vue +134 -0
  175. package/components/Form/index.ts +12 -0
  176. package/components/FormItem/FormItem.vue +85 -0
  177. package/components/FormItem/index.ts +12 -0
  178. package/components/GraphyEmpty/GraphyEmpty.vue +16 -0
  179. package/components/GraphyEmpty/index.ts +12 -0
  180. package/components/GraphyLabel/GraphyLabel.vue +34 -0
  181. package/components/GraphyLabel/index.ts +12 -0
  182. package/components/GraphyPrice/GraphyPrice.story.ts +37 -0
  183. package/components/GraphyPrice/GraphyPrice.vue +65 -0
  184. package/components/GraphyPrice/index.ts +12 -0
  185. package/components/GraphySubtitle/GraphySubtitle.vue +22 -0
  186. package/components/GraphySubtitle/index.ts +12 -0
  187. package/components/GraphyTitle/GraphyTitle.vue +13 -0
  188. package/components/GraphyTitle/index.ts +12 -0
  189. package/components/Icon/Icon.vue +84 -0
  190. package/components/Icon/index.ts +12 -0
  191. package/components/IconButton/IconButton.vue +168 -0
  192. package/components/IconButton/index.ts +12 -0
  193. package/components/InputAvatar/InputAvatar.vue +63 -0
  194. package/components/InputAvatar/index.ts +12 -0
  195. package/components/InputCheckbox/InputCheckbox.vue +77 -0
  196. package/components/InputCheckbox/index.ts +12 -0
  197. package/components/InputColor/InputColor.vue +54 -0
  198. package/components/InputColor/index.ts +12 -0
  199. package/components/InputDate/InputDate.story.ts +15 -0
  200. package/components/InputDate/InputDate.vue +368 -0
  201. package/components/InputDate/index.ts +12 -0
  202. package/components/InputMultiplier/InputMultiplier.vue +144 -0
  203. package/components/InputMultiplier/index.ts +12 -0
  204. package/components/InputPassword/InputPassword.vue +168 -0
  205. package/components/InputPassword/index.ts +12 -0
  206. package/components/InputPhone/InputPhone.vue +125 -0
  207. package/components/InputPhone/index.ts +12 -0
  208. package/components/InputPrice/InputPrice.vue +96 -0
  209. package/components/InputPrice/index.ts +12 -0
  210. package/components/InputRadio/InputRadio.vue +41 -0
  211. package/components/InputRadio/InputRadioGroup.story.ts +24 -0
  212. package/components/InputRadio/InputRadioGroup.vue +48 -0
  213. package/components/InputRadio/index.ts +14 -0
  214. package/components/InputSelect/InputSelect.story.ts +87 -0
  215. package/components/InputSelect/InputSelect.vue +507 -0
  216. package/components/InputSelect/index.ts +12 -0
  217. package/components/InputSwitch/InputSwitch.story.ts +34 -0
  218. package/components/InputSwitch/InputSwitch.vue +82 -0
  219. package/components/InputSwitch/index.ts +12 -0
  220. package/components/InputText/InputText.vue +62 -0
  221. package/components/InputText/index.ts +12 -0
  222. package/components/InputTextarea/InputTextarea.vue +64 -0
  223. package/components/InputTextarea/index.ts +12 -0
  224. package/components/LineChart/LineChart.vue +14 -0
  225. package/components/LineChart/index.ts +12 -0
  226. package/components/Modal/Modal.vue +106 -0
  227. package/components/Modal/index.ts +12 -0
  228. package/components/ModalForm/ModalForm.vue +141 -0
  229. package/components/ModalForm/index.ts +12 -0
  230. package/components/Pagination/Pagination.story.ts +15 -0
  231. package/components/Pagination/Pagination.vue +138 -0
  232. package/components/Pagination/index.ts +12 -0
  233. package/components/PieChart/PieChart.vue +14 -0
  234. package/components/PieChart/index.ts +12 -0
  235. package/components/Popconfirm/Popconfirm.vue +80 -0
  236. package/components/Popconfirm/index.ts +12 -0
  237. package/components/Popover/Popover.vue +133 -0
  238. package/components/Popover/index.ts +12 -0
  239. package/components/ProgressCircle/ProgressCircle.story.ts +31 -0
  240. package/components/ProgressCircle/ProgressCircle.vue +82 -0
  241. package/components/ProgressCircle/index.ts +12 -0
  242. package/components/ProgressLine/ProgressLine.story.ts +27 -0
  243. package/components/ProgressLine/ProgressLine.vue +104 -0
  244. package/components/ProgressLine/index.ts +12 -0
  245. package/components/SensitiveInfo/SensitiveInfo.vue +18 -0
  246. package/components/SensitiveInfo/index.ts +12 -0
  247. package/components/Tab/Tab.vue +58 -0
  248. package/components/Tab/index.ts +12 -0
  249. package/components/Table/Table.story.ts +32 -0
  250. package/components/Table/Table.vue +318 -0
  251. package/components/Table/index.ts +12 -0
  252. package/components/Tag/Tag.vue +73 -0
  253. package/components/Tag/index.ts +12 -0
  254. package/components/Toast/Toast.vue +75 -0
  255. package/components/Toast/index.ts +12 -0
  256. package/components/index.ts +43 -0
  257. package/components/plugins.ts +89 -0
  258. package/composables/index.ts +2 -0
  259. package/composables/useBreakpoints.ts +30 -0
  260. package/composables/useRender.ts +29 -0
  261. package/entrypoint.sh +19 -0
  262. package/enums/app.ts +5 -0
  263. package/enums/form.ts +25 -0
  264. package/enums/ui.ts +160 -0
  265. package/env.d.ts +8 -0
  266. package/i18n.ts +20 -0
  267. package/index.css +383 -0
  268. package/index.html +22 -0
  269. package/index.ts +14 -0
  270. package/main.ts +31 -0
  271. package/package.json +70 -0
  272. package/plugins/register-component.ts +5 -0
  273. package/postcss.config.js +6 -0
  274. package/services/clipboard.ts +5 -0
  275. package/services/date.ts +27 -0
  276. package/services/form/crud.ts +109 -0
  277. package/services/form/form-data-transformers.ts +148 -0
  278. package/services/form/form-json-transformers.ts +91 -0
  279. package/services/form/form-transformer.ts +54 -0
  280. package/services/form/form-value-transformers.ts +35 -0
  281. package/services/form/form.test.ts +98 -0
  282. package/services/form/form.ts +80 -0
  283. package/services/password.ts +309 -0
  284. package/services/ui.ts +43 -0
  285. package/tailwind.config.js +16 -0
  286. package/tsconfig.json +23 -0
  287. package/types/address.ts +44 -0
  288. package/types/api.ts +28 -0
  289. package/types/common.ts +5 -0
  290. package/types/form.ts +144 -0
  291. package/types/index.ts +5 -0
  292. package/types/ui.ts +55 -0
  293. package/types/website.ts +16 -0
  294. package/vite.config.mts +38 -0
  295. package/vitest.setup.ts +21 -0
@@ -0,0 +1,144 @@
1
+ <script lang="ts" setup>
2
+ import { SocialDirectory } from "@/types/social-network";
3
+
4
+ import { ref, watch, inject } from "vue";
5
+
6
+ defineOptions({ name: "TInputMultiplier" });
7
+
8
+ const props = withDefaults(
9
+ defineProps<{
10
+ modelValue?: any[];
11
+ type?: string;
12
+ label?: string;
13
+ inputProps?: any;
14
+ }>(),
15
+ {
16
+ type: "",
17
+ label: "",
18
+ inputProps: {},
19
+ },
20
+ );
21
+
22
+ const values = ref<any[]>([]);
23
+ const formStyle = inject("formStyle", { label: "", input: "" });
24
+
25
+ const emit = defineEmits<{
26
+ (e: "update:modelValue", val: any): void;
27
+ (e: "on-fetch-directory", val: SocialDirectory): void;
28
+ }>();
29
+
30
+ const add = () => {
31
+ // @todo: Add an switch case that adds an value according to the input type
32
+ values.value.push({});
33
+ };
34
+
35
+ const setValue = (value: any[]) => {
36
+ values.value = value;
37
+ };
38
+
39
+ const onRemoveItem = (index: number) => {
40
+ values.value.splice(index, 1);
41
+ };
42
+
43
+ const getItemKey = (value: any, index: number): string | number => {
44
+ switch (props.type) {
45
+ case "social":
46
+ return `${value.network}-${value.profile}`;
47
+ default:
48
+ return index;
49
+ }
50
+ };
51
+
52
+ const onFetchDirectory = (directory: SocialDirectory) => {
53
+ values.value = [
54
+ ...values.value,
55
+ ...directory.social_networks
56
+ .filter(
57
+ (network) =>
58
+ !!!values.value.find(
59
+ (value) =>
60
+ value.network === network.network &&
61
+ value.profile === network.path,
62
+ ),
63
+ )
64
+ .map((network) => ({
65
+ network: network.network,
66
+ profile: network.path,
67
+ })),
68
+ ];
69
+
70
+ emit("on-fetch-directory", directory);
71
+ };
72
+
73
+ watch(
74
+ values,
75
+ (newValues: any[]) => {
76
+ emit("update:modelValue", newValues);
77
+ },
78
+ { deep: true },
79
+ );
80
+
81
+ watch(
82
+ () => props.modelValue,
83
+ (newValue) => {
84
+ setValue(newValue ?? []);
85
+ },
86
+ { immediate: true },
87
+ );
88
+ </script>
89
+
90
+ <template>
91
+ <div>
92
+ <div class="inline-flex w-full items-center my-3">
93
+ <t-graphy-label
94
+ v-if="label"
95
+ :text="label"
96
+ class="text-right"
97
+ />
98
+ <t-button
99
+ :label="`Add ${label}`"
100
+ variant="primary"
101
+ :is-outline="true"
102
+ icon="plus"
103
+ size="sm"
104
+ @click="add"
105
+ />
106
+ </div>
107
+ <div
108
+ v-for="(value, index) in values"
109
+ :key="getItemKey(value, index)"
110
+ :label="`${label} ${index + 1}`"
111
+ class="flex items-center justify-start mt-1 ml-2"
112
+ >
113
+ <div :class="{ [formStyle.label]: true }" />
114
+ <t-input-social
115
+ v-if="type === 'social'"
116
+ v-model="values[index]"
117
+ class="my-1"
118
+ @onFetchDirectory="onFetchDirectory"
119
+ />
120
+ <t-input-text
121
+ v-else-if="type === 'text'"
122
+ v-model="values[index]"
123
+ class="my-1"
124
+ />
125
+ <t-input-phone
126
+ v-else-if="type === 'phone'"
127
+ v-model="values[index]"
128
+ class="my-1"
129
+ />
130
+ <t-input-website
131
+ v-else-if="type === 'website'"
132
+ v-model="values[index]"
133
+ v-bind="props.inputProps"
134
+ class="my-1"
135
+ />
136
+ <t-icon-button
137
+ icon="close"
138
+ size="sm"
139
+ class="ml-2"
140
+ @click="() => onRemoveItem(index)"
141
+ />
142
+ </div>
143
+ </div>
144
+ </template>
@@ -0,0 +1,12 @@
1
+ import type { App, Plugin } from "vue";
2
+ import registerComponent from "@/plugins/register-component";
3
+
4
+ import InputMultiplier from "./InputMultiplier.vue";
5
+
6
+ export default {
7
+ install(app: App) {
8
+ registerComponent(app, InputMultiplier);
9
+ },
10
+ } as Plugin;
11
+
12
+ export { InputMultiplier };
@@ -0,0 +1,168 @@
1
+ <script lang="ts" setup>
2
+ import { InputPasswordModel } from "@/types/form";
3
+
4
+ import dateService from "@/services/date";
5
+ import passwordService from "@/services/password";
6
+ import { inject, ref, watch } from "vue";
7
+
8
+ import InputText from "@/components/InputText/InputText.vue";
9
+ import ButtonCopy from "@/components/ButtonCopy/ButtonCopy.vue";
10
+
11
+ defineOptions({ name: "TInputPassword" });
12
+
13
+ const props = withDefaults(
14
+ defineProps<{
15
+ keyup?: any;
16
+ encrypt?: boolean;
17
+ canCopy?: boolean;
18
+ modelValue?: InputPasswordModel;
19
+ simpleMode?: boolean;
20
+ showRefresh?: boolean;
21
+ showStrength?: boolean;
22
+ autocomplete?: string;
23
+ }>(),
24
+ {
25
+ keyup: () => () => {},
26
+ encrypt: true,
27
+ canCopy: true,
28
+ simpleMode: false,
29
+ showRefresh: false,
30
+ showStrength: false,
31
+ autocomplete: "current-password",
32
+ },
33
+ );
34
+
35
+ const emit = defineEmits<{
36
+ (e: "generate", val: InputPasswordModel): void;
37
+ (e: "update:modelValue", val: InputPasswordModel): void;
38
+ (e: "enter"): void;
39
+ }>();
40
+
41
+ const type = ref<"password" | "text">("password");
42
+ const input = ref<InstanceType<typeof InputText> | null>(null);
43
+ const strength = ref<number>(0);
44
+ const password = ref<string>("");
45
+ const isLoading = ref<boolean>(false);
46
+ const formStyle = inject("formStyle", { input: "w-full" });
47
+ const updatedAt = ref<Date | null>(null);
48
+
49
+ const setValue = (localPassword?: InputPasswordModel) => {
50
+ if (typeof localPassword !== "object") {
51
+ return;
52
+ }
53
+
54
+ password.value = localPassword.value;
55
+ strength.value = localPassword.strength
56
+ ? localPassword.strength
57
+ : passwordService.getPasswordStrength(localPassword.value).score;
58
+ updatedAt.value = localPassword.updatedAt ? localPassword.updatedAt : null;
59
+ };
60
+
61
+ const passwordToPayload = (password: string): InputPasswordModel => {
62
+ strength.value = passwordService.getPasswordStrength(password).score;
63
+
64
+ return {
65
+ value: password,
66
+ strength: strength.value,
67
+ encrypt: props.encrypt,
68
+ updatedAt: updatedAt.value ? updatedAt.value : null,
69
+ } as InputPasswordModel;
70
+ };
71
+
72
+ const onInput = (password: string) => {
73
+ emit("update:modelValue", passwordToPayload(password));
74
+ };
75
+
76
+ const focus = () => {
77
+ if (input.value && input.value.$el) {
78
+ input.value.$el.focus();
79
+ }
80
+ };
81
+
82
+ const generatePassword = async () => {
83
+ isLoading.value = true;
84
+
85
+ // const { data } = await api.get("passwords/generate");
86
+ const data = "asdasdasd545";
87
+
88
+ isLoading.value = false;
89
+
90
+ emit("generate", passwordToPayload(password.value));
91
+ onInput(data);
92
+ };
93
+
94
+ watch(() => props.modelValue, setValue, { immediate: true });
95
+
96
+ defineExpose({ focus });
97
+ </script>
98
+
99
+ <template>
100
+ <div :class="{ [formStyle.input]: true }">
101
+ <div class="flex border h-9 relative input-roundness input-border">
102
+ <div
103
+ v-if="props.canCopy"
104
+ class="border-r select-none input-border input-control"
105
+ :class="{ 'w-12': props.canCopy }"
106
+ >
107
+ <ButtonCopy
108
+ class="mx-1"
109
+ :text="password"
110
+ :is-disabled="isLoading"
111
+ />
112
+ </div>
113
+ <div
114
+ v-if="props.showRefresh"
115
+ class="border-r select-none input-border input-control"
116
+ :class="{ 'w-12': props.showRefresh }"
117
+ >
118
+ <t-icon
119
+ icon="refresh"
120
+ size="sm"
121
+ role="button"
122
+ :disabled="isLoading"
123
+ @click="generatePassword"
124
+ />
125
+ </div>
126
+ <t-input-text
127
+ v-model="password"
128
+ :type="type"
129
+ :autocomplete="props.autocomplete"
130
+ :disabled="isLoading"
131
+ :disable-style="true"
132
+ ref="input"
133
+ class="w-full px-2 input-bg-color input-text-color input-outline input-roundness"
134
+ @keyup.enter="emit('enter')"
135
+ @input="onInput(password)"
136
+ @keyup="props.keyup"
137
+ />
138
+ <div class="border-l select-none input-border input-control">
139
+ <t-icon
140
+ :icon="type === 'password' ? 'eye' : 'eye-off'"
141
+ :disabled="isLoading"
142
+ size="sm"
143
+ role="button"
144
+ @click="type = type === 'password' ? 'text' : 'password'"
145
+ />
146
+ </div>
147
+ </div>
148
+ <t-progress-line
149
+ v-if="props.showStrength"
150
+ :value="strength"
151
+ :height="1"
152
+ :show-percentage="false"
153
+ class="rounded-sm"
154
+ />
155
+ <small
156
+ v-if="updatedAt"
157
+ class="inline-block float-right select-none"
158
+ >
159
+ Last updated
160
+ {{
161
+ dateService.format(
162
+ new Date(updatedAt),
163
+ "MMMM do yyyy, hh:mm:ss",
164
+ )
165
+ }}
166
+ </small>
167
+ </div>
168
+ </template>
@@ -0,0 +1,12 @@
1
+ import type { App, Plugin } from "vue";
2
+ import registerComponent from "@/plugins/register-component";
3
+
4
+ import InputPassword from "./InputPassword.vue";
5
+
6
+ export default {
7
+ install(app: App) {
8
+ registerComponent(app, InputPassword);
9
+ },
10
+ } as Plugin;
11
+
12
+ export { InputPassword };
@@ -0,0 +1,125 @@
1
+ <script lang="ts" setup>
2
+ import { Country } from "@/types/address";
3
+ import { SelectOption, SelectValue } from "@/types/form";
4
+
5
+ import { ref, watch, inject, onBeforeMount } from "vue";
6
+
7
+ type PhoneNumber = {
8
+ iso2: string;
9
+ dialCode: string;
10
+ number: string;
11
+ };
12
+
13
+ defineOptions({ name: "TInputPhone" });
14
+
15
+ const props = withDefaults(
16
+ defineProps<{
17
+ resource: any;
18
+ modelValue?: PhoneNumber;
19
+ }>(),
20
+ {
21
+ modelValue: () => ({}) as any,
22
+ },
23
+ );
24
+
25
+ const emit = defineEmits<{
26
+ (e: "update:modelValue", val: PhoneNumber): void;
27
+ }>();
28
+
29
+ const number = ref<string>("");
30
+ const country = ref<SelectValue>();
31
+ const options = ref<SelectOption[]>([]);
32
+ const countries = ref<Country[]>([]);
33
+ const formStyle = inject("formStyle", { label: "", input: "" });
34
+
35
+ const emitInput = () => {
36
+ if (!country.value) {
37
+ return;
38
+ }
39
+
40
+ const localCountry = countries.value.find(
41
+ (c) => c.dialCode === country.value,
42
+ );
43
+
44
+ if (!localCountry) {
45
+ return;
46
+ }
47
+
48
+ emit("update:modelValue", {
49
+ iso2: localCountry.iso2,
50
+ dialCode: localCountry.dialCode,
51
+ number: number.value ?? "",
52
+ });
53
+ };
54
+
55
+ const fetchCountries = async () => {
56
+ countries.value = await props.resource();
57
+
58
+ options.value =
59
+ countries.value.map(
60
+ (country: Country): SelectOption => ({
61
+ label: country,
62
+ value: country.dialCode,
63
+ }),
64
+ ) ?? [];
65
+ };
66
+
67
+ const setValue = async (value: any) => {
68
+ if (!value) {
69
+ return;
70
+ }
71
+
72
+ if (typeof value === "object") {
73
+ country.value = value.dialCode;
74
+
75
+ if ("number" in value) {
76
+ number.value = value.number;
77
+ }
78
+ }
79
+ };
80
+
81
+ onBeforeMount(async () => {
82
+ await fetchCountries();
83
+ setValue(props.modelValue);
84
+ });
85
+
86
+ watch(
87
+ () => props.modelValue,
88
+ (newValue) => {
89
+ setValue(newValue);
90
+ },
91
+ { immediate: true },
92
+ );
93
+ </script>
94
+
95
+ <template>
96
+ <div
97
+ class="flex border h-9 input-bg-color input-text-color input-border input-roundness"
98
+ :class="{ [formStyle.input]: true }"
99
+ >
100
+ <t-input-select
101
+ v-model="country"
102
+ :options="options"
103
+ :disable-style="true"
104
+ class="border-r w-min-20 flex justify-center items-center input-border"
105
+ @update:modelValue="emitInput"
106
+ >
107
+ <template v-slot:default="option">
108
+ <span
109
+ >{{ option.flag }} {{ option.name }} +{{
110
+ option.dialCode
111
+ }}</span
112
+ >
113
+ </template>
114
+ <template v-slot:selection="option">
115
+ <span>{{ option.flag }} +{{ option.dialCode }}</span>
116
+ </template>
117
+ </t-input-select>
118
+ <t-input-text
119
+ v-model="number"
120
+ :disable-style="true"
121
+ class="w-full input-bg-color input-text-color input-outline input-roundness input-padding"
122
+ @input="emitInput"
123
+ />
124
+ </div>
125
+ </template>
@@ -0,0 +1,12 @@
1
+ import type { App, Plugin } from "vue";
2
+ import registerComponent from "@/plugins/register-component";
3
+
4
+ import InputPhone from "./InputPhone.vue";
5
+
6
+ export default {
7
+ install(app: App) {
8
+ registerComponent(app, InputPhone);
9
+ },
10
+ } as Plugin;
11
+
12
+ export { InputPhone };
@@ -0,0 +1,96 @@
1
+ <script lang="ts" setup>
2
+ import { InputPriceModel, SelectOption } from "@/types/form";
3
+
4
+ import { ref, watch, inject, onBeforeMount } from "vue";
5
+
6
+ defineOptions({ name: "TInputPrice", inheritAttrs: false });
7
+
8
+ const props = withDefaults(
9
+ defineProps<{
10
+ modelValue?: InputPriceModel;
11
+ wrapperClass?: string;
12
+ resource?: any;
13
+ }>(),
14
+ {
15
+ modelValue: () => ({}) as any,
16
+ },
17
+ );
18
+
19
+ const emit = defineEmits<{
20
+ (e: "update:modelValue", val: InputPriceModel): void;
21
+ }>();
22
+
23
+ const price = ref<string>("");
24
+ const currency = ref<string>("");
25
+ const formStyle = inject("formStyle", { label: "", input: "" });
26
+ const currencies = ref<SelectOption[]>([]);
27
+
28
+ const fetchCurrencies = async () => {
29
+ currencies.value = (await props.resource()).map(
30
+ (currency: any): SelectOption => ({
31
+ label: currency.symbol,
32
+ value: currency.iso,
33
+ }),
34
+ );
35
+ };
36
+
37
+ const emitInput = () => {
38
+ emit("update:modelValue", {
39
+ iso: currency.value,
40
+ value: parseFloat(price.value),
41
+ });
42
+ };
43
+
44
+ const setValue = (value: any) => {
45
+ if (!value || typeof value !== "object") {
46
+ return;
47
+ }
48
+
49
+ if (props.modelValue?.value) {
50
+ price.value = `${props.modelValue.value}`;
51
+ }
52
+
53
+ if (props.modelValue?.iso) {
54
+ currency.value = props.modelValue.iso;
55
+ }
56
+ };
57
+
58
+ onBeforeMount(async () => {
59
+ await fetchCurrencies();
60
+ });
61
+
62
+ watch(
63
+ () => props.modelValue,
64
+ (newValue) => {
65
+ setValue(newValue);
66
+ },
67
+ { immediate: true },
68
+ );
69
+ </script>
70
+
71
+ <template>
72
+ <div
73
+ class="flex h-9"
74
+ :class="{
75
+ [formStyle.input]: true,
76
+ 'input-bg-color input-text-color border input-border input-roundness':
77
+ props.wrapperClass ? false : true,
78
+ }"
79
+ >
80
+ <t-input-select
81
+ v-model="currency"
82
+ :options="currencies"
83
+ :disable-style="true"
84
+ class="w-20 flex justify-center items-center border-r input-border"
85
+ v-bind="$attrs"
86
+ @update:modelValue="emitInput"
87
+ />
88
+ <t-input-text
89
+ v-model="price"
90
+ :disable-style="true"
91
+ class="w-full input-bg-color input-text-color input-outline input-roundness input-padding"
92
+ v-bind="$attrs"
93
+ @update:modelValue="emitInput"
94
+ />
95
+ </div>
96
+ </template>
@@ -0,0 +1,12 @@
1
+ import type { App, Plugin } from "vue";
2
+ import registerComponent from "@/plugins/register-component";
3
+
4
+ import InputPrice from "./InputPrice.vue";
5
+
6
+ export default {
7
+ install(app: App) {
8
+ registerComponent(app, InputPrice);
9
+ },
10
+ } as Plugin;
11
+
12
+ export { InputPrice };
@@ -0,0 +1,41 @@
1
+ <script lang="ts">
2
+ let id = 0;
3
+ </script>
4
+
5
+ <script lang="ts" setup>
6
+ import { inject } from "vue";
7
+
8
+ defineOptions({ name: "TInputRadio" });
9
+
10
+ const props = defineProps<{
11
+ value?: any;
12
+ label?: string;
13
+ }>();
14
+
15
+ const ref = `radio_${++id}`;
16
+ const name = inject("name", "");
17
+ const model = inject<string>("model", "");
18
+ const change = inject<(value: string) => void>("change", () => {});
19
+ const disabled = inject<boolean>("disabled", false);
20
+ </script>
21
+
22
+ <template>
23
+ <div class="h-9 inline-flex items-center">
24
+ <input
25
+ :value="props.value"
26
+ :name="name"
27
+ :id="ref"
28
+ :disabled="disabled"
29
+ :checked="props.value === model"
30
+ type="radio"
31
+ class="form-radio relative w-5 h-5 border border-caipira-primary-inverted checked:hover:border-caipira-primary-inverted checked:focus:border-caipira-primary-inverted checked:border-caipira-primary-inverted input-outline focus:input-outline bg-caipira-primary color-caipira-primary cursor-pointer bg-[length:30px]"
32
+ @change="change(props.value)"
33
+ />
34
+ <label
35
+ class="cursor-pointer pl-2 mr-3 input-label"
36
+ :for="ref"
37
+ >
38
+ {{ label }}
39
+ </label>
40
+ </div>
41
+ </template>
@@ -0,0 +1,24 @@
1
+ export default {
2
+ title: "Form/Radio Group",
3
+ args: {},
4
+ };
5
+
6
+ const defaultArgs = {};
7
+
8
+ const Template = (args: typeof defaultArgs) => ({
9
+ setup() {
10
+ return { args };
11
+ },
12
+ template: `
13
+ <t-input-radio-group v-bind="args">
14
+ <t-input-radio value="1" label="Option 1" />
15
+ <t-input-radio value="2" label="Option 2" />
16
+ <t-input-radio value="3" label="Option 3" />
17
+ </t-input-radio-group>
18
+ `,
19
+ });
20
+
21
+ const Default: any = Template.bind({});
22
+ Default.args = defaultArgs;
23
+
24
+ export { Default };
@@ -0,0 +1,48 @@
1
+ <script lang="ts" setup>
2
+ import { computed, provide, inject, onBeforeMount } from "vue";
3
+
4
+ defineOptions({ name: "TInputRadioGroup" });
5
+
6
+ const props = withDefaults(
7
+ defineProps<{
8
+ disabled?: boolean;
9
+ modelValue?: any;
10
+ initialValue?: any;
11
+ }>(),
12
+ {
13
+ disabled: false,
14
+ },
15
+ );
16
+
17
+ const formStyle = inject("formStyle", { input: "w-full" });
18
+
19
+ const emit = defineEmits<{
20
+ (e: "update:modelValue", val: string): void;
21
+ }>();
22
+
23
+ const change = (value: string) => {
24
+ emit("update:modelValue", value);
25
+ };
26
+
27
+ const name: string = `radio_${Math.floor(Math.random() * 1000)}`;
28
+
29
+ onBeforeMount(() => {
30
+ if (!props.modelValue && props.initialValue) {
31
+ change(props.initialValue);
32
+ }
33
+ });
34
+
35
+ provide("name", name);
36
+ provide(
37
+ "model",
38
+ computed(() => props.modelValue),
39
+ );
40
+ provide("change", change);
41
+ provide("disabled", props.disabled);
42
+ </script>
43
+
44
+ <template>
45
+ <div :class="{ [formStyle.input]: true }">
46
+ <slot />
47
+ </div>
48
+ </template>