@ujjan/built-badge 0.1.0 → 0.1.1

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.
package/README.md CHANGED
@@ -4,11 +4,33 @@ Reusable "Built at Ujjan.com" badge kit for adding Ujjan attribution to project
4
4
 
5
5
  ## Rule
6
6
 
7
- Place the badge inside a project's footer component or footer partial only.
7
+ Render the badge slot from a project's footer component or footer partial only, immediately before the actual `<footer>` element.
8
8
  If a page does not render a footer, it should not render this badge.
9
9
 
10
+ The slot intentionally sits outside the footer box while remaining owned by the footer component. It reserves space above the footer so page content does not collide with the badge. The badge uses its own equal right and bottom gap instead of the project's regular content gutter.
11
+
10
12
  ## Quick Start
11
13
 
14
+ Install the package:
15
+
16
+ ```bash
17
+ npm install @ujjan/built-badge
18
+ ```
19
+
20
+ Then copy or import the assets/snippets you need from the installed package:
21
+
22
+ ```txt
23
+ node_modules/@ujjan/built-badge/dist/ujjan-badge.css
24
+ node_modules/@ujjan/built-badge/dist/ujjan-badge.png
25
+ node_modules/@ujjan/built-badge/snippets/html.html
26
+ node_modules/@ujjan/built-badge/snippets/php.php
27
+ node_modules/@ujjan/built-badge/snippets/react.tsx
28
+ ```
29
+
30
+ For plain HTML or legacy PHP projects, copying the CSS, PNG, and snippet into the project is usually the simplest option.
31
+
32
+ ### Manual Copy
33
+
12
34
  Copy these files into your project:
13
35
 
14
36
  - `dist/ujjan-badge.css`
@@ -20,19 +42,25 @@ Load the CSS from the page or layout that owns the footer:
20
42
  <link rel="stylesheet" href="/assets/ujjan-badge.css">
21
43
  ```
22
44
 
23
- Then place the badge markup inside the footer:
45
+ Then place the badge slot immediately before the footer:
24
46
 
25
47
  ```html
26
- <a
27
- class="ujjan-built-badge"
28
- href="https://ujjan.com/work/promptiles"
29
- target="_blank"
30
- rel="noopener noreferrer"
31
- aria-label="Built at Ujjan.com"
32
- >
33
- <img src="/assets/ujjan-badge.png" alt="" width="25" height="30">
34
- <span>Built at Ujjan.com</span>
35
- </a>
48
+ <div class="ujjan-built-badge-slot">
49
+ <a
50
+ class="ujjan-built-badge"
51
+ href="https://ujjan.com/work/promptiles"
52
+ target="_blank"
53
+ rel="noopener noreferrer"
54
+ aria-label="Built at Ujjan.com"
55
+ >
56
+ <img class="ujjan-built-badge__logo" src="/assets/ujjan-badge.png" alt="" width="25" height="30">
57
+ <span class="ujjan-built-badge__text">Built at Ujjan.com</span>
58
+ </a>
59
+ </div>
60
+
61
+ <footer>
62
+ ...
63
+ </footer>
36
64
  ```
37
65
 
38
66
  Use the project case-study slug after `/work/`, for example:
@@ -49,11 +77,12 @@ https://ujjan.com
49
77
 
50
78
  ## Plain HTML
51
79
 
52
- Use [snippets/html.html](snippets/html.html) inside your footer:
80
+ Use [snippets/html.html](snippets/html.html) immediately before your footer, from the same footer partial/component:
53
81
 
54
82
  ```html
83
+ <!-- Ujjan badge slot goes here -->
55
84
  <footer>
56
- <!-- Ujjan badge goes here -->
85
+ ...
57
86
  </footer>
58
87
  ```
59
88
 
@@ -70,20 +99,29 @@ If `$ujjanCaseStudySlug` is not set or is empty, the badge links to `https://ujj
70
99
 
71
100
  ## React
72
101
 
