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,164 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .tab {
4
+ cursor: pointer;
5
+ user-select: none;
6
+ transition: all 300ms ease;
7
+ }
8
+
9
+ .tab-list {
10
+ --color: var(--color-gray-900);
11
+ --color-contrast: var(--color-gray-50);
12
+ --inner-radius: 0;
13
+ --outer-radius: 0;
14
+
15
+ display: grid;
16
+ grid-auto-flow: column;
17
+ gap: 1em;
18
+ align-items: center;
19
+ position: relative;
20
+ @apply text-label;
21
+ border-radius: var(--outer-radius);
22
+
23
+ .tab, .tabs-selector {
24
+ border-radius: var(--inner-radius);
25
+ }
26
+
27
+ &.size-small {
28
+ @apply text-small;
29
+ }
30
+
31
+ &.size-medium {
32
+ @apply text-label;
33
+ }
34
+
35
+ &.size-large {
36
+ @apply text-body;
37
+ }
38
+
39
+ .tabs-selector {
40
+ position: absolute;
41
+ background: var(--color);
42
+ color: var(--color-contrast);
43
+ border-radius: 1.5em;
44
+
45
+ &.active {
46
+ transition: all 300ms ease;
47
+ }
48
+ }
49
+
50
+ .tab {
51
+ border-radius: 1.5em;
52
+ padding: 0.5em 1em;
53
+ z-index: 1;
54
+ text-align: center;
55
+
56
+ &.is-open {
57
+ color: var(--color-contrast);
58
+ }
59
+
60
+ &:not(.is-open):hover {
61
+ color: var(--color-gray-900);
62
+ }
63
+ }
64
+
65
+ &.radius-none {
66
+ --outer-radius: 0;
67
+ --inner-radius: 0;
68
+ }
69
+
70
+ &.radius-small {
71
+ --outer-radius: 0.5em;
72
+ --inner-radius: 0.5em;
73
+ }
74
+
75
+ &.radius-medium {
76
+ --outer-radius: 1em;
77
+ --inner-radius: 0.8em;
78
+ }
79
+
80
+ &.radius-large {
81
+ --outer-radius: 1.5em;
82
+ --inner-radius: 1.3em;
83
+ }
84
+
85
+ &.radius-full {
86
+ --outer-radius: 1.8em;
87
+ --inner-radius: 1.6em;
88
+ }
89
+
90
+ &.vertical-direction {
91
+ grid-auto-flow: row;
92
+ align-items: unset;
93
+ align-content: start;
94
+ }
95
+
96
+ &.variant-solid {
97
+ background: var(--color-background-paper);
98
+ color: var(--color-foreground);
99
+ padding: 0.5em;
100
+ }
101
+
102
+ &.variant-ghost {
103
+ border: 1px solid var(--color);
104
+ padding: 0.5em;
105
+ }
106
+
107
+ &.variant-flat {
108
+ }
109
+
110
+ &.variant-line {
111
+ border-radius: 0;
112
+
113
+ &:not(.vertical-direction) {
114
+ border-bottom: 2px solid var(--color-border);
115
+ }
116
+
117
+ .tabs-selector {
118
+ border-radius: 0;
119
+ }
120
+
121
+ .tab {
122
+ border-radius: 0;
123
+
124
+ &.is-open {
125
+ color: var(--color);
126
+ }
127
+ }
128
+ }
129
+
130
+ &.color-primary {
131
+ --color: var(--color-primary-500);
132
+ --color-contrast: var(--color-primary-50);
133
+ }
134
+
135
+ &.color-secondary {
136
+ --color: var(--color-secondary-500);
137
+ --color-contrast: var(--color-secondary-50);
138
+ }
139
+
140
+ &.color-tertiary {
141
+ --color: var(--color-tertiary-500);
142
+ --color-contrast: var(--color-tertiary-50);
143
+ }
144
+
145
+ &.color-active {
146
+ --color: var(--color-active-500);
147
+ --color-contrast: var(--color-active-50);
148
+ }
149
+
150
+ &.color-warning {
151
+ --color: var(--color-warning-500);
152
+ --color-contrast: var(--color-warning-50);
153
+ }
154
+
155
+ &.color-alert {
156
+ --color: var(--color-alert-500);
157
+ --color-contrast: var(--color-alert-50);
158
+ }
159
+
160
+ &.color-info {
161
+ --color: var(--color-info-500);
162
+ --color-contrast: var(--color-info-50);
163
+ }
164
+ }
@@ -0,0 +1,119 @@
1
+ import React, { createContext, useContext, useEffect, useState } from 'react';
2
+
3
+ import { useClassNames } from '../../hooks';
4
+
5
+ import { TabsList as TabListComponent, TabListProps } from './tabs-list';
6
+ import './tabs.styles.css';
7
+
8
+ type TabsContextState = {
9
+ openTab: string;
10
+ changeOpenTab: (id: string) => void;
11
+ };
12
+
13
+ const TabsContext = createContext<TabsContextState | null>(null);
14
+
15
+ const useTab = (id: string): [boolean, () => void] => {
16
+ const context = useContext(TabsContext);
17
+
18
+ if (!context) {
19
+ throw new Error('You cant use this component out off an Tabs component');
20
+ }
21
+
22
+ const { openTab, changeOpenTab } = context;
23
+
24
+ return [openTab === id, () => changeOpenTab(id)];
25
+ };
26
+
27
+ const useTabsContext = (): TabsContextState => {
28
+ const context = useContext(TabsContext);
29
+
30
+ if (!context) {
31
+ throw new Error('You cant use this component out off an Tabs component');
32
+ }
33
+
34
+ return context;
35
+ };
36
+
37
+ type TabsProps = {
38
+ children: React.ReactNode;
39
+ defaultOpenTab: string;
40
+ onChange?: (id: string) => void;
41
+ };
42
+
43
+ export const Tabs = ({ children, defaultOpenTab, onChange }: TabsProps) => {
44
+ const [openTab, setOpenTab] = useState(defaultOpenTab);
45
+
46
+ useEffect(() => {
47
+ if (onChange) {
48
+ onChange(openTab);
49
+ }
50
+ }, [openTab, onChange]);
51
+
52
+ return (
53
+ <TabsContext.Provider
54
+ value={{
55
+ openTab,
56
+ changeOpenTab: id => setOpenTab(id),
57
+ }}
58
+ >
59
+ {children}
60
+ </TabsContext.Provider>
61
+ );
62
+ };
63
+
64
+ type TabProps = {
65
+ id: string;
66
+ children: React.ReactNode;
67
+ className?: string;
68
+ style?: React.CSSProperties;
69
+ onClick?: (e: React.MouseEvent<HTMLSpanElement>) => void;
70
+ ref?: React.RefObject<HTMLSpanElement | null>;
71
+ };
72
+
73
+ const Tab = ({ id, children, className = '', style = {}, onClick, ref }: TabProps) => {
74
+ const [isOpen, openTab] = useTab(id);
75
+ const tabClassNames = useClassNames({
76
+ tab: true,
77
+ [className]: !!className,
78
+ 'is-open': isOpen,
79
+ });
80
+
81
+ const handleClick = (e: React.MouseEvent<HTMLSpanElement>) => {
82
+ openTab();
83
+
84
+ if (onClick) {
85
+ onClick(e);
86
+ }
87
+ };
88
+
89
+ return (
90
+ <span className={tabClassNames} style={style} onClick={handleClick} ref={ref}>
91
+ {children}
92
+ </span>
93
+ );
94
+ };
95
+
96
+ type TabPanelProps = {
97
+ id: string;
98
+ children: React.ReactNode;
99
+ };
100
+
101
+ const TabPanel = ({ id, children }: TabPanelProps) => {
102
+ const [isOpen] = useTab(id);
103
+
104
+ return isOpen ? children : null;
105
+ };
106
+
107
+ const TabList = ({ children, ...props }: Omit<TabListProps, 'openTab'>) => {
108
+ const { openTab } = useTabsContext();
109
+
110
+ return (
111
+ <TabListComponent {...props} openTab={openTab}>
112
+ {children}
113
+ </TabListComponent>
114
+ );
115
+ };
116
+
117
+ Tabs.Tab = Tab;
118
+ Tabs.TabPanel = TabPanel;
119
+ Tabs.TabList = TabList;
@@ -0,0 +1 @@
1
+ export * from './tag.component';
@@ -0,0 +1,34 @@
1
+ import { useClassNames } from '../../hooks';
2
+
3
+ import './tag.styles.css';
4
+
5
+ export enum TagRounded {
6
+ NONE = 'none',
7
+ SMALL = 'small',
8
+ MEDIUM = 'medium',
9
+ LARGE = 'large',
10
+ FULL = 'full',
11
+ }
12
+
13
+ interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {
14
+ children: React.ReactNode;
15
+ selected?: boolean;
16
+ rounded?: `${TagRounded}`;
17
+ noWrap?: boolean;
18
+ ref?: React.Ref<HTMLElement>;
19
+ }
20
+
21
+ export const Tag = ({ children, rounded = TagRounded.MEDIUM, selected = false, noWrap = false, ref }: TagProps) => {
22
+ const className = useClassNames({
23
+ tag: true,
24
+ [`rounded-${rounded}`]: Boolean(rounded),
25
+ 'is-selected': selected,
26
+ 'no-wrap': noWrap,
27
+ });
28
+
29
+ return (
30
+ <span className={className} ref={ref}>
31
+ {children}
32
+ </span>
33
+ );
34
+ };
@@ -0,0 +1,50 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .tag {
4
+ --background: attr(data-background, var(--color-primary-500));
5
+ --text: attr(data-text, var(--color-primary-50));
6
+ --background-selected: attr(data-background-selected, var(--color-primary-700));
7
+ --text-selected: attr(data-text-selected, var(--color-primary-50));
8
+
9
+ padding: 0.4em 0.8em;
10
+ border-radius: 0.3em;
11
+ border: 1px solid;
12
+ background: var(--background);
13
+ color: var(--text);
14
+ transition: all 300ms ease;
15
+ display: inline-block;
16
+ @apply text-label;
17
+ user-select: none;
18
+
19
+ &.no-wrap {
20
+ white-space: nowrap;
21
+ overflow: hidden;
22
+ text-overflow: ellipsis;
23
+ }
24
+
25
+ &.rounded-none {
26
+ border-radius: 0;
27
+ }
28
+
29
+ &.rounded-small {
30
+ border-radius: 0.25em;
31
+ }
32
+
33
+ &.rounded-medium {
34
+ border-radius: 0.5em;
35
+ }
36
+
37
+ &.rounded-large {
38
+ border-radius: 1em;
39
+ }
40
+
41
+ &.rounded-full {
42
+ border-radius: 100rem;
43
+ }
44
+
45
+ &:hover,
46
+ &.is-selected {
47
+ background: var(--background-selected);
48
+ color: var(--text-selected);
49
+ }
50
+ }
@@ -0,0 +1,41 @@
1
+ import { useState } from 'react';
2
+
3
+ import { Tooltip, TooltipProps } from '../tooltip';
4
+
5
+ type ClickToCopyProps = {
6
+ children?: React.ReactNode;
7
+ position?: TooltipProps['position'];
8
+ offset?: TooltipProps['offset'];
9
+ value: string;
10
+ tooltipText: string;
11
+ tooltipCopiedText?: string;
12
+ copiedTextTimeout?: number;
13
+ };
14
+
15
+ export const ClickToCopy = ({
16
+ children,
17
+ value,
18
+ position,
19
+ offset,
20
+ tooltipText,
21
+ tooltipCopiedText,
22
+ copiedTextTimeout = 500,
23
+ }: ClickToCopyProps) => {
24
+ const [justCopied, setJustCopied] = useState(false);
25
+
26
+ const handleCopy = () => {
27
+ setJustCopied(true);
28
+ navigator.clipboard.writeText(value);
29
+ setTimeout(() => setJustCopied(false), copiedTextTimeout);
30
+ };
31
+
32
+ return (
33
+ <Tooltip
34
+ content={justCopied && tooltipCopiedText ? tooltipCopiedText : tooltipText}
35
+ position={position}
36
+ offset={offset}
37
+ >
38
+ <span onClick={handleCopy}>{children}</span>
39
+ </Tooltip>
40
+ );
41
+ };
@@ -0,0 +1 @@
1
+ export * from './click-to-copy.component';
@@ -0,0 +1,2 @@
1
+ export * from './click-to-copy';
2
+ export * from './tooltip';
@@ -0,0 +1 @@
1
+ export * from './tooltip.component';
@@ -0,0 +1,64 @@
1
+ import React, { cloneElement } from 'react';
2
+
3
+ import { PositionContainer } from '../../../helpers';
4
+ import { useClassNames, useEventListener, useModal } from '../../../hooks';
5
+ import { Modal } from '../../modals';
6
+
7
+ import './tooltip.styles.css';
8
+
9
+ export type TooltipProps = {
10
+ position?:
11
+ | `${PositionContainer.TOP}`
12
+ | `${PositionContainer.LEFT}`
13
+ | `${PositionContainer.RIGHT}`
14
+ | `${PositionContainer.BOTTOM}`;
15
+ offset?: number | `${number}`;
16
+ disabled?: boolean;
17
+ children: React.ReactElement<{
18
+ ref: React.RefObject<HTMLElement | null>;
19
+ }>;
20
+ content: React.ReactNode;
21
+ };
22
+
23
+ export const Tooltip = ({
24
+ position = PositionContainer.TOP,
25
+ children,
26
+ content,
27
+ offset = 5,
28
+ disabled = false,
29
+ }: TooltipProps) => {
30
+ const { containerRef, openModal, closeModal, isOpen } = useModal();
31
+
32
+ const classNames = useClassNames({
33
+ tooltip: true,
34
+ [position]: true,
35
+ });
36
+
37
+ useEventListener('mouseenter', () => openModal(), containerRef);
38
+ useEventListener('mouseleave', () => closeModal(), containerRef);
39
+
40
+ if (disabled) return children;
41
+
42
+ return (
43
+ <>
44
+ {cloneElement(children, { ref: containerRef })}
45
+
46
+ <Modal
47
+ backdrop='none'
48
+ id='tooltip'
49
+ isOpen={isOpen}
50
+ containerRef={containerRef}
51
+ onClose={closeModal}
52
+ position={position}
53
+ className={classNames}
54
+ closeOnClickOutside={false}
55
+ offset={6 + +offset}
56
+ windowOffset={10}
57
+ transitionDuration={100}
58
+ closeAnimationClassName='close-animation'
59
+ >
60
+ <span className='tooltip-content'>{content}</span>
61
+ </Modal>
62
+ </>
63
+ );
64
+ };
@@ -0,0 +1,91 @@
1
+ @reference "polpo-tailwind-config/styles";
2
+
3
+ .tooltip {
4
+ color: var(--color-foreground);
5
+ @apply text-small;
6
+ line-height: 1em;
7
+ border-radius: 5px;
8
+ padding: 0.5em 1em;
9
+ display: block;
10
+ border: 1px solid;
11
+ pointer-events: none;
12
+
13
+ &::before {
14
+ content: '';
15
+ display: block;
16
+ background: var(--color-background-paper);
17
+ position: absolute;
18
+ z-index: 1;
19
+ width: 10px;
20
+ height: 10px;
21
+ border-left: 1px solid transparent;
22
+ border-top: 1px solid transparent;
23
+ border-right: 1px solid var(--color-foreground);
24
+ border-bottom: 1px solid var(--color-foreground);
25
+ border-radius: 0 0 3px 0;
26
+ }
27
+
28
+ &.left {
29
+ animation: fadeInRight 250ms ease-out;
30
+
31
+ &.close-animation {
32
+ animation: fadeOutLeft 250ms ease-out;
33
+ transform: translateX(-10px);
34
+ opacity: 0;
35
+ }
36
+
37
+ &::before {
38
+ top: 50%;
39
+ left: 100%;
40
+ transform: translate(-50%, -50%) rotate(-45deg);
41
+ }
42
+ }
43
+
44
+ &.right {
45
+ animation: fadeInLeft 250ms ease-out;
46
+
47
+ &.close-animation {
48
+ animation: fadeOutRight 250ms ease-out;
49
+ transform: translateX(10px);
50
+ opacity: 0;
51
+ }
52
+
53
+ &::before {
54
+ top: 50%;
55
+ right: 100%;
56
+ transform: translate(50%, -50%) rotate(135deg);
57
+ }
58
+ }
59
+
60
+ &.top {
61
+ animation: fadeInDown 250ms ease-out;
62
+
63
+ &.close-animation {
64
+ animation: fadeOutUp 250ms ease-out;
65
+ transform: translateY(-10px);
66
+ opacity: 0;
67
+ }
68
+
69
+ &::before {
70
+ top: 100%;
71
+ left: 50%;
72
+ transform: translate(-50%, -50%) rotate(45deg);
73
+ }
74
+ }
75
+
76
+ &.bottom {
77
+ animation: fadeInUp 250ms ease-out;
78
+
79
+ &.close-animation {
80
+ animation: fadeOutDown 250ms ease-out;
81
+ transform: translateY(10px);
82
+ opacity: 0;
83
+ }
84
+
85
+ &::before {
86
+ left: 50%;
87
+ bottom: 100%;
88
+ transform: translate(-50%, 50%) rotate(-135deg);
89
+ }
90
+ }
91
+ }
@@ -0,0 +1 @@
1
+ export * from './typography.component';
@@ -0,0 +1,81 @@
1
+ import React, { createElement, useMemo } from 'react';
2
+
3
+ import { useClassNames } from '../../hooks';
4
+
5
+ import {
6
+ TypographyColors,
7
+ TypographyVariant,
8
+ TypographyVariantsClassNames,
9
+ TypographyVariantsElements,
10
+ TypographyWeight,
11
+ } from './typography.constants';
12
+ import './typography.styles.css';
13
+
14
+ export type TypographyProps = React.HTMLAttributes<HTMLElement | HTMLLabelElement> & {
15
+ variant?: `${TypographyVariant}`;
16
+ nowrap?: boolean | number;
17
+ as?: React.HTMLElementType;
18
+ weight?: `${TypographyWeight}`;
19
+ children: React.ReactNode;
20
+ noPadding?: boolean;
21
+ htmlFor?: string;
22
+ align?: React.CSSProperties['textAlign'];
23
+ family?: 'primary' | 'code';
24
+ recommendedWidth?: boolean;
25
+ color?: `${TypographyColors}`;
26
+ ref?: React.RefObject<HTMLElement>;
27
+ style?: React.CSSProperties;
28
+ };
29
+
30
+ export const Typography = ({
31
+ variant = TypographyVariant.BODY,
32
+ nowrap = false,
33
+ className: customClassname = '',
34
+ style = {},
35
+ children,
36
+ as,
37
+ weight,
38
+ family = 'primary',
39
+ noPadding = false,
40
+ align,
41
+ color,
42
+ htmlFor,
43
+ recommendedWidth = false,
44
+ ...props
45
+ }: TypographyProps) => {
46
+ const className = useClassNames({
47
+ typography: true,
48
+ [TypographyVariantsClassNames[variant]]: TypographyVariantsClassNames[variant] !== undefined,
49
+ [customClassname]: !!customClassname,
50
+ [weight ?? '']: !!weight,
51
+ [color ?? '']: Boolean(color),
52
+ 'no-padding': noPadding,
53
+ 'code-family': family === 'code',
54
+ 'recommended-width': recommendedWidth,
55
+ 'nowrap-max-lines': typeof nowrap === 'number',
56
+ 'nowrap-max-lines-2': nowrap === 2,
57
+ 'nowrap-max-lines-3': nowrap === 3,
58
+ 'nowrap-max-lines-4': nowrap === 4,
59
+ 'nowrap-max-lines-5': nowrap === 5,
60
+ nowrap: nowrap === true,
61
+ });
62
+
63
+ const component = useMemo<React.HTMLElementType>(
64
+ () => TypographyVariantsElements[variant] ?? TypographyVariantsElements[TypographyVariant.BODY],
65
+ [variant],
66
+ );
67
+
68
+ return createElement(
69
+ as ?? component,
70
+ {
71
+ ...props,
72
+ className,
73
+ htmlFor,
74
+ style: {
75
+ textAlign: align,
76
+ ...style,
77
+ },
78
+ },
79
+ children,
80
+ );
81
+ };