polpo 0.1.13 → 0.1.16

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 (204) hide show
  1. package/.turbo/cache/eslint/.cache_16wwsjl +1 -0
  2. package/.turbo/cache/eslint/.cache_rpznjo +1 -0
  3. package/.turbo/turbo-build$colon$code.log +49 -0
  4. package/.turbo/turbo-build$colon$css.log +2 -0
  5. package/.turbo/turbo-build.log +43 -0
  6. package/.turbo/turbo-lint.log +2 -0
  7. package/dist/components.cjs +1 -3655
  8. package/dist/components.css +2 -2173
  9. package/dist/components.js +1 -3576
  10. package/dist/helpers.cjs +1 -311
  11. package/dist/helpers.d.cts +4 -1
  12. package/dist/helpers.d.ts +4 -1
  13. package/dist/helpers.js +1 -276
  14. package/dist/hooks.cjs +1 -1065
  15. package/dist/hooks.js +1 -998
  16. package/dist/layouts.cjs +1 -146
  17. package/dist/layouts.css +2 -5
  18. package/dist/layouts.js +1 -119
  19. package/dist/types.cjs +1 -19
  20. package/dist/types.js +0 -1
  21. package/eslint.config.js +4 -0
  22. package/package.json +16 -11
  23. package/postcss.config.js +3 -0
  24. package/src/components/accordion/accordion-item.tsx +123 -0
  25. package/src/components/accordion/accordion.component.tsx +80 -0
  26. package/src/components/accordion/accordion.styles.css +41 -0
  27. package/src/components/accordion/index.ts +2 -0
  28. package/src/components/button/button.component.tsx +50 -0
  29. package/src/components/button/button.styles.css +317 -0
  30. package/src/components/button/index.ts +1 -0
  31. package/src/components/cards/flip-card/flip-card.component.tsx +66 -0
  32. package/src/components/cards/flip-card/flip-card.styles.css +50 -0
  33. package/src/components/cards/flip-card/index.ts +1 -0
  34. package/src/components/cards/hover-card/hover-card.component.tsx +76 -0
  35. package/src/components/cards/hover-card/hover-card.styles.css +13 -0
  36. package/src/components/cards/hover-card/index.ts +1 -0
  37. package/src/components/cards/index.ts +3 -0
  38. package/src/components/cards/slide-card/index.ts +1 -0
  39. package/src/components/cards/slide-card/slide-card.component.tsx +27 -0
  40. package/src/components/component.types.ts +31 -0
  41. package/src/components/cursor/cursor.component.tsx +49 -0
  42. package/src/components/cursor/cursor.styles.css +73 -0
  43. package/src/components/cursor/index.ts +1 -0
  44. package/src/components/form/checkbox/checkbox.component.tsx +95 -0
  45. package/src/components/form/checkbox/checkbox.styles.css +162 -0
  46. package/src/components/form/checkbox/index.ts +1 -0
  47. package/src/components/form/controller/controller.component.tsx +42 -0
  48. package/src/components/form/controller/index.ts +1 -0
  49. package/src/components/form/date-picker/date-picker.component.tsx +66 -0
  50. package/src/components/form/date-picker/index.ts +1 -0
  51. package/src/components/form/field/field.component.tsx +84 -0
  52. package/src/components/form/field/field.styles.css +98 -0
  53. package/src/components/form/field/field.types.ts +34 -0
  54. package/src/components/form/field/index.ts +2 -0
  55. package/src/components/form/form.types.ts +37 -0
  56. package/src/components/form/index.ts +14 -0
  57. package/src/components/form/input/index.ts +1 -0
  58. package/src/components/form/input/input.component.tsx +75 -0
  59. package/src/components/form/input-color/index.ts +1 -0
  60. package/src/components/form/input-color/input-color.component.tsx +170 -0
  61. package/src/components/form/input-color/input-color.styles.css +92 -0
  62. package/src/components/form/input-file/index.ts +1 -0
  63. package/src/components/form/input-file/input-file.component.tsx +221 -0
  64. package/src/components/form/input-file/input-file.styles.css +143 -0
  65. package/src/components/form/input-number/index.ts +1 -0
  66. package/src/components/form/input-number/input-number.component.tsx +144 -0
  67. package/src/components/form/input-password/index.ts +1 -0
  68. package/src/components/form/input-password/input-password.component.tsx +77 -0
  69. package/src/components/form/radio/index.ts +1 -0
  70. package/src/components/form/radio/radio.component.tsx +92 -0
  71. package/src/components/form/radio/radio.styles.css +117 -0
  72. package/src/components/form/select/index.ts +1 -0
  73. package/src/components/form/select/option.tsx +101 -0
  74. package/src/components/form/select/options.tsx +165 -0
  75. package/src/components/form/select/select.component.tsx +317 -0
  76. package/src/components/form/select/select.styles.css +115 -0
  77. package/src/components/form/select/select.types.ts +97 -0
  78. package/src/components/form/slider/index.ts +1 -0
  79. package/src/components/form/slider/slider.component.tsx +117 -0
  80. package/src/components/form/slider/slider.styles.css +94 -0
  81. package/src/components/form/switch/index.ts +1 -0
  82. package/src/components/form/switch/switch.component.tsx +166 -0
  83. package/src/components/form/switch/switch.styles.css +165 -0
  84. package/src/components/form/textarea/index.ts +1 -0
  85. package/src/components/form/textarea/textarea.component.tsx +80 -0
  86. package/src/components/form/textarea/textarea.styles.css +7 -0
  87. package/src/components/image/image.tsx +7 -0
  88. package/src/components/image/index.ts +1 -0
  89. package/src/components/index.ts +15 -0
  90. package/src/components/infinity-scroll/index.ts +1 -0
  91. package/src/components/infinity-scroll/infinity-scroll.component.tsx +51 -0
  92. package/src/components/infinity-scroll/infinity-scroll.styles.css +25 -0
  93. package/src/components/line/index.ts +1 -0
  94. package/src/components/line/line.component.tsx +77 -0
  95. package/src/components/line/line.styles.css +61 -0
  96. package/src/components/modals/action-modal/action-modal.component.tsx +150 -0
  97. package/src/components/modals/action-modal/action-modal.styles.css +115 -0
  98. package/src/components/modals/action-modal/index.ts +1 -0
  99. package/src/components/modals/aside-modal/aside-modal.component.tsx +63 -0
  100. package/src/components/modals/aside-modal/aside-modal.styles.css +86 -0
  101. package/src/components/modals/aside-modal/index.ts +1 -0
  102. package/src/components/modals/confirmation-modal/confirmation-modal.component.tsx +43 -0
  103. package/src/components/modals/confirmation-modal/confirmation-modal.styles.css +17 -0
  104. package/src/components/modals/confirmation-modal/index.ts +1 -0
  105. package/src/components/modals/index.ts +6 -0
  106. package/src/components/modals/menu/index.ts +1 -0
  107. package/src/components/modals/menu/menu.component.tsx +194 -0
  108. package/src/components/modals/menu/menu.styles.css +101 -0
  109. package/src/components/modals/modal/index.ts +2 -0
  110. package/src/components/modals/modal/modal.backdrop.tsx +67 -0
  111. package/src/components/modals/modal/modal.component.tsx +104 -0
  112. package/src/components/modals/modal/modal.styles.css +70 -0
  113. package/src/components/modals/portal/index.ts +1 -0
  114. package/src/components/modals/portal/portal.component.tsx +19 -0
  115. package/src/components/ripple/index.ts +1 -0
  116. package/src/components/ripple/ripple.component.tsx +70 -0
  117. package/src/components/ripple/ripple.styles.css +33 -0
  118. package/src/components/smart-table/index.ts +2 -0
  119. package/src/components/smart-table/smart-table.column.tsx +62 -0
  120. package/src/components/smart-table/smart-table.component.tsx +116 -0
  121. package/src/components/smart-table/smart-table.helpers.tsx +58 -0
  122. package/src/components/smart-table/smart-table.hooks.ts +27 -0
  123. package/src/components/smart-table/smart-table.row.tsx +28 -0
  124. package/src/components/smart-table/smart-table.styles.css +102 -0
  125. package/src/components/smart-table/smart-table.types.ts +42 -0
  126. package/src/components/tabs/index.ts +1 -0
  127. package/src/components/tabs/tabs-list.tsx +120 -0
  128. package/src/components/tabs/tabs.styles.css +164 -0
  129. package/src/components/tabs/tabs.tsx +119 -0
  130. package/src/components/tag/index.ts +1 -0
  131. package/src/components/tag/tag.component.tsx +34 -0
  132. package/src/components/tag/tag.styles.css +50 -0
  133. package/src/components/tooltips/click-to-copy/click-to-copy.component.tsx +41 -0
  134. package/src/components/tooltips/click-to-copy/index.ts +1 -0
  135. package/src/components/tooltips/index.ts +2 -0
  136. package/src/components/tooltips/tooltip/index.ts +1 -0
  137. package/src/components/tooltips/tooltip/tooltip.component.tsx +64 -0
  138. package/src/components/tooltips/tooltip/tooltip.styles.css +91 -0
  139. package/src/components/typography/index.ts +1 -0
  140. package/src/components/typography/typography.component.tsx +81 -0
  141. package/src/components/typography/typography.constants.ts +53 -0
  142. package/src/components/typography/typography.styles.css +122 -0
  143. package/src/helpers/cn.ts +6 -0
  144. package/src/helpers/format-bytes.ts +11 -0
  145. package/src/helpers/format-dates.ts +47 -0
  146. package/src/helpers/get-modal-position-relative-to-screen.ts +86 -0
  147. package/src/helpers/get-modal-position.ts +211 -0
  148. package/src/helpers/index.ts +6 -0
  149. package/src/helpers/text/index.ts +1 -0
  150. package/src/helpers/text/to-capitalize.ts +17 -0
  151. package/src/hooks/index.ts +30 -0
  152. package/src/hooks/use-async.ts +88 -0
  153. package/src/hooks/use-classnames.ts +13 -0
  154. package/src/hooks/use-click-outside.ts +32 -0
  155. package/src/hooks/use-constant.ts +3 -0
  156. package/src/hooks/use-cookie.ts +124 -0
  157. package/src/hooks/use-debounce-state.ts +13 -0
  158. package/src/hooks/use-debounce.ts +15 -0
  159. package/src/hooks/use-dimensions.ts +19 -0
  160. package/src/hooks/use-dom-container.ts +35 -0
  161. package/src/hooks/use-event-listener.ts +71 -0
  162. package/src/hooks/use-file-reader.ts +69 -0
  163. package/src/hooks/use-geolocation.ts +63 -0
  164. package/src/hooks/use-hover.ts +17 -0
  165. package/src/hooks/use-in-view.ts +18 -0
  166. package/src/hooks/use-input-handlers.ts +52 -0
  167. package/src/hooks/use-intersection-observer.ts +19 -0
  168. package/src/hooks/use-media-query.ts +25 -0
  169. package/src/hooks/use-modal-in-container.ts +85 -0
  170. package/src/hooks/use-modal-transition.ts +64 -0
  171. package/src/hooks/use-modal.ts +21 -0
  172. package/src/hooks/use-mouse-position.ts +64 -0
  173. package/src/hooks/use-online-status.ts +12 -0
  174. package/src/hooks/use-render-count.ts +11 -0
  175. package/src/hooks/use-resize-observer.ts +18 -0
  176. package/src/hooks/use-safe-dispatch.ts +22 -0
  177. package/src/hooks/use-scroll.ts +31 -0
  178. package/src/hooks/use-state-history.ts +22 -0
  179. package/src/hooks/use-toggle-values.ts +14 -0
  180. package/src/hooks/use-toggle.ts +11 -0
  181. package/src/hooks/use-viewport.ts +38 -0
  182. package/src/index.ts +5 -0
  183. package/src/layouts/flex/flex.component.tsx +75 -0
  184. package/src/layouts/flex/index.ts +1 -0
  185. package/src/layouts/grid/grid.component.tsx +89 -0
  186. package/src/layouts/grid/grid.styles.css +5 -0
  187. package/src/layouts/grid/index.ts +1 -0
  188. package/src/layouts/index.ts +2 -0
  189. package/src/types/generics.ts +68 -0
  190. package/src/types/index.ts +1 -0
  191. package/tsconfig.json +10 -0
  192. package/tsup.config.cjs +36 -0
  193. package/dist/components.cjs.map +0 -1
  194. package/dist/components.css.map +0 -1
  195. package/dist/components.js.map +0 -1
  196. package/dist/helpers.cjs.map +0 -1
  197. package/dist/helpers.js.map +0 -1
  198. package/dist/hooks.cjs.map +0 -1
  199. package/dist/hooks.js.map +0 -1
  200. package/dist/layouts.cjs.map +0 -1
  201. package/dist/layouts.css.map +0 -1
  202. package/dist/layouts.js.map +0 -1
  203. package/dist/types.cjs.map +0 -1
  204. package/dist/types.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .cursor-overlay {
4
+ position: fixed;
5
+ top: 0;
6
+ left: 0;
7
+ width: 100%;
8
+ height: 100%;
9
+ cursor: none;
10
+ pointer-events: none;
11
+ }
12
+
13
+ .cursor {
14
+ position: fixed;
15
+ border-radius: 50%;
16
+ z-index: 99999999;
17
+ pointer-events: none;
18
+ transform: translateZ(0);
19
+
20
+ @media (any-pointer: coarse) {
21
+ display: none;
22
+ }
23
+
24
+ &.outer-circle {
25
+ margin-left: -15px;
26
+ margin-top: -15px;
27
+ width: 30px;
28
+ height: 30px;
29
+ border: 2px solid var(--color-primary-500);
30
+ box-sizing: border-box;
31
+ z-index: 99999999;
32
+ opacity: 0.5;
33
+ transition:
34
+ all 0.08s ease-out,
35
+ width 0.3s ease-in-out,
36
+ height 0.3s ease-in-out,
37
+ margin 0.3s ease-in-out,
38
+ opacity 0.3s ease-in-out;
39
+
40
+ &.cursor-hover {
41
+ margin-left: -40px;
42
+ margin-top: -40px;
43
+ width: 80px;
44
+ height: 80px;
45
+ background-color: var(--color-primary-500);
46
+ opacity: 0.3;
47
+ }
48
+
49
+ &.cursor-text {
50
+ margin-left: -2px;
51
+ margin-top: -40px;
52
+ width: 4px;
53
+ height: 80px;
54
+ background-color: var(--color-primary-500);
55
+ opacity: 0.3;
56
+ }
57
+ }
58
+
59
+ &.inner-circle {
60
+ margin-left: -3px;
61
+ margin-top: -3px;
62
+ width: 6px;
63
+ height: 6px;
64
+ z-index: 99999999;
65
+ background-color: var(--color-primary-500);
66
+ transition: opacity 0.3s ease-in-out;
67
+ opacity: 1;
68
+
69
+ &.cursor-hover {
70
+ opacity: 0;
71
+ }
72
+ }
73
+ }
@@ -0,0 +1 @@
1
+ export * from './cursor.component';
@@ -0,0 +1,95 @@
1
+ import { useMemo } from 'react';
2
+ import { IconType } from 'react-icons';
3
+ import { IoCheckmarkOutline } from 'react-icons/io5';
4
+
5
+ import { useClassNames, useInputHandlers } from '../../../hooks';
6
+ import { ColorTypes, SizeTypes } from '../../component.types';
7
+ import { Typography } from '../../typography';
8
+ import { Controller } from '../controller';
9
+ import { ControllerGeneratorProps, UnControlledComponentProps } from '../form.types';
10
+
11
+ import './checkbox.styles.css';
12
+
13
+ type CheckboxProps = {
14
+ label?: React.ReactNode;
15
+ placeholder?: never;
16
+ icon?: IconType;
17
+ color?: `${ColorTypes}`;
18
+ size?: `${SizeTypes}`;
19
+ };
20
+
21
+ export const Checkbox = ({
22
+ name,
23
+ value,
24
+ setValue,
25
+ onBlur,
26
+ onFocus,
27
+ className = '',
28
+ style = {},
29
+ autoFocus = false,
30
+ readOnly = false,
31
+ disabled = false,
32
+ autoComplete = 'off',
33
+ icon: Icon = IoCheckmarkOutline,
34
+ label,
35
+ color = ColorTypes.PRIMARY,
36
+ size = SizeTypes.REGULAR,
37
+ /*
38
+ * isDirty = false,
39
+ * isTouched = false,
40
+ * invalid = false,
41
+ * error,
42
+ */
43
+ }: UnControlledComponentProps<CheckboxProps, boolean>) => {
44
+ const id = useMemo(() => crypto.randomUUID(), []);
45
+
46
+ const { handlers } = useInputHandlers<HTMLInputElement>({
47
+ onChange: e => setValue(e.target.checked),
48
+ onBlur: onBlur,
49
+ onFocus: onFocus,
50
+ });
51
+
52
+ const checkboxContainerClassName = useClassNames({
53
+ 'checkbox-container': true,
54
+ [className]: Boolean(className),
55
+ [`color-${color}`]: Boolean(color),
56
+ });
57
+
58
+ const checkboxClassName = useClassNames({
59
+ checkbox: true,
60
+ 'is-checked': value,
61
+ [`size-${size}`]: Boolean(size),
62
+ });
63
+
64
+ return (
65
+ <section className={checkboxContainerClassName} style={style} onClick={e => e.stopPropagation()}>
66
+ <section className={checkboxClassName}>
67
+ <section className='checkbox-fill'>
68
+ <Icon size='1.3em' className='checkbox-icon' />
69
+ </section>
70
+ <input
71
+ id={id}
72
+ type='checkbox'
73
+ name={name}
74
+ className='checkbox-input'
75
+ checked={value}
76
+ autoFocus={autoFocus}
77
+ autoComplete={autoComplete}
78
+ disabled={disabled || readOnly}
79
+ {...handlers}
80
+ />
81
+ </section>
82
+ {label ? (
83
+ <Typography variant='label-form' htmlFor={id} className='checkbox-label'>
84
+ {label}
85
+ </Typography>
86
+ ) : null}
87
+ </section>
88
+ );
89
+ };
90
+
91
+ const CheckboxController = ({ rules, ...props }: ControllerGeneratorProps<CheckboxProps, boolean>) => {
92
+ return <Controller Component={Checkbox} defaultValue={false} inputProps={props} rules={rules} />;
93
+ };
94
+
95
+ Checkbox.Controller = CheckboxController;
@@ -0,0 +1,162 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .checkbox {
4
+ border-radius: 40%;
5
+ background: var(--color-background-paper);
6
+ transition: all 300ms ease;
7
+ width: 1em;
8
+ height: 1em;
9
+ margin: 2px;
10
+ outline: 1px solid;
11
+ display: flex;
12
+ position: relative;
13
+
14
+ .checkbox-input {
15
+ position: absolute;
16
+ top: 0;
17
+ left: 0;
18
+ width: 100%;
19
+ height: 100%;
20
+ cursor: pointer;
21
+ opacity: 0;
22
+ z-index: 2;
23
+ }
24
+
25
+ &.size-small {
26
+ font-size: 1em;
27
+ }
28
+
29
+ &.size-regular {
30
+ font-size: 1.2em;
31
+ }
32
+
33
+ &.size-large {
34
+ font-size: 1.4em;
35
+ }
36
+ }
37
+
38
+ .checkbox-fill {
39
+ transition: all 200ms ease-out;
40
+ border-radius: inherit;
41
+ margin: auto;
42
+ width: 0;
43
+ height: 0;
44
+ overflow: hidden;
45
+ position: relative;
46
+ display: grid;
47
+ place-content: center;
48
+ place-items: center;
49
+
50
+ .checkbox-icon {
51
+ font-size: 0.7em;
52
+ z-index: 1;
53
+ opacity: 0;
54
+ transition: opacity 300ms ease;
55
+ }
56
+ }
57
+
58
+ .checkbox-container {
59
+ --color: var(--color-gray-800);
60
+ --color-icon: var(--color-gray-50);
61
+ --color-hover: hsl(from var(--color-gray-800) h s l / 50%);
62
+
63
+ display: grid;
64
+ grid-auto-flow: column;
65
+ grid-auto-columns: auto 1fr;
66
+ align-items: center;
67
+ gap: 0.5em;
68
+ width: fit-content;
69
+
70
+ .checkbox-label {
71
+ cursor: pointer;
72
+ user-select: none;
73
+ width: 100%;
74
+ }
75
+
76
+ .checkbox {
77
+ color: var(--color);
78
+
79
+ &.is-checked {
80
+ .checkbox-fill {
81
+ width: 100%;
82
+ height: 100%;
83
+ background: var(--color);
84
+ color: var(--color-icon);
85
+ }
86
+
87
+ .checkbox-icon {
88
+ opacity: 1;
89
+ }
90
+ }
91
+ }
92
+
93
+ .checkbox:hover,
94
+ &:has(.checkbox-label:hover) .checkbox {
95
+ box-shadow: 0 0 0 0.3em var(--color-hover);
96
+
97
+ .checkbox-fill {
98
+ width: 20%;
99
+ height: 20%;
100
+ border-radius: 20%;
101
+ background: var(--color-hover);
102
+ color: var(--color-icon);
103
+ }
104
+
105
+ &:is(.is-checked) {
106
+ .checkbox-fill {
107
+ width: 100%;
108
+ height: 100%;
109
+ border-radius: inherit;
110
+ background: var(--color);
111
+ }
112
+ }
113
+ }
114
+
115
+ .checkbox:focus,
116
+ &:has(.checkbox-input:focus) .checkbox,
117
+ &:has(.checkbox-label:focus) .checkbox {
118
+ box-shadow: 0 0 0 0.3em var(--color-hover);
119
+ }
120
+
121
+ &.color-primary {
122
+ --color: var(--color-primary-500);
123
+ --color-icon: var(--color-primary-50);
124
+ --color-hover: hsl(from var(--color-primary-500) h s l / 50%);
125
+ }
126
+
127
+ &.color-secondary {
128
+ --color: var(--color-secondary-500);
129
+ --color-icon: var(--color-secondary-50);
130
+ --color-hover: hsl(from var(--color-secondary-500) h s l / 50%);
131
+ }
132
+
133
+ &.color-tertiary {
134
+ --color: var(--color-tertiary-500);
135
+ --color-icon: var(--color-tertiary-50);
136
+ --color-hover: hsl(from var(--color-tertiary-500) h s l / 50%);
137
+ }
138
+
139
+ &.color-active {
140
+ --color: var(--color-active-500);
141
+ --color-icon: var(--color-active-50);
142
+ --color-hover: hsl(from var(--color-active-500) h s l / 50%);
143
+ }
144
+
145
+ &.color-warning {
146
+ --color: var(--color-warning-500);
147
+ --color-icon: var(--color-warning-50);
148
+ --color-hover: hsl(from var(--color-warning-500) h s l / 50%);
149
+ }
150
+
151
+ &.color-alert {
152
+ --color: var(--color-alert-500);
153
+ --color-icon: var(--color-alert-50);
154
+ --color-hover: hsl(from var(--color-alert-500) h s l / 50%);
155
+ }
156
+
157
+ &.color-info {
158
+ --color: var(--color-info-500);
159
+ --color-icon: var(--color-info-50);
160
+ --color-hover: hsl(from var(--color-info-500) h s l / 50%);
161
+ }
162
+ }
@@ -0,0 +1 @@
1
+ export * from './checkbox.component';
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { Controller as RHFController, useFormContext, UseControllerProps } from 'react-hook-form';
3
+
4
+ import { ControlledComponentProps, Props, UnControlledComponentProps } from '../form.types';
5
+
6
+ type ControllerProps<T extends Props, V> = {
7
+ inputProps: ControlledComponentProps<T, V>;
8
+ Component: React.FC<UnControlledComponentProps<T, V>>;
9
+ rules?: UseControllerProps['rules'];
10
+ defaultValue: V;
11
+ };
12
+
13
+ export const Controller = <T extends Props, V>({
14
+ Component,
15
+ inputProps,
16
+ defaultValue: fieldDefaultValue,
17
+ rules,
18
+ }: ControllerProps<T, V>) => {
19
+ const { control, setValue } = useFormContext();
20
+ const { name, defaultValue } = inputProps;
21
+
22
+ return (
23
+ <RHFController
24
+ name={name}
25
+ control={control}
26
+ rules={rules}
27
+ defaultValue={defaultValue ?? fieldDefaultValue}
28
+ render={({ field: { onBlur, value }, fieldState }) => (
29
+ <Component
30
+ value={value}
31
+ error={fieldState.error?.message}
32
+ invalid={fieldState.invalid}
33
+ isTouched={fieldState.isTouched}
34
+ isDirty={fieldState.isDirty}
35
+ setValue={value => setValue(name, value)}
36
+ onBlur={onBlur}
37
+ {...inputProps}
38
+ />
39
+ )}
40
+ />
41
+ );
42
+ };
@@ -0,0 +1 @@
1
+ export * from './controller.component';
@@ -0,0 +1,66 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import { useInputHandlers } from '../../../hooks';
4
+ import { Controller } from '../controller';
5
+ import { Field, InputFieldProps } from '../field';
6
+ import { ControllerGeneratorProps, UnControlledComponentProps } from '../form.types';
7
+
8
+ type DatePickerProps = InputFieldProps<{
9
+ type?: 'date' | 'datetime-local' | 'month' | 'time' | 'week';
10
+ }>;
11
+
12
+ export const DatePicker = ({
13
+ name,
14
+ value,
15
+ setValue,
16
+ onBlur,
17
+ onFocus,
18
+ type = 'date',
19
+ className = '',
20
+ style = {},
21
+ autoFocus = false,
22
+ readOnly = false,
23
+ disabled = false,
24
+ placeholder = '',
25
+ autoComplete = 'off',
26
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
+ isDirty = false,
28
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
+ isTouched = false,
30
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
31
+ invalid = false,
32
+ error,
33
+ ...fieldProps
34
+ }: UnControlledComponentProps<DatePickerProps, string>) => {
35
+ const id = useMemo(() => crypto.randomUUID(), []);
36
+ const { isFocus, handlers } = useInputHandlers({
37
+ onBlur: onBlur,
38
+ onChange: e => setValue(e.target.value),
39
+ onFocus: onFocus,
40
+ });
41
+
42
+ return (
43
+ <Field id={id} error={error} isFocus={isFocus} {...fieldProps}>
44
+ <input
45
+ id={id}
46
+ type={type}
47
+ name={name}
48
+ className={className}
49
+ style={style}
50
+ value={value}
51
+ autoFocus={autoFocus}
52
+ autoComplete={autoComplete}
53
+ placeholder={placeholder}
54
+ disabled={disabled}
55
+ readOnly={readOnly}
56
+ {...handlers}
57
+ />
58
+ </Field>
59
+ );
60
+ };
61
+
62
+ const DatePickerController = ({ rules, ...props }: ControllerGeneratorProps<DatePickerProps, string>) => {
63
+ return <Controller Component={DatePicker} defaultValue='' inputProps={props} rules={rules} />;
64
+ };
65
+
66
+ DatePicker.Controller = DatePickerController;
@@ -0,0 +1 @@
1
+ export * from './date-picker.component';
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import { IconType } from 'react-icons';
3
+ import { ImCross } from 'react-icons/im';
4
+
5
+ import { useClassNames } from '../../../hooks';
6
+ import { Typography } from '../../typography';
7
+
8
+ import './field.styles.css';
9
+ import { FieldOrientation, FieldProps, FieldVariant } from './field.types';
10
+
11
+ type GetIconParams = {
12
+ icon?: IconType;
13
+ onClick: (e: React.MouseEvent) => void;
14
+ className: string;
15
+ };
16
+
17
+ const getIcon = ({ icon: Icon, className, onClick }: GetIconParams) =>
18
+ Icon ? <Icon className={className} onClick={onClick} /> : <span />;
19
+
20
+ export const Field = ({
21
+ id,
22
+ label,
23
+ leftIcon,
24
+ rightIcon,
25
+ errorIcon: ErrorIcon = ImCross,
26
+ error,
27
+ onClickLeftIcon,
28
+ onClickRightIcon,
29
+ fieldOrientation = FieldOrientation.VERTICAL,
30
+ children,
31
+ isFocus = false,
32
+ variant,
33
+ ref,
34
+ }: FieldProps) => {
35
+ const fieldClassName = useClassNames({
36
+ 'form-field': true,
37
+ focus: isFocus,
38
+ error: !!error,
39
+ 'variant-content-border': variant === FieldVariant.CONTENT_BORDER,
40
+ 'variant-content-line': variant === FieldVariant.CONTENT_LINE,
41
+ 'variant-full-border': variant === FieldVariant.FULL_BORDER,
42
+ 'variant-inline': fieldOrientation === FieldOrientation.HORIZONTAL,
43
+ });
44
+
45
+ const handleClick = (callback?: () => void) => (e: React.MouseEvent) => {
46
+ e.stopPropagation();
47
+ const input = document.getElementById(id);
48
+ input?.focus();
49
+ input?.click();
50
+
51
+ if (callback) callback();
52
+ };
53
+
54
+ return (
55
+ <section className={fieldClassName} ref={ref}>
56
+ {label ? (
57
+ <Typography className='field-label' noPadding variant='label-form' htmlFor={id}>
58
+ {label}
59
+ </Typography>
60
+ ) : null}
61
+ <section className='field-content'>
62
+ {getIcon({
63
+ className: 'field-left-icon',
64
+ icon: leftIcon,
65
+ onClick: handleClick(onClickLeftIcon),
66
+ })}
67
+ <section className='field-children'>{children}</section>
68
+ {getIcon({
69
+ className: 'field-right-icon',
70
+ icon: rightIcon,
71
+ onClick: handleClick(onClickRightIcon),
72
+ })}
73
+ </section>
74
+ {Boolean(error) && (
75
+ <section className='field-message'>
76
+ {ErrorIcon ? <ErrorIcon size={10} /> : <span />}
77
+ <Typography noPadding variant='small'>
78
+ {error}
79
+ </Typography>
80
+ </section>
81
+ )}
82
+ </section>
83
+ );
84
+ };
@@ -0,0 +1,98 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .form-field {
4
+ display: grid;
5
+ grid-auto-columns: auto;
6
+ gap: 0.5em;
7
+ transition: all 200ms ease;
8
+
9
+ .field-content {
10
+ display: grid;
11
+ grid-template-columns: auto 1fr auto;
12
+ align-items: center;
13
+ }
14
+
15
+ .field-left-icon,
16
+ .field-right-icon {
17
+ font-size: 1em;
18
+ }
19
+
20
+ .field-left-icon {
21
+ margin-right: 1em;
22
+ }
23
+
24
+ .field-right-icon {
25
+ margin-left: 1em;
26
+ }
27
+
28
+ .field-message {
29
+ display: grid;
30
+ grid-auto-flow: column;
31
+ gap: 5px;
32
+ align-items: center;
33
+ justify-content: start;
34
+ }
35
+
36
+ &.variant-content-border {
37
+ .field-content {
38
+ border: 1px solid var(--color-border);
39
+ border-radius: 4px;
40
+ padding: 1em;
41
+ background: var(--color-background);
42
+ }
43
+ }
44
+
45
+ &.variant-content-line {
46
+ .field-content {
47
+ border-bottom: 1px solid;
48
+ padding: 0.5em 0;
49
+ }
50
+ }
51
+
52
+ &.variant-full-border {
53
+ border: 1px solid var(--color-border);
54
+ border-radius: 4px;
55
+ padding: 0.5em 0;
56
+ background: var(--color-background);
57
+
58
+ .field-label,
59
+ .field-content,
60
+ .field-message {
61
+ padding: 0 1em;
62
+ }
63
+ }
64
+
65
+ &.variant-inline {
66
+ grid-auto-flow: column;
67
+ padding: 0.5em 0;
68
+ align-items: center;
69
+
70
+ .field-label {
71
+ width: auto;
72
+ }
73
+ }
74
+
75
+ &.error {
76
+ color: var(--color-alert-500);
77
+ border-color: var(--color-alert-500);
78
+ }
79
+
80
+ &.focus {
81
+ color: var(--color-info-500);
82
+ border-color: var(--color-info-500);
83
+ }
84
+
85
+ &.error,
86
+ &.focus {
87
+ .field-left-icon,
88
+ .field-right-icon,
89
+ .field-children {
90
+ color: var(--color-foreground);
91
+ border-color: var(--color-foreground);
92
+ }
93
+ }
94
+
95
+ .field-children > * {
96
+ width: 100%;
97
+ }
98
+ }
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { IconType } from 'react-icons';
3
+
4
+ export enum FieldVariant {
5
+ FULL_BORDER = 'full-border',
6
+ CONTENT_BORDER = 'content-border',
7
+ CONTENT_LINE = 'line',
8
+ }
9
+
10
+ export enum FieldOrientation {
11
+ HORIZONTAL = 'horizontal',
12
+ VERTICAL = 'vertical',
13
+ }
14
+
15
+ type FieldSharedProps = {
16
+ rightIcon?: IconType;
17
+ leftIcon?: IconType;
18
+ errorIcon?: IconType;
19
+ onClickLeftIcon?: () => void;
20
+ onClickRightIcon?: () => void;
21
+ label?: string;
22
+ variant?: `${FieldVariant}`;
23
+ ref?: React.RefObject<HTMLElement | null>;
24
+ };
25
+
26
+ export type FieldProps = FieldSharedProps & {
27
+ children: React.ReactNode;
28
+ id: string;
29
+ error?: string;
30
+ isFocus?: boolean;
31
+ fieldOrientation?: `${FieldOrientation}`;
32
+ };
33
+
34
+ export type InputFieldProps<T> = T & FieldSharedProps;
@@ -0,0 +1,2 @@
1
+ export * from './field.component';
2
+ export * from './field.types';