73
- Copy [snippets/react.tsx](snippets/react.tsx) into your component library, import the CSS once, and render it from your footer component:
102
+ Install the package:
103
+
104
+ ```bash
105
+ npm install @ujjan/built-badge
106
+ ```
107
+
108
+ For the current version, copy [snippets/react.tsx](snippets/react.tsx) into your component library, import the CSS once, and render the slot from your footer component before the footer element:
74
109
 
75
110
  ```tsx
76
- import "./ujjan-badge.css";
77
- import { UjjanBuiltBadge } from "./UjjanBuiltBadge";
111
+ import "@ujjan/built-badge/css";
112
+ import { UjjanBuiltBadgeSlot } from "./UjjanBuiltBadge";
78
113
 
79
114
  export function Footer() {
80
115
  return (
81
- <footer>
82
- <UjjanBuiltBadge
116
+ <>
117
+ <UjjanBuiltBadgeSlot
83
118
  caseStudySlug="promptiles"
84
119
  logoSrc="/assets/ujjan-badge.png"
85
120
  />
86
- </footer>
121
+ <footer>
122
+ ...
123
+ </footer>
124
+ </>
87
125
  );
88
126
  }
89
127
  ```
@@ -91,7 +129,7 @@ export function Footer() {
91
129
  Omit `caseStudySlug` until the case study is live:
92
130
 
93
131
  ```tsx
94
- <UjjanBuiltBadge logoSrc="/assets/ujjan-badge.png" />
132
+ <UjjanBuiltBadgeSlot logoSrc="/assets/ujjan-badge.png" />
95
133
  ```
96
134
 
97
135
  ## Files
@@ -108,6 +146,9 @@ The CSS uses custom properties so each project can tune the badge without editin
108
146
 
109
147
  ```css
110
148
  :root {
149
+ --ujjan-badge-slot-min-height: 116px;
150
+ --ujjan-badge-slot-edge-gap: 36px;
151
+ --ujjan-badge-slot-mobile-edge-gap: 16px;
111
152
  --ujjan-badge-bg: #1e2126;
112
153
  --ujjan-badge-border: #505050;
113
154
  --ujjan-badge-text: #fff;
@@ -1,3 +1,15 @@
1
+ .ujjan-built-badge-slot {
2
+ box-sizing: border-box;
3
+ display: flex;
4
+ align-items: flex-end;
5
+ justify-content: var(--ujjan-badge-slot-justify, flex-end);
6
+ width: 100%;
7
+ min-height: var(--ujjan-badge-slot-min-height, 116px);
8
+ padding: var(--ujjan-badge-slot-top-gap, 32px)
9
+ var(--ujjan-badge-slot-edge-gap, 36px)
10
+ var(--ujjan-badge-slot-edge-gap, 36px);
11
+ }
12
+
1
13
  .ujjan-built-badge {
2
14
  position: relative;
3
15
  display: inline-flex;
@@ -15,6 +27,7 @@
15
27
  text-decoration: none;
16
28
  cursor: pointer;
17
29
  isolation: isolate;
30
+ box-sizing: border-box;
18
31
  transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
19
32
  }
20
33
 
@@ -97,3 +110,12 @@
97
110
  transition: none;
98
111
  }
99
112
  }
113
+
114
+ @media (max-width: 520px) {
115
+ .ujjan-built-badge-slot {
116
+ justify-content: var(--ujjan-badge-slot-mobile-justify, center);
117
+ padding-right: var(--ujjan-badge-slot-mobile-edge-gap, 16px);
118
+ padding-left: var(--ujjan-badge-slot-mobile-edge-gap, 16px);
119
+ padding-bottom: var(--ujjan-badge-slot-mobile-edge-gap, 16px);
120
+ }
121
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ujjan/built-badge",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Reusable footer badge kit for Built at Ujjan.com attribution.",
5
5
  "homepage": "https://ujjan.com",
6
6
  "repository": {
@@ -1,12 +1,14 @@
1
- <!-- Place this inside the project's footer only. -->
1
+ <!-- Place this immediately before the project's footer, inside the footer component/partial only. -->
2
2
  <!-- Use https://ujjan.com when the project case study is not published yet. -->
3
- <a
4
- class="ujjan-built-badge"
5
- href="https://ujjan.com/work/promptiles"
6
- target="_blank"
7
- rel="noopener noreferrer"
8
- aria-label="Built at Ujjan.com"
9
- >
10
- <img class="ujjan-built-badge__logo" src="/assets/ujjan-badge.png" alt="" width="25" height="30">
11
- <span class="ujjan-built-badge__text">Built at Ujjan.com</span>
12
- </a>
3
+ <div class="ujjan-built-badge-slot">
4
+ <a
5
+ class="ujjan-built-badge"
6
+ href="https://ujjan.com/work/promptiles"
7
+ target="_blank"
8
+ rel="noopener noreferrer"
9
+ aria-label="Built at Ujjan.com"
10
+ >
11
+ <img class="ujjan-built-badge__logo" src="/assets/ujjan-badge.png" alt="" width="25" height="30">
12
+ <span class="ujjan-built-badge__text">Built at Ujjan.com</span>
13
+ </a>
14
+ </div>
package/snippets/php.php CHANGED
@@ -1,6 +1,7 @@
1
1
  <?php
2
2
  /**
3
- * Place this partial inside the project's footer only.
3
+ * Place this partial immediately before the project's footer,
4
+ * inside the footer component/template only.
4
5
  *
5
6
  * Optional:
6
7
  * $ujjanCaseStudySlug = 'promptiles';
@@ -16,13 +17,15 @@ $ujjanBadgeHref = $ujjanBadgeSlug !== ''
16
17
  ? $ujjanBadgeBaseUrl . '/work/' . rawurlencode($ujjanBadgeSlug)
17
18
  : $ujjanBadgeBaseUrl;
18
19
  ?>
19
- <a
20
- class="ujjan-built-badge"
21
- href="<?= htmlspecialchars($ujjanBadgeHref, ENT_QUOTES, 'UTF-8') ?>"
22
- target="_blank"
23
- rel="noopener noreferrer"
24
- aria-label="Built at Ujjan.com"
25
- >
26
- <img class="ujjan-built-badge__logo" src="/assets/ujjan-badge.png" alt="" width="25" height="30">
27
- <span class="ujjan-built-badge__text">Built at Ujjan.com</span>
28
- </a>
20
+ <div class="ujjan-built-badge-slot">
21
+ <a
22
+ class="ujjan-built-badge"
23
+ href="<?= htmlspecialchars($ujjanBadgeHref, ENT_QUOTES, 'UTF-8') ?>"
24
+ target="_blank"
25
+ rel="noopener noreferrer"
26
+ aria-label="Built at Ujjan.com"
27
+ >
28
+ <img class="ujjan-built-badge__logo" src="/assets/ujjan-badge.png" alt="" width="25" height="30">
29
+ <span class="ujjan-built-badge__text">Built at Ujjan.com</span>
30
+ </a>
31
+ </div>
@@ -4,6 +4,10 @@ type UjjanBuiltBadgeProps = {
4
4
  logoSrc?: string;
5
5
  };
6
6
 
7
+ type UjjanBuiltBadgeSlotProps = UjjanBuiltBadgeProps & {
8
+ slotClassName?: string;
9
+ };
10
+
7
11
  const UJJAN_BASE_URL = "https://ujjan.com";
8
12
 
9
13
  function getUjjanBadgeHref(caseStudySlug?: string) {
@@ -42,3 +46,16 @@ export function UjjanBuiltBadge({
42
46
  </a>
43
47
  );
44
48
  }
49
+
50
+ export function UjjanBuiltBadgeSlot({
51
+ slotClassName = "",
52
+ ...badgeProps
53
+ }: UjjanBuiltBadgeSlotProps) {
54
+ const classes = ["ujjan-built-badge-slot", slotClassName].filter(Boolean).join(" ");
55
+
56
+ return (
57
+ <div className={classes}>
58
+ <UjjanBuiltBadge {...badgeProps} />
59
+ </div>
60
+ );
61
+ }