@fpkit/acss 0.4.4

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 (297) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -0
  3. package/dist/chunk-77CZU5XZ.cjs +9 -0
  4. package/dist/chunk-77CZU5XZ.cjs.map +1 -0
  5. package/dist/chunk-D43FJIRQ.cjs +31 -0
  6. package/dist/chunk-D43FJIRQ.cjs.map +1 -0
  7. package/dist/chunk-GJWMCDFS.js +9 -0
  8. package/dist/chunk-GJWMCDFS.js.map +1 -0
  9. package/dist/chunk-PCDUGD3C.js +5 -0
  10. package/dist/chunk-PCDUGD3C.js.map +1 -0
  11. package/dist/hooks.cjs +10 -0
  12. package/dist/hooks.cjs.map +1 -0
  13. package/dist/hooks.d.cts +32 -0
  14. package/dist/hooks.d.ts +32 -0
  15. package/dist/hooks.js +8 -0
  16. package/dist/hooks.js.map +1 -0
  17. package/dist/icon-e6044c73.d.ts +227 -0
  18. package/dist/icons.cjs +73 -0
  19. package/dist/icons.cjs.map +1 -0
  20. package/dist/icons.d.cts +252 -0
  21. package/dist/icons.d.ts +252 -0
  22. package/dist/icons.js +4 -0
  23. package/dist/icons.js.map +1 -0
  24. package/dist/index.cjs +59 -0
  25. package/dist/index.cjs.map +1 -0
  26. package/dist/index.d.cts +566 -0
  27. package/dist/index.d.ts +566 -0
  28. package/dist/index.js +11 -0
  29. package/dist/index.js.map +1 -0
  30. package/libs/chunk-GCGKYLDG.js +7 -0
  31. package/libs/chunk-GCGKYLDG.js.map +1 -0
  32. package/libs/chunk-PDD4N5P5.cjs +10 -0
  33. package/libs/chunk-PDD4N5P5.cjs.map +1 -0
  34. package/libs/chunk-QHIABQNQ.js +8 -0
  35. package/libs/chunk-QHIABQNQ.js.map +1 -0
  36. package/libs/chunk-ZOHIKF6I.cjs +31 -0
  37. package/libs/chunk-ZOHIKF6I.cjs.map +1 -0
  38. package/libs/components/badge/badge.css +1 -0
  39. package/libs/components/badge/badge.css.map +1 -0
  40. package/libs/components/badge/badge.min.css +3 -0
  41. package/libs/components/breadcrumbs/breadcrumb.css +1 -0
  42. package/libs/components/breadcrumbs/breadcrumb.css.map +1 -0
  43. package/libs/components/breadcrumbs/breadcrumb.min.css +3 -0
  44. package/libs/components/buttons/button.css +1 -0
  45. package/libs/components/buttons/button.css.map +1 -0
  46. package/libs/components/buttons/button.min.css +3 -0
  47. package/libs/components/cards/card-style.css +1 -0
  48. package/libs/components/cards/card-style.css.map +1 -0
  49. package/libs/components/cards/card-style.min.css +3 -0
  50. package/libs/components/cards/card.css +1 -0
  51. package/libs/components/cards/card.css.map +1 -0
  52. package/libs/components/cards/card.min.css +3 -0
  53. package/libs/components/details/details.css +1 -0
  54. package/libs/components/details/details.css.map +1 -0
  55. package/libs/components/details/details.min.css +3 -0
  56. package/libs/components/form/form.css +1 -0
  57. package/libs/components/form/form.css.map +1 -0
  58. package/libs/components/form/form.min.css +3 -0
  59. package/libs/components/icons/icon.css +1 -0
  60. package/libs/components/icons/icon.css.map +1 -0
  61. package/libs/components/icons/icon.min.css +3 -0
  62. package/libs/components/images/img.css +1 -0
  63. package/libs/components/images/img.css.map +1 -0
  64. package/libs/components/images/img.min.css +3 -0
  65. package/libs/components/layout/landmarks.css +1 -0
  66. package/libs/components/layout/landmarks.css.map +1 -0
  67. package/libs/components/layout/landmarks.min.css +3 -0
  68. package/libs/components/link/link.css +1 -0
  69. package/libs/components/link/link.css.map +1 -0
  70. package/libs/components/link/link.min.css +3 -0
  71. package/libs/components/nav/nav.css +1 -0
  72. package/libs/components/nav/nav.css.map +1 -0
  73. package/libs/components/nav/nav.min.css +3 -0
  74. package/libs/components/progress/progress.css +1 -0
  75. package/libs/components/progress/progress.css.map +1 -0
  76. package/libs/components/progress/progress.min.css +3 -0
  77. package/libs/components/styles/index.css +1 -0
  78. package/libs/components/styles/index.css.map +1 -0
  79. package/libs/components/styles/index.min.css +3 -0
  80. package/libs/components/tag/tag.css +1 -0
  81. package/libs/components/tag/tag.css.map +1 -0
  82. package/libs/components/tag/tag.min.css +3 -0
  83. package/libs/components/text-to-speech/text-to-speech.css +1 -0
  84. package/libs/components/text-to-speech/text-to-speech.css.map +1 -0
  85. package/libs/components/text-to-speech/text-to-speech.min.css +3 -0
  86. package/libs/hooks.cjs +12 -0
  87. package/libs/hooks.cjs.map +1 -0
  88. package/libs/hooks.d.cts +32 -0
  89. package/libs/hooks.d.ts +32 -0
  90. package/libs/hooks.js +3 -0
  91. package/libs/hooks.js.map +1 -0
  92. package/libs/icons-1f5afc0c.d.ts +318 -0
  93. package/libs/icons.cjs +12 -0
  94. package/libs/icons.cjs.map +1 -0
  95. package/libs/icons.d.cts +2 -0
  96. package/libs/icons.d.ts +2 -0
  97. package/libs/icons.js +3 -0
  98. package/libs/icons.js.map +1 -0
  99. package/libs/index.cjs +71 -0
  100. package/libs/index.cjs.map +1 -0
  101. package/libs/index.css +1 -0
  102. package/libs/index.css.map +1 -0
  103. package/libs/index.d.cts +551 -0
  104. package/libs/index.d.ts +551 -0
  105. package/libs/index.js +11 -0
  106. package/libs/index.js.map +1 -0
  107. package/package.json +125 -0
  108. package/src/App.css +42 -0
  109. package/src/App.tsx +35 -0
  110. package/src/__snapshots__/App.test.tsx.snap +56 -0
  111. package/src/components/.gitkeep +0 -0
  112. package/src/components/__snapshots__/fp.test.tsx.snap +3 -0
  113. package/src/components/badge/badge.scss +20 -0
  114. package/src/components/badge/badge.stories.tsx +54 -0
  115. package/src/components/badge/badge.tsx +17 -0
  116. package/src/components/breadcrumbs/bc-item.tsx +20 -0
  117. package/src/components/breadcrumbs/breadcrumb.scss +35 -0
  118. package/src/components/breadcrumbs/breadcrumb.stories.tsx +92 -0
  119. package/src/components/breadcrumbs/breadcrumb.tsx +218 -0
  120. package/src/components/buttons/button.scss +115 -0
  121. package/src/components/buttons/button.stories.tsx +57 -0
  122. package/src/components/buttons/button.test.tsx +104 -0
  123. package/src/components/buttons/button.tsx +64 -0
  124. package/src/components/cards/card-style.scss +0 -0
  125. package/src/components/cards/card.scss +43 -0
  126. package/src/components/cards/card.stories.tsx +114 -0
  127. package/src/components/cards/card.test.tsx +30 -0
  128. package/src/components/cards/card.tsx +135 -0
  129. package/src/components/cards/flex-card.tsx +15 -0
  130. package/src/components/details/details.scss +75 -0
  131. package/src/components/details/details.stories.tsx +122 -0
  132. package/src/components/details/details.tsx +77 -0
  133. package/src/components/form/README.mdx +70 -0
  134. package/src/components/form/fields.tsx +45 -0
  135. package/src/components/form/form.scss +87 -0
  136. package/src/components/form/form.stories.tsx +49 -0
  137. package/src/components/form/form.tsx +71 -0
  138. package/src/components/form/input.stories.tsx +155 -0
  139. package/src/components/form/inputs.tsx +84 -0
  140. package/src/components/form/select.stories.tsx +38 -0
  141. package/src/components/form/select.tsx +112 -0
  142. package/src/components/form/textarea.tsx +87 -0
  143. package/src/components/fp.test.tsx +56 -0
  144. package/src/components/fp.tsx +78 -0
  145. package/src/components/heading/heading.stories.tsx +75 -0
  146. package/src/components/heading/heading.tsx +27 -0
  147. package/src/components/icons/components/add.tsx +42 -0
  148. package/src/components/icons/components/arrow-down.tsx +52 -0
  149. package/src/components/icons/components/arrow-left.tsx +49 -0
  150. package/src/components/icons/components/arrow-right.tsx +52 -0
  151. package/src/components/icons/components/arrow-up.tsx +49 -0
  152. package/src/components/icons/components/chat.tsx +44 -0
  153. package/src/components/icons/components/code.tsx +50 -0
  154. package/src/components/icons/components/copy.tsx +51 -0
  155. package/src/components/icons/components/down.tsx +33 -0
  156. package/src/components/icons/components/home.tsx +57 -0
  157. package/src/components/icons/components/left.tsx +43 -0
  158. package/src/components/icons/components/minus.tsx +42 -0
  159. package/src/components/icons/components/pause-solid.tsx +48 -0
  160. package/src/components/icons/components/pause.tsx +63 -0
  161. package/src/components/icons/components/play-solid.tsx +44 -0
  162. package/src/components/icons/components/play.tsx +51 -0
  163. package/src/components/icons/components/remove.tsx +42 -0
  164. package/src/components/icons/components/resume-solid.tsx +52 -0
  165. package/src/components/icons/components/resume.tsx +57 -0
  166. package/src/components/icons/components/right.tsx +43 -0
  167. package/src/components/icons/components/star.tsx +38 -0
  168. package/src/components/icons/components/stop-solid.tsx +44 -0
  169. package/src/components/icons/components/stop.tsx +54 -0
  170. package/src/components/icons/components/svg.tsx +44 -0
  171. package/src/components/icons/components/up.tsx +31 -0
  172. package/src/components/icons/components/user.tsx +46 -0
  173. package/src/components/icons/icon.scss +15 -0
  174. package/src/components/icons/icon.stories.tsx +208 -0
  175. package/src/components/icons/icon.tsx +100 -0
  176. package/src/components/icons/index.ts +29 -0
  177. package/src/components/icons/types.ts +12 -0
  178. package/src/components/images/README.mdx +43 -0
  179. package/src/components/images/figure.stories.tsx +34 -0
  180. package/src/components/images/figure.tsx +44 -0
  181. package/src/components/images/img.scss +43 -0
  182. package/src/components/images/img.stories.tsx +24 -0
  183. package/src/components/images/img.test.tsx +43 -0
  184. package/src/components/images/img.tsx +93 -0
  185. package/src/components/images/place-holder.png +0 -0
  186. package/src/components/kit.tsx +56 -0
  187. package/src/components/layout/_header.scss +72 -0
  188. package/src/components/layout/footer.stories.tsx +34 -0
  189. package/src/components/layout/landmarks.scss +51 -0
  190. package/src/components/layout/landmarks.stories.tsx +54 -0
  191. package/src/components/layout/landmarks.tsx +149 -0
  192. package/src/components/layout/main.stories.tsx +90 -0
  193. package/src/components/link/link.scss +92 -0
  194. package/src/components/link/link.stories.tsx +74 -0
  195. package/src/components/link/link.tsx +48 -0
  196. package/src/components/list/list.stories.tsx +52 -0
  197. package/src/components/list/list.tsx +74 -0
  198. package/src/components/modal/dialog.tsx +50 -0
  199. package/src/components/modal/modal.tsx +85 -0
  200. package/src/components/nav/nav.scss +90 -0
  201. package/src/components/nav/nav.stories.tsx +96 -0
  202. package/src/components/nav/nav.tsx +76 -0
  203. package/src/components/popover/node_modules/.vitest/results.json +1 -0
  204. package/src/components/popover/popover.stories.tsx +31 -0
  205. package/src/components/popover/popover.test.tsx +39 -0
  206. package/src/components/popover/popover.tsx +85 -0
  207. package/src/components/progress/progress.scss +70 -0
  208. package/src/components/progress/progress.stories.tsx +51 -0
  209. package/src/components/progress/progress.tsx +82 -0
  210. package/src/components/readme.stories.mdx +7 -0
  211. package/src/components/styles/index.css +520 -0
  212. package/src/components/styles/index.css.map +1 -0
  213. package/src/components/tables/table-elements.tsx +57 -0
  214. package/src/components/tables/table.tsx +57 -0
  215. package/src/components/tag/tag.scss +56 -0
  216. package/src/components/tag/tag.stories.tsx +39 -0
  217. package/src/components/tag/tag.tsx +25 -0
  218. package/src/components/text/text.stories.tsx +67 -0
  219. package/src/components/text/text.tsx +93 -0
  220. package/src/components/text-to-speech/README.mdx +192 -0
  221. package/src/components/text-to-speech/TextInput.tsx +19 -0
  222. package/src/components/text-to-speech/TextToSpeech.stories.tsx +145 -0
  223. package/src/components/text-to-speech/TextToSpeech.tsx +94 -0
  224. package/src/components/text-to-speech/text-to-speech.scss +31 -0
  225. package/src/components/text-to-speech/useTextToSpeech.mdx +182 -0
  226. package/src/components/text-to-speech/useTextToSpeech.tsx +176 -0
  227. package/src/components/text-to-speech/views/TextToSpeechControls.tsx +117 -0
  228. package/src/components/ui.tsx +67 -0
  229. package/src/favicon.svg +15 -0
  230. package/src/hooks/popover/__snapshots__/popover.test.tsx.snap +88 -0
  231. package/src/hooks/popover/node_modules/.vitest/results.json +1 -0
  232. package/src/hooks/popover/popover.tsx +71 -0
  233. package/src/hooks/popover/use-popover.tsx +83 -0
  234. package/src/hooks.ts +1 -0
  235. package/src/icons.ts +1 -0
  236. package/src/index.css +13 -0
  237. package/src/index.scss +19 -0
  238. package/src/index.ts +35 -0
  239. package/src/libs/content.ts +30 -0
  240. package/src/logo.svg +7 -0
  241. package/src/main.tsx +10 -0
  242. package/src/patterns/.gitkeep +0 -0
  243. package/src/patterns/page/page-header.stories.tsx +44 -0
  244. package/src/patterns/page/page-header.tsx +78 -0
  245. package/src/sass/_elements.scss +17 -0
  246. package/src/sass/_globals.scss +162 -0
  247. package/src/sass/_layout.scss +51 -0
  248. package/src/sass/_loading-animation.scss +35 -0
  249. package/src/sass/_mixins.scss +10 -0
  250. package/src/sass/_properties.scss +106 -0
  251. package/src/sass/_reset.scss +183 -0
  252. package/src/sass/_type.scss +43 -0
  253. package/src/setupTest.ts +1 -0
  254. package/src/styles/badge/badge.css +22 -0
  255. package/src/styles/badge/badge.css.map +1 -0
  256. package/src/styles/breadcrumbs/breadcrumb.css +42 -0
  257. package/src/styles/breadcrumbs/breadcrumb.css.map +1 -0
  258. package/src/styles/buttons/button.css +93 -0
  259. package/src/styles/buttons/button.css.map +1 -0
  260. package/src/styles/cards/card-style.css +3 -0
  261. package/src/styles/cards/card-style.css.map +1 -0
  262. package/src/styles/cards/card.css +48 -0
  263. package/src/styles/cards/card.css.map +1 -0
  264. package/src/styles/details/details.css +69 -0
  265. package/src/styles/details/details.css.map +1 -0
  266. package/src/styles/dropdowns/dropdown.css.map +1 -0
  267. package/src/styles/form/form.css +93 -0
  268. package/src/styles/form/form.css.map +1 -0
  269. package/src/styles/form/style.css.map +1 -0
  270. package/src/styles/icons/icon.css +16 -0
  271. package/src/styles/icons/icon.css.map +1 -0
  272. package/src/styles/images/img.css +42 -0
  273. package/src/styles/images/img.css.map +1 -0
  274. package/src/styles/index.css +1330 -0
  275. package/src/styles/index.css.map +1 -0
  276. package/src/styles/layout/landmarks.css +155 -0
  277. package/src/styles/layout/landmarks.css.map +1 -0
  278. package/src/styles/link/link.css +88 -0
  279. package/src/styles/link/link.css.map +1 -0
  280. package/src/styles/nav/nav.css +85 -0
  281. package/src/styles/nav/nav.css.map +1 -0
  282. package/src/styles/progress/progress.css +54 -0
  283. package/src/styles/progress/progress.css.map +1 -0
  284. package/src/styles/progress/sass/progress.css.map +1 -0
  285. package/src/styles/styles/index.css +562 -0
  286. package/src/styles/styles/index.css.map +1 -0
  287. package/src/styles/tag/badge.css.map +1 -0
  288. package/src/styles/tag/tag.css +71 -0
  289. package/src/styles/tag/tag.css.map +1 -0
  290. package/src/styles/text-to-speech/text-to-speech.css +32 -0
  291. package/src/styles/text-to-speech/text-to-speech.css.map +1 -0
  292. package/src/test/setup.ts +6 -0
  293. package/src/types/component-props.ts +36 -0
  294. package/src/types/index.ts +2 -0
  295. package/src/types/input-props.ts +28 -0
  296. package/src/types/shared.ts +57 -0
  297. package/src/vite-env.d.ts +1 -0
