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,64 @@
1
+ import React, { useCallback, useEffect, useLayoutEffect, useMemo } from 'react';
2
+
3
+ export enum ModalState {
4
+ OPENING = 'OPENING',
5
+ OPEN = 'OPEN',
6
+ CLOSING = 'CLOSING',
7
+ CLOSED = 'CLOSED',
8
+ }
9
+
10
+ export type UseModalTransitionParams = {
11
+ transitionDuration?: number;
12
+ isOpen: boolean;
13
+ };
14
+
15
+ export const useModalTransition = ({ transitionDuration = 0, isOpen }: UseModalTransitionParams) => {
16
+ const [modalState, setModalState] = React.useState<ModalState>(ModalState.CLOSED);
17
+
18
+ const isVisible = useMemo(() => {
19
+ return modalState !== ModalState.CLOSED;
20
+ }, [modalState]);
21
+
22
+ useEffect(() => {
23
+ document.documentElement.style.overflow = isVisible ? 'hidden' : 'auto';
24
+ }, [isVisible]);
25
+
26
+ const closeModal = useCallback(() => {
27
+ if ([ModalState.OPENING, ModalState.OPEN].includes(modalState)) {
28
+ if (transitionDuration > 0) {
29
+ setModalState(ModalState.CLOSING);
30
+ setTimeout(() => {
31
+ setModalState(ModalState.CLOSED);
32
+ }, transitionDuration);
33
+ } else {
34
+ setModalState(ModalState.CLOSED);
35
+ }
36
+ }
37
+ }, [modalState, transitionDuration]);
38
+
39
+ const openModal = useCallback(() => {
40
+ if ([ModalState.CLOSING, ModalState.CLOSED].includes(modalState)) {
41
+ if (transitionDuration > 0) {
42
+ setModalState(ModalState.OPENING);
43
+ setTimeout(() => {
44
+ setModalState(ModalState.OPEN);
45
+ }, transitionDuration);
46
+ } else {
47
+ setModalState(ModalState.OPEN);
48
+ }
49
+ }
50
+ }, [modalState, transitionDuration]);
51
+
52
+ useLayoutEffect(() => {
53
+ if (modalState === ModalState.CLOSED && isOpen) {
54
+ openModal();
55
+ } else if (modalState === ModalState.OPEN && !isOpen) {
56
+ closeModal();
57
+ }
58
+ }, [isOpen, openModal, closeModal, modalState]);
59
+
60
+ return {
61
+ isVisible,
62
+ modalState,
63
+ };
64
+ };
@@ -0,0 +1,21 @@
1
+ import { useRef, useState } from 'react';
2
+
3
+ export const useModal = <T extends HTMLElement>() => {
4
+ const containerRef = useRef<T>(null);
5
+ const [isOpen, setIsOpen] = useState(false);
6
+
7
+ const openModal = () => {
8
+ setIsOpen(true);
9
+ };
10
+
11
+ const closeModal = () => {
12
+ setIsOpen(false);
13
+ };
14
+
15
+ return {
16
+ containerRef,
17
+ isOpen,
18
+ openModal,
19
+ closeModal,
20
+ };
21
+ };
@@ -0,0 +1,64 @@
1
+ import React, { useRef, useState } from 'react';
2
+
3
+ import { useEventListener } from './use-event-listener';
4
+
5
+ type MousePosition = {
6
+ x: null | number;
7
+ y: null | number;
8
+ elementX: number | null;
9
+ elementY: number | null;
10
+ elementPositionX: number | null;
11
+ elementPositionY: number | null;
12
+ };
13
+
14
+ const getMousePosition = (domRect: DOMRect, e: MouseEvent) => {
15
+ const { left, top } = domRect;
16
+ const containerPositionX = left + window.scrollX;
17
+ const containerPositionY = top + window.scrollY;
18
+ const containerX = e.pageX - containerPositionX;
19
+ const containerY = e.pageY - containerPositionY;
20
+
21
+ return {
22
+ x: e.pageX,
23
+ y: e.pageY,
24
+ elementX: containerX,
25
+ elementY: containerY,
26
+ elementPositionX: containerPositionX,
27
+ elementPositionY: containerPositionY,
28
+ };
29
+ };
30
+
31
+ export const useMousePosition = (containerRef?: React.RefObject<HTMLElement | SVGElement | null>) => {
32
+ const ref = useRef<HTMLElement>(null);
33
+ const [position, setPosition] = useState<MousePosition>({
34
+ x: null,
35
+ y: null,
36
+ elementX: null,
37
+ elementY: null,
38
+ elementPositionX: null,
39
+ elementPositionY: null,
40
+ });
41
+
42
+ const mouseMove = (e: MouseEvent) => {
43
+ const { clientX, clientY } = e;
44
+ setPosition(prev => ({ ...prev, x: clientX, y: clientY }));
45
+
46
+ if (containerRef?.current instanceof Element) {
47
+ const newState = getMousePosition(containerRef.current.getBoundingClientRect(), e);
48
+ setPosition(prev => ({
49
+ ...prev,
50
+ ...newState,
51
+ }));
52
+ } else if (ref.current instanceof Element) {
53
+ const newState = getMousePosition(ref.current.getBoundingClientRect(), e);
54
+ setPosition(prev => ({
55
+ ...prev,
56
+ ...newState,
57
+ }));
58
+ }
59
+ };
60
+
61
+ useEventListener('mousemove', mouseMove);
62
+
63
+ return { ...position, ref };
64
+ };
@@ -0,0 +1,12 @@
1
+ import { useState } from 'react';
2
+
3
+ import { useEventListener } from './use-event-listener';
4
+
5
+ export const useOnlineStatus = () => {
6
+ const [online, setOnline] = useState(navigator.onLine);
7
+
8
+ useEventListener('online', () => setOnline(navigator.onLine));
9
+ useEventListener('offline', () => setOnline(navigator.onLine));
10
+
11
+ return online;
12
+ };
@@ -0,0 +1,11 @@
1
+ import { useEffect, useRef } from 'react';
2
+
3
+ export const useRenderCount = () => {
4
+ const count = useRef(1);
5
+
6
+ useEffect(() => {
7
+ count.current++;
8
+ });
9
+
10
+ return count.current;
11
+ };
@@ -0,0 +1,18 @@
1
+ import { RefObject, useEffect } from 'react';
2
+
3
+ export const useResizeObserver = <T extends Element>(
4
+ ref: RefObject<T | null> | Array<RefObject<T | null>>,
5
+ callback: ResizeObserverCallback,
6
+ ) => {
7
+ useEffect(() => {
8
+ const refs = Array.isArray(ref) ? ref : [ref];
9
+
10
+ const observer = new ResizeObserver(callback);
11
+
12
+ refs.forEach(r => r.current && observer.observe(r.current));
13
+
14
+ return () => {
15
+ observer.disconnect();
16
+ };
17
+ }, [ref, callback]);
18
+ };
@@ -0,0 +1,22 @@
1
+ import React, { useCallback, useLayoutEffect, useRef } from 'react';
2
+
3
+ export const useSafeDispatch = <T>(dispatch: React.Dispatch<T>): ((action: T) => void) => {
4
+ const mounted = useRef(false);
5
+
6
+ useLayoutEffect(() => {
7
+ mounted.current = true;
8
+
9
+ return () => {
10
+ mounted.current = false;
11
+ };
12
+ }, []);
13
+
14
+ return useCallback(
15
+ (...args: Parameters<React.Dispatch<T>>) => {
16
+ if (mounted.current) {
17
+ dispatch(...args);
18
+ }
19
+ },
20
+ [dispatch],
21
+ );
22
+ };
@@ -0,0 +1,31 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+
3
+ export const useScroll = () => {
4
+ const ref = useRef<HTMLElement>(null);
5
+ const [position, setPosition] = useState([0, 0]);
6
+
7
+ useEffect(() => {
8
+ const element = ref.current;
9
+
10
+ const handleScroll = () => {
11
+ if (!element) return;
12
+
13
+ setPosition([element.scrollLeft, element.scrollTop]);
14
+ };
15
+
16
+ if (element) {
17
+ element.addEventListener('scroll', handleScroll);
18
+ }
19
+
20
+ return () => {
21
+ if (element) {
22
+ element.removeEventListener('scroll', handleScroll);
23
+ }
24
+ };
25
+ }, []);
26
+
27
+ return {
28
+ ref,
29
+ position,
30
+ };
31
+ };
@@ -0,0 +1,22 @@
1
+ import { Dispatch, SetStateAction, useEffect, useState } from 'react';
2
+
3
+ function useStateHistory<T>(initialState: T | (() => T)): [T, Dispatch<SetStateAction<T>>, Array<T>];
4
+
5
+ function useStateHistory<T = undefined>(): [T | undefined, Dispatch<SetStateAction<T | undefined>>, Array<T>];
6
+
7
+ function useStateHistory<T = undefined>(
8
+ initialState?: T | (() => T) | undefined,
9
+ ): [T | undefined, Dispatch<SetStateAction<T | undefined>>, Array<T>] {
10
+ const [state, setState] = useState<T | undefined>(initialState);
11
+ const [history, setHistory] = useState<Array<T>>([]);
12
+
13
+ useEffect(() => {
14
+ if (state !== undefined) {
15
+ setHistory(prevHistory => [...prevHistory, state]);
16
+ }
17
+ }, [state]);
18
+
19
+ return [state, setState, history];
20
+ }
21
+
22
+ export { useStateHistory };
@@ -0,0 +1,14 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ export const useToggleValues = <T>(values: Array<T>, defaultIndex: number = 0): [T, (index?: number) => void] => {
4
+ const [index, setIndex] = useState(defaultIndex);
5
+
6
+ const toggle = useCallback(
7
+ (index?: number) => {
8
+ setIndex(index !== undefined ? index : prev => (prev + 1) % values.length);
9
+ },
10
+ [values.length],
11
+ );
12
+
13
+ return [values[index], toggle];
14
+ };
@@ -0,0 +1,11 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ export const useToggle = (defaultValue: boolean = false) => {
4
+ const [value, setValue] = useState<boolean>(defaultValue);
5
+
6
+ const toggle = useCallback(() => {
7
+ setValue(prev => !prev);
8
+ }, []);
9
+
10
+ return [value, toggle, setValue];
11
+ };
@@ -0,0 +1,38 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ import { useEventListener } from './use-event-listener';
4
+
5
+ enum ScreenOrientation {
6
+ PORTRAIT = 'portrait',
7
+ LANDSCAPE = 'landscape',
8
+ }
9
+
10
+ type UseViewportData = {
11
+ width: number;
12
+ height: number;
13
+ orientation: ScreenOrientation;
14
+ };
15
+
16
+ export const useViewport = (): UseViewportData => {
17
+ const getData = (): UseViewportData => {
18
+ const { innerWidth, innerHeight } = window;
19
+
20
+ return {
21
+ width: innerWidth,
22
+ height: innerHeight,
23
+ orientation: innerWidth > innerHeight ? ScreenOrientation.LANDSCAPE : ScreenOrientation.PORTRAIT,
24
+ };
25
+ };
26
+
27
+ const [data, setData] = useState<UseViewportData>(getData);
28
+
29
+ useEventListener('resize', () => {
30
+ setData(getData());
31
+ });
32
+
33
+ useEffect(() => {
34
+ setData(getData());
35
+ }, []);
36
+
37
+ return data;
38
+ };
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './hooks';
2
+ export * from './types';
3
+ export * from './helpers';
4
+ export * from './layouts';
5
+ export * from './components';
@@ -0,0 +1,75 @@
1
+ import React, { createElement } from 'react';
2
+
3
+ type FlexProps = {
4
+ tag?: React.HTMLElementType;
5
+ children?: React.ReactNode;
6
+ className?: string;
7
+ style?: React.CSSProperties;
8
+ direction?: React.CSSProperties['flexDirection'];
9
+ wrap?: React.CSSProperties['flexWrap'];
10
+ basis?: React.CSSProperties['flexBasis'];
11
+ grow?: React.CSSProperties['flexGrow'];
12
+ shrink?: React.CSSProperties['flexShrink'];
13
+ flow?: React.CSSProperties['flexFlow'];
14
+ pc?: React.CSSProperties['placeContent'];
15
+ pi?: React.CSSProperties['placeItems'];
16
+ ps?: React.CSSProperties['placeSelf'];
17
+ jc?: React.CSSProperties['justifyContent'];
18
+ ji?: React.CSSProperties['justifyItems'];
19
+ js?: React.CSSProperties['justifySelf'];
20
+ ac?: React.CSSProperties['alignContent'];
21
+ ai?: React.CSSProperties['alignItems'];
22
+ as?: React.CSSProperties['alignSelf'];
23
+ gap?: React.CSSProperties['gap'];
24
+ };
25
+
26
+ export const Flex = ({
27
+ tag = 'section',
28
+ children,
29
+ className,
30
+ style,
31
+ direction,
32
+ wrap,
33
+ basis,
34
+ grow,
35
+ shrink,
36
+ flow,
37
+ pc,
38
+ pi,
39
+ ps,
40
+ jc,
41
+ ji,
42
+ js,
43
+ ac,
44
+ ai,
45
+ as,
46
+ gap,
47
+ }: FlexProps) => {
48
+ return createElement(
49
+ tag,
50
+ {
51
+ className,
52
+ style: {
53
+ ...style,
54
+ ...(direction ? { flexDirection: direction } : {}),
55
+ ...(wrap ? { flexWrap: wrap } : {}),
56
+ ...(basis ? { flexBasis: basis } : {}),
57
+ ...(grow ? { flexGrow: grow } : {}),
58
+ ...(shrink ? { flexShrink: shrink } : {}),
59
+ ...(flow ? { flexFlow: flow } : {}),
60
+ ...(pc ? { placeContent: pc } : {}),
61
+ ...(pi ? { placeItems: pi } : {}),
62
+ ...(ps ? { placeSelf: ps } : {}),
63
+ ...(jc ? { justifyContent: jc } : {}),
64
+ ...(ji ? { justifyItems: ji } : {}),
65
+ ...(js ? { justifySelf: js } : {}),
66
+ ...(ac ? { alignContent: ac } : {}),
67
+ ...(ai ? { alignItems: ai } : {}),
68
+ ...(as ? { alignSelf: as } : {}),
69
+ ...(gap ? { gap: gap } : {}),
70
+ display: 'flex',
71
+ },
72
+ },
73
+ children,
74
+ );
75
+ };
@@ -0,0 +1 @@
1
+ export * from './flex.component';
@@ -0,0 +1,89 @@
1
+ import React, { createElement } from 'react';
2
+
3
+ import './grid.styles.css';
4
+
5
+ type GridProps = React.HTMLAttributes<HTMLDivElement> & {
6
+ tag?: React.HTMLElementType;
7
+ children?: React.ReactNode;
8
+ className?: string;
9
+ style?: React.CSSProperties;
10
+ flow?: React.CSSProperties['gridAutoFlow'];
11
+ columnSize?: React.CSSProperties['gridAutoColumns'];
12
+ rowSize?: React.CSSProperties['gridAutoRows'];
13
+ column?: React.CSSProperties['gridColumn'];
14
+ row?: React.CSSProperties['gridRow'];
15
+ pc?: React.CSSProperties['placeContent'];
16
+ pi?: React.CSSProperties['placeItems'];
17
+ ps?: React.CSSProperties['placeSelf'];
18
+ jc?: React.CSSProperties['justifyContent'];
19
+ ji?: React.CSSProperties['justifyItems'];
20
+ js?: React.CSSProperties['justifySelf'];
21
+ ac?: React.CSSProperties['alignContent'];
22
+ ai?: React.CSSProperties['alignItems'];
23
+ as?: React.CSSProperties['alignSelf'];
24
+ gtc?: React.CSSProperties['gridTemplateColumns'];
25
+ gtr?: React.CSSProperties['gridTemplateRows'];
26
+ gta?: React.CSSProperties['gridTemplateAreas'];
27
+ gt?: React.CSSProperties['gridTemplate'];
28
+ gap?: React.CSSProperties['gap'];
29
+ ref?: React.Ref<HTMLElement>;
30
+ };
31
+
32
+ export const Grid = ({
33
+ tag = 'section',
34
+ children,
35
+ className,
36
+ style,
37
+ flow,
38
+ columnSize,
39
+ rowSize,
40
+ column,
41
+ row,
42
+ pc,
43
+ pi,
44
+ ps,
45
+ jc,
46
+ ji,
47
+ js,
48
+ ac,
49
+ ai,
50
+ as,
51
+ gtc,
52
+ gtr,
53
+ gta,
54
+ gt,
55
+ gap,
56
+ ...props
57
+ }: GridProps) => {
58
+ return createElement(
59
+ tag,
60
+ {
61
+ className,
62
+ ...props,
63
+ style: {
64
+ ...style,
65
+ ...(flow ? { gridAutoFlow: flow } : {}),
66
+ ...(columnSize ? { gridAutoColumns: columnSize } : {}),
67
+ ...(rowSize ? { gridAutoRows: rowSize } : {}),
68
+ ...(column ? { gridColumn: column } : {}),
69
+ ...(row ? { gridRow: row } : {}),
70
+ ...(pc ? { placeContent: pc } : {}),
71
+ ...(pi ? { placeItems: pi } : {}),
72
+ ...(ps ? { placeSelf: ps } : {}),
73
+ ...(jc ? { justifyContent: jc } : {}),
74
+ ...(ji ? { justifyItems: ji } : {}),
75
+ ...(js ? { justifySelf: js } : {}),
76
+ ...(ac ? { alignContent: ac } : {}),
77
+ ...(ai ? { alignItems: ai } : {}),
78
+ ...(as ? { alignSelf: as } : {}),
79
+ ...(gtc ? { gridTemplateColumns: gtc } : {}),
80
+ ...(gtr ? { gridTemplateRows: gtr } : {}),
81
+ ...(gta ? { gridTemplateAreas: gta } : {}),
82
+ ...(gt ? { gridTemplate: gt } : {}),
83
+ ...(gap ? { gap: gap } : {}),
84
+ display: 'grid',
85
+ },
86
+ },
87
+ children,
88
+ );
89
+ };
@@ -0,0 +1,5 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .grida {
4
+ display: grid;
5
+ }
@@ -0,0 +1 @@
1
+ export * from './grid.component';
@@ -0,0 +1,2 @@
1
+ export * from './flex';
2
+ export * from './grid';
@@ -0,0 +1,68 @@
1
+ /*
2
+ *KeyValuesOf
3
+ *
4
+ *Description:
5
+ * This generic type extract specific attributes from an object type, this is
6
+ * useful when you are creating a component with a generic type, and then you
7
+ * want to add a prop that only could receive specific attributes from that
8
+ * generic object.
9
+ *
10
+ * Example:
11
+ * - select.tsx
12
+ *
13
+ * type SelectProps<T> = {
14
+ * options: Array<T>;
15
+ * renderAttribute: KeyValuesOf<T, string>; // <---- Only allow string attributes from T
16
+ * }
17
+ *
18
+ * const Select = <T,>(props: SelectProps<T>) => { ... }
19
+ *
20
+ * - user.entities.ts
21
+ *
22
+ * type UserProfileEntity = {
23
+ * picture: string;
24
+ * website: string;
25
+ * };
26
+ *
27
+ * type UserEntity = {
28
+ * name: string;
29
+ * lastname: string;
30
+ * age: number;
31
+ * profile: UserProfileEntity;
32
+ * }
33
+ *
34
+ * - page.tsx
35
+ *
36
+ * import { Select } from './components';
37
+ * import { UserEntity } from './user.entities';
38
+ *
39
+ * <Select<UserEntity>
40
+ * options={options}
41
+ * renderAttribute='name' // <---- Only allow 'name | lastname'
42
+ * />
43
+ *
44
+ *Params:
45
+ * T: Object or map Type with keys
46
+ * V: Type to extract from T
47
+ *
48
+ *Example:
49
+ * Input: KeyValuesOf<UserEntity, string>
50
+ * Output: name | lastname
51
+ *
52
+ * Input: KeyValuesOf<UserEntity, number>
53
+ * Output: age
54
+ *
55
+ * Input: KeyValuesOf<UserEntity, string | number>
56
+ * Output: name | lastname | age
57
+ *
58
+ * Input: KeyValuesOf<UserEntity, UserProfileEntity>
59
+ * Output: profile
60
+ *
61
+ */
62
+ export type KeyValuesOf<T, V> = {
63
+ [P in keyof T]-?: T[P] extends V ? P : never;
64
+ }[keyof T];
65
+
66
+ export type DeepPartial<T> = {
67
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
68
+ };
@@ -0,0 +1 @@
1
+ export * from './generics';
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "polpo-typescript-config/react-library",
3
+ "include": ["src"],
4
+ "exclude": ["node_modules", "dist"],
5
+ "compilerOptions": {
6
+ "rootDir": ".",
7
+ "outDir": "dist",
8
+ "baseUrl": "src"
9
+ }
10
+ }
@@ -0,0 +1,36 @@
1
+ import postcss from 'esbuild-postcss';
2
+ import { defineConfig } from 'tsup';
3
+
4
+ export default defineConfig([
5
+ {
6
+ entry: {
7
+ components: './src/components/index.ts',
8
+ hooks: './src/hooks/index.ts',
9
+ layouts: './src/layouts/index.ts',
10
+ types: './src/types/index.ts',
11
+ helpers: './src/helpers/index.ts',
12
+ },
13
+ outDir: './dist',
14
+ dts: true,
15
+ bundle: true,
16
+ minify: true,
17
+ sourcemap: false,
18
+ target: 'node24',
19
+ format: ['cjs', 'esm'],
20
+ banner: {
21
+ js: '"use client";',
22
+ },
23
+ clean: true,
24
+ splitting: false,
25
+ esbuildTarget: 'esnext',
26
+ external: ['react', 'react-dom'],
27
+ globals: {
28
+ react: 'React',
29
+ 'react-dom': 'ReactDOM',
30
+ },
31
+ esbuildPlugins: [postcss()],
32
+ esbuildOptions: options => {
33
+ options.packages = 'external';
34
+ },
35
+ },
36
+ ]);