@notionhive/contacts 0.1.0

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 (68) hide show
  1. package/bin/contacts.js +16 -0
  2. package/category.config.json +7 -0
  3. package/package.json +24 -0
  4. package/registry/contact-01.json +9 -0
  5. package/registry/contact-02.json +9 -0
  6. package/registry/contact-03.json +9 -0
  7. package/registry/contact-04.json +6 -0
  8. package/registry/contact-05.json +9 -0
  9. package/registry/contact-06.json +9 -0
  10. package/registry/contact-07.json +9 -0
  11. package/registry/contact-08.json +6 -0
  12. package/registry/contact-09.json +10 -0
  13. package/registry/contact-10.json +6 -0
  14. package/registry/index.json +88 -0
  15. package/templates/components/atoms/SafeImage/SafeImage.jsx +101 -0
  16. package/templates/components/atoms/SafeImage/index.js +1 -0
  17. package/templates/components/hooks/useCarousel.js +73 -0
  18. package/templates/components/organisms/Contact01/Contact01.jsx +363 -0
  19. package/templates/components/organisms/Contact01/Contact01.propTypes.js +105 -0
  20. package/templates/components/organisms/Contact01/index.js +1 -0
  21. package/templates/components/organisms/Contact02/Contact02.jsx +288 -0
  22. package/templates/components/organisms/Contact02/Contact02.propTypes.js +78 -0
  23. package/templates/components/organisms/Contact02/index.js +1 -0
  24. package/templates/components/organisms/Contact03/Contact03.jsx +94 -0
  25. package/templates/components/organisms/Contact03/Contact03.propTypes.js +25 -0
  26. package/templates/components/organisms/Contact03/index.js +1 -0
  27. package/templates/components/organisms/Contact04/Contact04.jsx +239 -0
  28. package/templates/components/organisms/Contact04/Contact04.propTypes.js +50 -0
  29. package/templates/components/organisms/Contact04/index.js +1 -0
  30. package/templates/components/organisms/Contact05/Contact05.jsx +272 -0
  31. package/templates/components/organisms/Contact05/Contact05.propTypes.js +49 -0
  32. package/templates/components/organisms/Contact05/index.js +1 -0
  33. package/templates/components/organisms/Contact06/Contact06.jsx +223 -0
  34. package/templates/components/organisms/Contact06/Contact06.propTypes.js +40 -0
  35. package/templates/components/organisms/Contact06/index.js +1 -0
  36. package/templates/components/organisms/Contact07/Contact07.jsx +348 -0
  37. package/templates/components/organisms/Contact07/Contact07.propTypes.js +92 -0
  38. package/templates/components/organisms/Contact07/index.js +1 -0
  39. package/templates/components/organisms/Contact08/Contact08.jsx +178 -0
  40. package/templates/components/organisms/Contact08/Contact08.propTypes.js +36 -0
  41. package/templates/components/organisms/Contact08/index.js +1 -0
  42. package/templates/components/organisms/Contact09/Contact09.jsx +345 -0
  43. package/templates/components/organisms/Contact09/Contact09.propTypes.js +96 -0
  44. package/templates/components/organisms/Contact09/index.js +1 -0
  45. package/templates/components/organisms/Contact10/Contact10.jsx +175 -0
  46. package/templates/components/organisms/Contact10/Contact10.propTypes.js +55 -0
  47. package/templates/components/organisms/Contact10/index.js +1 -0
  48. package/templates/public/contact/contact01/ellipse.svg +12 -0
  49. package/templates/public/contact/contact01/logo-accenture.svg +6 -0
  50. package/templates/public/contact/contact01/logo-amart.svg +12 -0
  51. package/templates/public/contact/contact01/logo-brand12.png +0 -0
  52. package/templates/public/contact/contact01/logo-brand5.png +0 -0
  53. package/templates/public/contact/contact01/logo-brand7.png +0 -0
  54. package/templates/public/contact/contact01/logo-brand9.svg +12 -0
  55. package/templates/public/contact/contact01/logo-great-eastern.png +0 -0
  56. package/templates/public/contact/contact01/logo-kenwood.png +0 -0
  57. package/templates/public/contact/contact01/logo-nissan.svg +12 -0
  58. package/templates/public/contact/contact01/logo-suncorp.png +0 -0
  59. package/templates/public/contact/contact01/logo-ticketmaster.png +0 -0
  60. package/templates/public/contact/contact01/logo-toyota.svg +5 -0
  61. package/templates/public/contact/contact02/map.jpg +0 -0
  62. package/templates/public/contact/contact03/bg.jpg +0 -0
  63. package/templates/public/contact/contact03/card-photo.jpg +0 -0
  64. package/templates/public/contact/contact05/hero.jpg +0 -0
  65. package/templates/public/contact/contact05/pattern.png +0 -0
  66. package/templates/public/contact/contact06/hero.jpg +0 -0
  67. package/templates/public/contact/contact07/hero.jpg +0 -0
  68. package/templates/public/contact/contact09/avatar.jpg +0 -0
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+
3
+ const path = require("path");
4
+ const categoryConfig = require("../category.config.json");
5
+
6
+ function loadCore() {
7
+ try {
8
+ return require("@notionhive/core");
9
+ } catch {
10
+ return require(path.join(__dirname, "../../core/lib"));
11
+ }
12
+ }
13
+
14
+ const { createCategoryCli } = loadCore();
15
+ const run = createCategoryCli(categoryConfig);
16
+ run(path.resolve(__dirname, ".."));
@@ -0,0 +1,7 @@
1
+ {
2
+ "packageName": "@notionhive/contacts",
3
+ "binName": "contacts",
4
+ "label": "contact section",
5
+ "labelPlural": "contact sections",
6
+ "exampleId": "contact-01"
7
+ }
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@notionhive/contacts",
3
+ "version": "0.1.0",
4
+ "description": "Add editable contact sections into your Next.js project.",
5
+ "license": "UNLICENSED",
6
+ "bin": {
7
+ "contacts": "./bin/contacts.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "registry",
12
+ "templates",
13
+ "category.config.json"
14
+ ],
15
+ "scripts": {
16
+ "prepublishOnly": "node ../../scripts/sync-templates.js"
17
+ },
18
+ "dependencies": {
19
+ "@notionhive/core": "0.1.0"
20
+ },
21
+ "engines": {
22
+ "node": ">=18"
23
+ }
24
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "contact-01",
3
+ "exportName": "Contact01",
4
+ "folderName": "Contact01",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/contact/contact01"
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "contact-02",
3
+ "exportName": "Contact02",
4
+ "folderName": "Contact02",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/contact/contact02"
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "contact-03",
3
+ "exportName": "Contact03",
4
+ "folderName": "Contact03",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/contact/contact03"
9
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "contact-04",
3
+ "exportName": "Contact04",
4
+ "folderName": "Contact04",
5
+ "shared": []
6
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "contact-05",
3
+ "exportName": "Contact05",
4
+ "folderName": "Contact05",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/contact/contact05"
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "contact-06",
3
+ "exportName": "Contact06",
4
+ "folderName": "Contact06",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/contact/contact06"
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "id": "contact-07",
3
+ "exportName": "Contact07",
4
+ "folderName": "Contact07",
5
+ "shared": [
6
+ "atoms/SafeImage"
7
+ ],
8
+ "assets": "public/contact/contact07"
9
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "contact-08",
3
+ "exportName": "Contact08",
4
+ "folderName": "Contact08",
5
+ "shared": []
6
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "id": "contact-09",
3
+ "exportName": "Contact09",
4
+ "folderName": "Contact09",
5
+ "shared": [
6
+ "atoms/SafeImage",
7
+ "hooks/useCarousel"
8
+ ],
9
+ "assets": "public/contact/contact09"
10
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "id": "contact-10",
3
+ "exportName": "Contact10",
4
+ "folderName": "Contact10",
5
+ "shared": []
6
+ }
@@ -0,0 +1,88 @@
1
+ {
2
+ "category": "contacts",
3
+ "packageName": "@notionhive/contacts",
4
+ "items": [
5
+ {
6
+ "id": "contact-01",
7
+ "exportName": "Contact01",
8
+ "folderName": "Contact01",
9
+ "shared": [
10
+ "atoms/SafeImage"
11
+ ],
12
+ "assets": "public/contact/contact01"
13
+ },
14
+ {
15
+ "id": "contact-02",
16
+ "exportName": "Contact02",
17
+ "folderName": "Contact02",
18
+ "shared": [
19
+ "atoms/SafeImage"
20
+ ],
21
+ "assets": "public/contact/contact02"
22
+ },
23
+ {
24
+ "id": "contact-03",
25
+ "exportName": "Contact03",
26
+ "folderName": "Contact03",
27
+ "shared": [
28
+ "atoms/SafeImage"
29
+ ],
30
+ "assets": "public/contact/contact03"
31
+ },
32
+ {
33
+ "id": "contact-04",
34
+ "exportName": "Contact04",
35
+ "folderName": "Contact04",
36
+ "shared": []
37
+ },
38
+ {
39
+ "id": "contact-05",
40
+ "exportName": "Contact05",
41
+ "folderName": "Contact05",
42
+ "shared": [
43
+ "atoms/SafeImage"
44
+ ],
45
+ "assets": "public/contact/contact05"
46
+ },
47
+ {
48
+ "id": "contact-06",
49
+ "exportName": "Contact06",
50
+ "folderName": "Contact06",
51
+ "shared": [
52
+ "atoms/SafeImage"
53
+ ],
54
+ "assets": "public/contact/contact06"
55
+ },
56
+ {
57
+ "id": "contact-07",
58
+ "exportName": "Contact07",
59
+ "folderName": "Contact07",
60
+ "shared": [
61
+ "atoms/SafeImage"
62
+ ],
63
+ "assets": "public/contact/contact07"
64
+ },
65
+ {
66
+ "id": "contact-08",
67
+ "exportName": "Contact08",
68
+ "folderName": "Contact08",
69
+ "shared": []
70
+ },
71
+ {
72
+ "id": "contact-09",
73
+ "exportName": "Contact09",
74
+ "folderName": "Contact09",
75
+ "shared": [
76
+ "atoms/SafeImage",
77
+ "hooks/useCarousel"
78
+ ],
79
+ "assets": "public/contact/contact09"
80
+ },
81
+ {
82
+ "id": "contact-10",
83
+ "exportName": "Contact10",
84
+ "folderName": "Contact10",
85
+ "shared": []
86
+ }
87
+ ]
88
+ }
@@ -0,0 +1,101 @@
1
+ import Image from "next/image";
2
+
3
+ /**
4
+ * SafeImage — renders local /heroes/ assets reliably.
5
+ *
6
+ * Figma exports are often SVG content saved with .png extensions.
7
+ * Native img avoids next/image SVG restrictions and broken renders in Storybook.
8
+ *
9
+ * @param {object} props - Same as next/image (src, alt, fill, className, sizes, priority, width, height).
10
+ */
11
+ export function SafeImage({
12
+ src,
13
+ alt = "",
14
+ fill,
15
+ className = "",
16
+ sizes,
17
+ priority,
18
+ width,
19
+ height,
20
+ style,
21
+ ...rest
22
+ }) {
23
+ if (!src) return null;
24
+
25
+ const isLocalAsset =
26
+ src.startsWith("/heroes/") ||
27
+ src.startsWith("/menus/") ||
28
+ src.startsWith("/about/") ||
29
+ src.startsWith("/services/") ||
30
+ src.startsWith("/testimonials/") ||
31
+ src.startsWith("/cta/") ||
32
+ src.startsWith("/contact/") ||
33
+ src.startsWith("/footer/");
34
+ const isSvg = src.endsWith(".svg");
35
+
36
+ if (isLocalAsset || isSvg) {
37
+ if (fill) {
38
+ return (
39
+ // eslint-disable-next-line @next/next/no-img-element
40
+ <img
41
+ src={src}
42
+ alt={alt}
43
+ className={className}
44
+ style={{
45
+ ...style,
46
+ position: "absolute",
47
+ inset: 0,
48
+ width: "100%",
49
+ height: "100%",
50
+ objectFit: "cover",
51
+ }}
52
+ {...rest}
53
+ />
54
+ );
55
+ }
56
+
57
+ return (
58
+ // eslint-disable-next-line @next/next/no-img-element
59
+ <img
60
+ src={src}
61
+ alt={alt}
62
+ className={className}
63
+ width={width}
64
+ height={height}
65
+ style={style}
66
+ {...rest}
67
+ />
68
+ );
69
+ }
70
+
71
+ if (fill) {
72
+ return (
73
+ <Image
74
+ src={src}
75
+ alt={alt}
76
+ fill
77
+ className={className}
78
+ sizes={sizes}
79
+ priority={priority}
80
+ style={style}
81
+ {...rest}
82
+ />
83
+ );
84
+ }
85
+
86
+ return (
87
+ <Image
88
+ src={src}
89
+ alt={alt}
90
+ width={width}
91
+ height={height}
92
+ className={className}
93
+ sizes={sizes}
94
+ priority={priority}
95
+ style={style}
96
+ {...rest}
97
+ />
98
+ );
99
+ }
100
+
101
+ export default SafeImage;
@@ -0,0 +1 @@
1
+ export { SafeImage, default } from "./SafeImage";
@@ -0,0 +1,73 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+
5
+ /**
6
+ * useCarousel — shared slide state for hero carousels and sliders.
7
+ *
8
+ * @param {object} options
9
+ * @param {number} [options.count=1] - Total slide count.
10
+ * @param {number} [options.initialIndex=0] - Starting slide.
11
+ * @param {boolean} [options.loop=false] - Wrap from last → first.
12
+ * @param {number} [options.autoPlayMs=0] - Auto-advance interval; 0 = off.
13
+ * @param {(index: number) => void} [options.onChange] - Called when slide changes.
14
+ * @returns {{ activeSlide: number, goTo: Function, next: Function, prev: Function, pause: Function, resume: Function, isPaused: boolean }}
15
+ */
16
+ export function useCarousel({
17
+ count = 1,
18
+ initialIndex = 0,
19
+ loop = false,
20
+ autoPlayMs = 0,
21
+ onChange,
22
+ } = {}) {
23
+ const maxIndex = Math.max(0, count - 1);
24
+ const [activeSlide, setActiveSlide] = useState(() =>
25
+ Math.min(Math.max(initialIndex, 0), maxIndex)
26
+ );
27
+ const [isPaused, setIsPaused] = useState(false);
28
+
29
+ const goTo = useCallback(
30
+ (index) => {
31
+ const next = loop
32
+ ? ((index % count) + count) % count
33
+ : Math.min(Math.max(index, 0), maxIndex);
34
+ setActiveSlide(next);
35
+ onChange?.(next);
36
+ },
37
+ [count, loop, maxIndex, onChange]
38
+ );
39
+
40
+ const next = useCallback(() => {
41
+ if (loop || activeSlide < maxIndex) goTo(activeSlide + 1);
42
+ }, [activeSlide, goTo, loop, maxIndex]);
43
+
44
+ const prev = useCallback(() => {
45
+ if (loop || activeSlide > 0) goTo(activeSlide - 1);
46
+ }, [activeSlide, goTo, loop]);
47
+
48
+ const pause = useCallback(() => setIsPaused(true), []);
49
+ const resume = useCallback(() => setIsPaused(false), []);
50
+
51
+ useEffect(() => {
52
+ if (!autoPlayMs || isPaused || count <= 1) return undefined;
53
+
54
+ const id = window.setInterval(next, autoPlayMs);
55
+ return () => window.clearInterval(id);
56
+ }, [autoPlayMs, count, isPaused, next]);
57
+
58
+ useEffect(() => {
59
+ setActiveSlide((current) => Math.min(Math.max(current, 0), maxIndex));
60
+ }, [maxIndex]);
61
+
62
+ return {
63
+ activeSlide,
64
+ goTo,
65
+ next,
66
+ prev,
67
+ pause,
68
+ resume,
69
+ isPaused,
70
+ };
71
+ }
72
+
73
+ export default useCarousel;