@@ -0,0 +1,71 @@
1
+ import React from 'react'
2
+ import usePopover from './use-popover'
3
+
4
+ /**
5
+ * Interface for props accepted by the Popover component
6
+ *
7
+ * @property {ReactNode} children - The content to show in the popover
8
+ * @property {ReactNode} [content] - Optional alternative content for popover
9
+ */
10
+ export type PopoverProps = {
11
+ children: React.ReactNode
12
+ content?: React.ReactNode
13
+ }
14
+
15
+ /**
16
+ * Popover component to display popover content.
17
+ *
18
+ * @param {Object} props - The props for the component.
19
+ * @returns {JSX.Element} - The JSX element for the Popover component.
20
+ *
21
+ * The component uses the usePopover hook to handle popover visibility and positioning.
22
+ *
23
+ * It renders a button that shows the popover on hover using pointer events.
24
+ *
25
+ * The popover content itself is rendered absolutely positioned when visible.
26
+ *
27
+ * Styles like background, border, padding etc are applied inline.
28
+ *
29
+ * Transforms and opacity animate the popover enter/exit.
30
+ */
31
+ export const Popover = ({ children, ...props }: PopoverProps) => {
32
+ const hoverRef = React.useRef(null)
33
+ const popOverRef = React.useRef(null)
34
+ const { isVisible, popoverPosition, handlePointerEvent, handlePointerLeave } =
35
+ usePopover(hoverRef, popOverRef)
36
+
37
+ return (
38
+ <div data-testid="popover">
39
+ <div
40
+ ref={hoverRef}
41
+ onPointerEnter={handlePointerEvent}
42
+ onPointerLeave={handlePointerLeave}
43
+ >
44
+ {children}
45
+ </div>
46
+ {isVisible && (
47
+ <div
48
+ ref={popOverRef}
49
+ style={{
50
+ display: 'block',
51
+ position: 'absolute',
52
+ background: '#000',
53
+ border: '1px solid #ccc',
54
+ padding: '10px',
55
+ color: '#fff',
56
+ top: popoverPosition.top,
57
+ left: popoverPosition.left,
58
+ transition: 'opacity .5s ease-in-out',
59
+ opacity: isVisible ? 1 : 0,
60
+ transform: `translateY(${isVisible ? '0px' : '-50px'})`,
61
+ // zIndex: 999,
62
+ }}
63
+ >
64
+ {'This is a popover.'}
65
+ </div>
66
+ )}
67
+ </div>
68
+ )
69
+ }
70
+
71
+ export default Popover
@@ -0,0 +1,83 @@
1
+ import { useState } from 'react'
2
+
3
+ type Position = {
4
+ /**
5
+ * @description This is the top position of the popover.
6
+ * @default 0
7
+ */
8
+ top: number
9
+ /**
10
+ * @description This is the left position of the popover.
11
+ * @default 0
12
+ */
13
+ left: number
14
+ }
15
+
16
+ /**
17
+ * @description This is the hook to show/hide the popover.
18
+ * @param elementRef - This is the ref of the element on which the popover should be shown.
19
+ * @param hoverRef - This is the ref of the element on which the popover should be shown.
20
+ * @param spacing - This is the spacing between the element and the popover.
21
+ * @example - const { isVisible, popoverPosition, handlePointerEvent, handlePointerLeave } = usePopover(hoverRef, popOverRef, 1)
22
+ * @returns - This is the object of the following properties.
23
+ * @returns - isVisible - This is the boolean value to show/hide the popover.
24
+ * @returns - popoverPosition - This is the position of the popover.
25
+ * @returns - handlePointerEvent - This is the function to handle the pointer event.
26
+ * @returns - handlePointerLeave - This is the function to handle the pointer leave event.
27
+ */
28
+ export const usePopover = (
29
+ elementRef: React.RefObject<HTMLElement | HTMLDivElement>,
30
+ hoverRef: React.RefObject<HTMLElement | HTMLDivElement>,
31
+ spacing = 1,
32
+ ) => {
33
+ const [isVisible, setIsVisible] = useState(false)
34
+ const [popoverPosition, setPopoverPosition] = useState<Position>({
35
+ top: 0,
36
+ left: 0,
37
+ })
38
+
39
+ const handlePointerEvent = (
40
+ event: React.MouseEvent<HTMLButtonElement | HTMLElement>,
41
+ ) => {
42
+ event?.stopPropagation()
43
+ const height = elementRef.current?.offsetHeight || 40
44
+ if (elementRef.current) {
45
+ const rect = elementRef.current.getBoundingClientRect()
46
+ const { scrollY, scrollX, innerHeight } = window
47
+
48
+ const popoverTop = rect.bottom + scrollY + spacing
49
+ const popoverLeft = rect.left + scrollX
50
+ const popoverBottom = popoverTop + height // Adjust the popover height as needed
51
+ const popoverHeight = hoverRef.current?.offsetHeight ?? height // Adjust the popover height as needed
52
+
53
+ const adjustedTop =
54
+ popoverBottom > scrollY + innerHeight
55
+ ? Math.max(
56
+ scrollY + innerHeight - popoverHeight - height - spacing,
57
+ scrollY,
58
+ ) -
59
+ height -
60
+ spacing
61
+ : popoverTop
62
+
63
+ setPopoverPosition({
64
+ top: adjustedTop,
65
+ left: popoverLeft,
66
+ })
67
+ setIsVisible(true)
68
+ }
69
+ }
70
+
71
+ const handlePointerLeave = () => {
72
+ setIsVisible(false)
73
+ }
74
+
75
+ return {
76
+ isVisible,
77
+ popoverPosition,
78
+ handlePointerEvent,
79
+ handlePointerLeave,
80
+ }
81
+ }
82
+
83
+ export default usePopover
package/src/hooks.ts ADDED
@@ -0,0 +1 @@
1
+ export { usePopover } from './hooks/popover/use-popover'
package/src/icons.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './components/icons/icon'
package/src/index.css ADDED
@@ -0,0 +1,13 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5
+ sans-serif;
6
+ -webkit-font-smoothing: antialiased;
7
+ -moz-osx-font-smoothing: grayscale;
8
+ }
9
+
10
+ code {
11
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12
+ monospace;
13
+ }
package/src/index.scss ADDED
@@ -0,0 +1,19 @@
1
+ @import './sass/reset';
2
+ @import './sass/layout';
3
+ @import './sass/type';
4
+ @import './sass/properties';
5
+ @import './sass/globals';
6
+ @import './sass/elements';
7
+ @import './components/buttons/button.scss';
8
+ @import './components/tag/tag.scss';
9
+ @import './components/images/img.scss';
10
+ @import './components/cards/card.scss';
11
+ @import './components/progress/progress.scss';
12
+ @import './components/details/details.scss';
13
+ @import './components/link/link.scss';
14
+ @import './components/layout/landmarks.scss';
15
+ @import './components/badge/badge.scss';
16
+ @import './components/nav/nav.scss';
17
+ @import './components/form/form.scss';
18
+ @import './components/breadcrumbs/breadcrumb.scss';
19
+ @import './components/text-to-speech/text-to-speech.scss';
package/src/index.ts ADDED
@@ -0,0 +1,35 @@
1
+ import { TextToSpeech } from './components/text-to-speech/TextToSpeech'
2
+ // import { Popover } from './hooks/popover/popover'
3
+ // export { Textarea } from './components/form/textarea';
4
+
5
+ export { Button } from './components/buttons/button'
6
+ export { Card } from './components/cards/card'
7
+ export { Dialog } from './components/modal/dialog'
8
+ export { Field } from './components/form/fields'
9
+ export * from './components/layout/landmarks'
10
+ export * from './components/layout/landmarks'
11
+ export { Icon } from './components/icons/icon'
12
+ export { Img } from './components/images/img'
13
+ export { Input } from './components/form/inputs'
14
+ export { Link } from './components/link/link'
15
+ export { List } from './components/list/list'
16
+ export { Modal } from './components/modal/modal'
17
+ export * from './components/nav/nav'
18
+ export { Popover } from './components/popover/popover'
19
+ export { RenderTable as TBL } from './components/tables/table'
20
+ export * from './components/tag/tag'
21
+ export * from './components/tables/table-elements'
22
+ export * from './components/details/details'
23
+ export * from './components/text/text'
24
+ export * from './components/form/textarea'
25
+ export * from './components/nav/nav'
26
+ export * from './components/heading/heading'
27
+ export * from './components/breadcrumbs/breadcrumb'
28
+ export * from './components/text-to-speech/TextToSpeech'
29
+ export { TextToSpeech } from './components/text-to-speech/TextToSpeech'
30
+
31
+ export { default as To } from './components/link/link'
32
+ export { default as FP } from './components/fp'
33
+ export { default as Box } from './components/fp'
34
+
35
+ export * from './components/ui'
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Converts a string to a slug by:
3
+ * - Converting to lowercase
4
+ * - Trimming whitespace
5
+ * - Removing non-word and non-hyphen characters
6
+ * - Replacing sequences of whitespace and hyphens with a single hyphen
7
+ * - Removing leading and trailing hyphens
8
+ *
9
+ * @param str - The string to slugify
10
+ * @returns The slugified string
11
+ */
12
+ export const Slugify = (str: string) => {
13
+ return str
14
+ .toLowerCase()
15
+ .trim()
16
+ .replace(/[^\w\s-]/g, '')
17
+ .replace(/[\s_-]+/g, '-')
18
+ .replace(/^-+|-+$/g, '')
19
+ }
20
+
21
+ /**
22
+ * Truncates a string to a maximum length.
23
+ *
24
+ * @param str - The string to truncate.
25
+ * @param length - The maximum length of the truncated string. Defaults to 15.
26
+ * @returns The truncated string, with ellipses appended if truncated.
27
+ */
28
+ export const Truncate = (str: string, length: number = 15) => {
29
+ return str.length > length ? `${str.slice(0, length)}...` : str
30
+ }
package/src/logo.svg ADDED
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
2
+ <g fill="#61DAFB">
3
+ <path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
4
+ <circle cx="420.9" cy="296.5" r="45.7"/>
5
+ <path d="M520.5 78.1z"/>
6
+ </g>
7
+ </svg>
package/src/main.tsx ADDED
@@ -0,0 +1,10 @@
1
+ import React from 'react'
2
+ import ReactDOM from 'react-dom/client'
3
+ import App from './App'
4
+ import './index.css'
5
+
6
+ ReactDOM.createRoot(document.getElementById('root')!).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>
10
+ )
File without changes
@@ -0,0 +1,44 @@
1
+ import { StoryObj, Meta } from '@storybook/react'
2
+ import { within, userEvent, screen } from '@storybook/testing-library'
3
+ import { expect } from '@storybook/jest'
4
+
5
+ import PageHeader, { HeaderVariants } from './page-header.js'
6
+ import { Img } from '#components/images/img'
7
+
8
+ const meta: Meta<typeof PageHeader> = {
9
+ title: 'FP.React Patterns/PageHeader',
10
+ component: PageHeader,
11
+ args: {
12
+ headerTitle: 'Page Header',
13
+ headerSubtitle: 'Place your cool elevator pitch here...',
14
+ headerBackground: <Img src="https://picsum.photos/2400/600" alt="" />,
15
+ },
16
+ } as Meta
17
+
18
+ export default meta
19
+ type Story = StoryObj<typeof PageHeader>
20
+
21
+ export const PageHeaderComponent: Story = {
22
+ args: {},
23
+ name: 'Page Header',
24
+ play: async ({ canvasElement }) => {
25
+ const canvas = within(canvasElement)
26
+ //expect(canvas).toBeInTheDocument()
27
+ },
28
+ }
29
+
30
+ export const Cover: Story = {
31
+ args: {
32
+ ...PageHeaderComponent.args,
33
+ variant: HeaderVariants.Cover,
34
+ },
35
+ name: 'Cover Style',
36
+ } as Story
37
+
38
+ export const Banner: Story = {
39
+ args: {
40
+ ...PageHeaderComponent.args,
41
+ variant: HeaderVariants.Banner,
42
+ },
43
+ name: 'Banner Style',
44
+ } as Story
@@ -0,0 +1,78 @@
1
+ import React, { Component } from 'react'
2
+ import Landmarks from '#components/layout/landmarks'
3
+ import Heading from '#components/heading/heading'
4
+ import { Link } from '#components/link/link'
5
+ import { ComponentProps } from '#types'
6
+
7
+ export enum HeaderVariants {
8
+ Cover = 'cover',
9
+ Banner = 'banner',
10
+ }
11
+
12
+ export type HeaderLinkType = {
13
+ url: string
14
+ label: string
15
+ }
16
+
17
+ export type PageHeaderProps = {
18
+ /** The title of the page header */
19
+ headerTitle: string
20
+ /** The subtitle of the page header (optional) */
21
+ headerSubtitle?: string
22
+ /** The variant of the page header (optional) */
23
+ variant?: HeaderVariants
24
+ /** The children of the page header (optional) */
25
+ children?: React.ReactNode
26
+ /** The link of the page header (optional) */
27
+ headerLink?: HeaderLinkType
28
+ } & React.ComponentProps<typeof Landmarks.Header>
29
+
30
+ const defaultStyles = {
31
+ minHeight: 'var(--hdr-min-h, 30vh)',
32
+ }
33
+
34
+ /**
35
+ * PageHeader component
36
+ *
37
+ * Renders a page header with title, subtitle, variant and children.
38
+ *
39
+ * @param {PageHeaderProps} props - Component props
40
+ * @param {string} props.headerTitle - The title of the header
41
+ * @param {string} [props.headerSubtitle] - Optional subtitle
42
+ * @param {HeaderVariants} [props.variant] - Visual variant
43
+ * @param {ReactNode} [props.headerBackground] - Background element to render inside the header
44
+ * @param {ReactNode} [props.children] - Content inside the header
45
+ * @param {Object} [props.styles] - CSS styles to apply
46
+ *
47
+ * @returns {ReactElement} The page header component
48
+ */
49
+ const PageHeader = ({
50
+ headerTitle,
51
+ headerSubtitle,
52
+ variant,
53
+ children,
54
+ styles,
55
+ headerBackground,
56
+ ...props
57
+ }: PageHeaderProps) => {
58
+ const style = { defaultStyles, ...styles }
59
+ return (
60
+ <Landmarks.Header
61
+ headerBackground={headerBackground}
62
+ styles={style}
63
+ data-style={variant}
64
+ aria-label="landmark header"
65
+ {...props}
66
+ >
67
+ <Landmarks.Section>
68
+ <Heading type={`h1`}>{headerTitle}</Heading>
69
+ {!!headerSubtitle && <h2>{headerSubtitle}</h2>}
70
+ {children}
71
+ </Landmarks.Section>
72
+ </Landmarks.Header>
73
+ )
74
+ }
75
+
76
+ export default PageHeader
77
+ PageHeader.displayName = 'PageHeader'
78
+ PageHeader.styles = defaultStyles
@@ -0,0 +1,17 @@
1
+ h1,
2
+ h2,
3
+ h3,
4
+ h4,
5
+ h5,
6
+ h6 {
7
+ &[data-ui~='display'],
8
+ &:has(span:first-of-type) > span {
9
+ --weight: 600;
10
+ --title-1: var(--h1);
11
+ --title-2: var(--h2);
12
+ --title-3: var(--h3);
13
+ --title-4: var(--h4);
14
+ --title-5: var(--h5);
15
+ --title-6: var(--h6);
16
+ }
17
+ }
@@ -0,0 +1,162 @@
1
+ :root {
2
+ --font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI',
3
+ 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
4
+ 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
5
+ --TRUE: initial;
6
+ --FALSE: ;
7
+ --fs-weight: 500;
8
+ }
9
+
10
+ html {
11
+ font-family: var(--font-family);
12
+ font-size: 100%;
13
+ }
14
+
15
+ body {
16
+ display: var(--body-dsp, flex);
17
+ min-height: 100%;
18
+ flex-direction: var(--body-direction, column);
19
+ min-width: 20.3125rem;
20
+ font-size: var(--fs-0);
21
+
22
+ main {
23
+ flex-grow: 1;
24
+ }
25
+
26
+ > a[href^='#'] {
27
+ position: absolute;
28
+ top: -4rem;
29
+ left: 0;
30
+ width: 100%;
31
+ display: block;
32
+ justify-content: flex-start;
33
+ padding: 1rem;
34
+ z-index: 100;
35
+ transition: top 0.3s;
36
+ border-radius: 0;
37
+ // padding: 1rem;
38
+ background-color: whitesmoke;
39
+ &:focus {
40
+ top: 0;
41
+ }
42
+ }
43
+ }
44
+
45
+ * + div,
46
+ * + ul,
47
+ * + section {
48
+ margin-block-start: 1rem;
49
+ }
50
+
51
+ main,
52
+ header,
53
+ footer,
54
+ section {
55
+ font-size: var(--fs-0);
56
+ > section {
57
+ margin-inline: auto;
58
+ width: var(--content-w, 80%);
59
+ }
60
+ > div {
61
+ width: 100%;
62
+ text-align: center;
63
+ }
64
+ }
65
+
66
+ section {
67
+ &:not(nav) {
68
+ margin-inline: var(--sect-y, auto);
69
+ padding-block: var(--sect-x, --spc-4);
70
+ }
71
+ }
72
+
73
+ p {
74
+ max-width: 75ch;
75
+ font-size: var(--fs-0);
76
+ line-height: 1.6;
77
+
78
+ & + p {
79
+ margin-block-start: 1rem;
80
+ }
81
+ }
82
+
83
+ ul,
84
+ ol {
85
+ display: var(--li-display, flex);
86
+ flex-direction: var(--li-direction, column);
87
+ gap: var(--li-gap, 0.2rem);
88
+ flex-wrap: var(--li-wrap, nowrap);
89
+ padding-inline-start: var(--li-ps, var(--spc-0));
90
+ &[role='list'],
91
+ &[data-list~='unstyled'] {
92
+ list-style: var(--li-style, none);
93
+ margin-block-end: var(--li-my, 0);
94
+ margin-block-start: var(--li-mx, 0);
95
+ }
96
+ &[data-list~='inline'] {
97
+ --li-direction: row;
98
+ --li-gap: 1rem;
99
+ --li-wrap: wrap;
100
+ --li-px: 0;
101
+ }
102
+ }
103
+
104
+ sup {
105
+ vertical-align: super;
106
+ font-size: smaller;
107
+ }
108
+
109
+ blockquote {
110
+ padding: 1rem;
111
+ border-left: 5px lightgray solid;
112
+ }
113
+
114
+ strong {
115
+ font-weight: var(--fs-weight);
116
+ }
117
+
118
+ h1,
119
+ h2,
120
+ h3,
121
+ h4,
122
+ h5,
123
+ h6 {
124
+ font-weight: var(--fs-weight);
125
+ margin-block-start: 0;
126
+ margin-block-end: 1rem;
127
+ line-height: 1.5;
128
+ }
129
+
130
+ h1 {
131
+ font-size: var(--h1, var(--fs-7));
132
+ }
133
+
134
+ h2 {
135
+ font-size: var(--h2, var(--fs-6));
136
+ }
137
+
138
+ h3 {
139
+ font-size: var(--h3, var(--fs-5));
140
+ }
141
+
142
+ h4 {
143
+ font-size: var(--h4, var(--fs-4));
144
+ }
145
+
146
+ h5 {
147
+ font-size: var(--h5, var(--fs-3));
148
+ }
149
+
150
+ h6 {
151
+ font-size: var(--h6, var(--fs-2));
152
+ }
153
+
154
+ hr {
155
+ --hr-h: 0.0625rem;
156
+ --hr-color: lightgray;
157
+ --hr-my: 1.5rem;
158
+ --hr-style: dotted;
159
+ border: none;
160
+ border-bottom: var(--hr-h) var(--hr-style) var(--hr-color);
161
+ margin-block: var(--hr-my);
162
+ }
@@ -0,0 +1,51 @@
1
+ @mixin props {
2
+
3
+ --spc-0: 0;
4
+ --spc-1: 0.25rem;
5
+ --spc-2: 0.5rem;
6
+ --spc-3: 0.75rem;
7
+ --spc-4: 1rem;
8
+ --spc-5: 1.5;
9
+ --spc-6: 2rem;
10
+ --spc-7: 2.5rem;
11
+ --spc-8: 3rem;
12
+ --spc-9: 3.5rem;
13
+ --spc-10: 4rem;
14
+ --spc-11: 4.5rem;
15
+ --spc-12: 5rem;
16
+ --spc-13: 6rem;
17
+ --spc-14: 7rem;
18
+ --spc-15: 8rem;
19
+ --spc-16: 9rem;
20
+ --spc-17: 10rem;
21
+ --spc-18: 11rem;
22
+ --spc-19: 12rem;
23
+ --spc-20: 13rem;
24
+
25
+ // t-shirt sizes
26
+ --spc: var(--spc-4);
27
+ --spc-xs: var(--spc-1);
28
+ --spc-sm: var(--spc-3);
29
+ --spc-base: var(--spc-5);
30
+ --spc-md: var(--spc-7);
31
+ --spc-lg: var(--spc-9);
32
+ --spc-xl: var(--spc-11);
33
+ --spc-xxl: var(--spc-13);
34
+
35
+ // vw units
36
+ --vw-xs: 5vw;
37
+ --vw-sm: 10vw;
38
+ --vw-md: 20vw;
39
+ --vw-lg: 50vw;
40
+ --vw-xl: 80vw;
41
+ --vw-xxl: 95vw;
42
+
43
+ // vh units
44
+ --vh-xs: 5vh;
45
+ --vh-sm: 10vh;
46
+ --vh-md: 20vh;
47
+ --vh-lg: 50vh;
48
+ --vh-xl: 80vh;
49
+ --vh-xxl: 95vh;
50
+
51
+ }
@@ -0,0 +1,35 @@
1
+ @keyframes loading {
2
+ 0% {
3
+ width: 0%;
4
+ }
5
+ 100% {
6
+ width: 100%;
7
+ }
8
+ }
9
+
10
+ .loading-bar {
11
+ height: 20px;
12
+ background-color: #3498db;
13
+ animation-name: loading;
14
+ animation-duration: 2s;
15
+ animation-iteration-count: infinite;
16
+ }
17
+ @keyframes pulse {
18
+ 0% {
19
+ transform: scale(1);
20
+ }
21
+ 50% {
22
+ transform: scale(1.1);
23
+ }
24
+ 100% {
25
+ transform: scale(1);
26
+ }
27
+ }
28
+
29
+ .loading-bar {
30
+ height: 20px;
31
+ background-color: #3498db;
32
+ animation-name: pulse;
33
+ animation-duration: 2s;
34
+ animation-iteration-count: infinite;
35
+ }
@@ -0,0 +1,10 @@
1
+ @mixin scale-transitions {
2
+ --scale-transition: transform 0.25s ease;
3
+ --scale: scale(1);
4
+ --scale-to: scale(1.05);
5
+ transform: var(--scale);
6
+ transition: var(--scale-transition);
7
+ &:hover {
8
+ transform: var(--scale-to);
9
+ }
10
+ }