@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 +62 -21
- package/dist/ujjan-badge.css +22 -0
- package/package.json +1 -1
- package/snippets/html.html +13 -11
- package/snippets/php.php +14 -11
- package/snippets/react.tsx +17 -0
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
|
-
|
|
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
|
|
45
|
+
Then place the badge slot immediately before the footer:
|
|
24
46
|
|
|
25
47
|
```html
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</
|
|
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)
|
|
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
|
-
|
|
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
|
-
|
|
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 "
|
|
77
|
-
import {
|
|
111
|
+
import "@ujjan/built-badge/css";
|
|
112
|
+
import { UjjanBuiltBadgeSlot } from "./UjjanBuiltBadge";
|
|
78
113
|
|
|
79
114
|
export function Footer() {
|
|
80
115
|
return (
|
|
81
|
-
|
|
82
|
-
<
|
|
116
|
+
<>
|
|
117
|
+
<UjjanBuiltBadgeSlot
|
|
83
118
|
caseStudySlug="promptiles"
|
|
84
119
|
logoSrc="/assets/ujjan-badge.png"
|
|
85
120
|
/>
|
|
86
|
-
|
|
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
|
-
<
|
|
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;
|
package/dist/ujjan-badge.css
CHANGED
|
@@ -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
package/snippets/html.html
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
<!-- Place this
|
|
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
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</
|
|
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
|
|
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
|
-
<
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
</
|
|
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>
|
package/snippets/react.tsx
CHANGED
|
@@ -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
|
+
}
|