@dnaproje/identity 0.0.0-stage → 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 +49 -2
- package/dist/fonts/Archivo-Bold.ttf +0 -0
- package/dist/fonts/Archivo-Regular.ttf +0 -0
- package/dist/fonts/SourceCodePro-Bold.ttf +0 -0
- package/dist/fonts/SourceCodePro-Regular.ttf +0 -0
- package/dist/fonts/SourceSans3-Bold.ttf +0 -0
- package/dist/fonts/SourceSans3-Regular.ttf +0 -0
- package/dist/fonts.css +43 -0
- package/dist/logos.cjs +6 -0
- package/dist/logos.d.ts +4 -0
- package/dist/logos.js +5 -0
- package/dist/png/dna-cizgi.png +0 -0
- package/dist/png/dna-mark-email.png +0 -0
- package/dist/png/dna-mark-white.png +0 -0
- package/dist/png/dna-mark.png +0 -0
- package/dist/png/dna-serit.png +0 -0
- package/dist/png/dna-wordmark.png +0 -0
- package/dist/svg/dna-mark-white.svg +1 -0
- package/dist/svg/dna-mark.svg +1 -0
- package/dist/svg/dna-wordmark.svg +1 -0
- package/dist/tailwind.css +30 -0
- package/dist/tokens.cjs +638 -0
- package/dist/tokens.css +57 -0
- package/dist/tokens.d.ts +9 -0
- package/dist/tokens.js +638 -0
- package/dist/tokens.json +613 -0
- package/package.json +47 -4
- package/src/email-signature.d.ts +28 -0
- package/src/email-signature.js +96 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// DNA e-mail signature (identity/spec/50-email-signature.md). Table based, inline styles only,
|
|
2
|
+
// no web fonts, no company name or e-mail address in the signature. Colours, address, web and
|
|
3
|
+
// logo come from the tokens, so dna-website and any other tool render the same signature.
|
|
4
|
+
import { tokens } from '../dist/tokens.js'
|
|
5
|
+
|
|
6
|
+
const C = {
|
|
7
|
+
ink: tokens.color.brand.ink.hex,
|
|
8
|
+
navy: tokens.color.brand.navy.hex,
|
|
9
|
+
secondary: tokens.color.support.textSecondary.hex,
|
|
10
|
+
link: tokens.color.support.link.hex,
|
|
11
|
+
}
|
|
12
|
+
const FONT = [tokens.font.email.family, ...tokens.font.email.fallback].map(f => (/\s/.test(f) && f !== 'sans-serif' ? `'${f}'` : f)).join(',')
|
|
13
|
+
const ADDRESS = tokens.company.addressShort
|
|
14
|
+
const WEB_LABEL = tokens.company.web
|
|
15
|
+
const WEB_URL = `https://${tokens.company.web}`
|
|
16
|
+
export const LOGO_URL = tokens.logo.webMarkUrl
|
|
17
|
+
|
|
18
|
+
const escapeHtml = s => String(s ?? '').replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>').replaceAll('"', '"')
|
|
19
|
+
|
|
20
|
+
// Normalises a Turkish mobile number to "+90 5XX XXX XX XX"; leaves anything else as typed.
|
|
21
|
+
export function normalizeGsm(input) {
|
|
22
|
+
let d = String(input ?? '').replace(/\D/g, '')
|
|
23
|
+
if (d.startsWith('0090')) d = d.slice(4)
|
|
24
|
+
else if (d.startsWith('90') && d.length === 12) d = d.slice(2)
|
|
25
|
+
else if (d.startsWith('0') && d.length === 11) d = d.slice(1)
|
|
26
|
+
if (d.length !== 10 || !d.startsWith('5')) return String(input ?? '').trim()
|
|
27
|
+
return `+90 ${d.slice(0, 3)} ${d.slice(3, 6)} ${d.slice(6, 8)} ${d.slice(8)}`
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function phones({ gsm, phone }) {
|
|
31
|
+
const g = normalizeGsm(gsm)
|
|
32
|
+
const p = String(phone ?? '').trim()
|
|
33
|
+
return p ? `${g} · ${p}` : g
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function required(data) {
|
|
37
|
+
for (const key of ['name', 'titleTr', 'titleEn', 'gsm']) {
|
|
38
|
+
if (!String(data?.[key] ?? '').trim()) throw new Error(`E-posta imzası için "${key}" zorunlu.`)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* HTML signature to paste into Gmail or Outlook.
|
|
44
|
+
* @param {{ name: string, titleTr: string, titleEn: string, gsm: string, phone?: string, variant?: 'A'|'B' }} data
|
|
45
|
+
* @param {{ logoUrl?: string }} [options] logoUrl must be absolute in a copied signature; a preview may pass a site-relative path.
|
|
46
|
+
*/
|
|
47
|
+
export function emailSignatureHtml(data, { logoUrl = LOGO_URL } = {}) {
|
|
48
|
+
required(data)
|
|
49
|
+
const variant = data.variant === 'B' ? 'B' : 'A'
|
|
50
|
+
const title = `${escapeHtml(data.titleTr.trim())} · ${escapeHtml(data.titleEn.trim())}`
|
|
51
|
+
const address = variant === 'A'
|
|
52
|
+
? `<a href="${WEB_URL}" style="color:${C.link};text-decoration:none">${WEB_LABEL}</a> · ${escapeHtml(ADDRESS)}`
|
|
53
|
+
: escapeHtml(ADDRESS)
|
|
54
|
+
const webRow = variant === 'B'
|
|
55
|
+
? `\n <tr>\n <td colspan="2" align="center" style="padding-top:10px"><a href="${WEB_URL}" style="font-size:11px;line-height:16px;color:${C.link};text-decoration:none;letter-spacing:.08em">${WEB_LABEL}</a></td>\n </tr>`
|
|
56
|
+
: ''
|
|
57
|
+
return `<table cellpadding="0" cellspacing="0" border="0" style="border-collapse:collapse;font-family:${FONT}">
|
|
58
|
+
<tr>
|
|
59
|
+
<td valign="top" style="padding:2px 16px 0 0"><img src="${escapeHtml(logoUrl)}" width="48" height="48" alt="DNA" style="display:block;border:0"></td>
|
|
60
|
+
<td valign="top">
|
|
61
|
+
<div style="font-size:14px;font-weight:700;color:${C.ink};line-height:20px">${escapeHtml(data.name.trim())}</div>
|
|
62
|
+
<div style="font-size:12px;color:${C.navy};line-height:18px">${title}</div>
|
|
63
|
+
<div style="font-size:11px;color:${C.secondary};line-height:18px;padding-top:4px">${address}</div>
|
|
64
|
+
<div style="font-size:12px;color:${C.ink};line-height:18px">${escapeHtml(phones(data))}</div>
|
|
65
|
+
</td>
|
|
66
|
+
</tr>${webRow}
|
|
67
|
+
</table>`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Plain-text twin of the HTML signature (text/plain part of the clipboard). */
|
|
71
|
+
export function emailSignatureText(data) {
|
|
72
|
+
required(data)
|
|
73
|
+
const variant = data.variant === 'B' ? 'B' : 'A'
|
|
74
|
+
const lines = [data.name.trim(), `${data.titleTr.trim()} · ${data.titleEn.trim()}`, variant === 'A' ? `${WEB_LABEL} · ${ADDRESS}` : ADDRESS, phones(data)]
|
|
75
|
+
if (variant === 'B') lines.push(WEB_LABEL)
|
|
76
|
+
return lines.join('\n')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Two-line reply signature: name, then "DNA · GSM". */
|
|
80
|
+
export const shortReplySignature = data => `${String(data.name ?? '').trim()}\nDNA · ${normalizeGsm(data.gsm)}`
|
|
81
|
+
|
|
82
|
+
/** Mobile signature: "Name — DNA", then GSM. */
|
|
83
|
+
export const mobileSignature = data => `${String(data.name ?? '').trim()} — DNA\n${normalizeGsm(data.gsm)}`
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Preview only: mimics how mail clients recolour the signature in dark mode. Never copy this
|
|
87
|
+
* output; the copied HTML always carries the light values.
|
|
88
|
+
*/
|
|
89
|
+
export function darkPreview(html) {
|
|
90
|
+
const d = tokens.color.darkPreview
|
|
91
|
+
const map = { [C.ink]: d.ink, [C.navy]: d.navy, [C.secondary]: d.textSecondary, [C.link]: d.link }
|
|
92
|
+
const pattern = new RegExp(Object.keys(map).join('|'), 'gi')
|
|
93
|
+
return html.replace(pattern, hex => map[hex.toUpperCase()] ?? hex)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export const DARK_PREVIEW_BACKGROUND = tokens.color.darkPreview.background
|