@ideare/kit 0.1.0-next.1 → 0.1.0-next.3
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/dist/draft/draft.d.ts +6 -2
- package/dist/draft/draft.js +119 -10
- package/dist/files/docs.d.ts +2 -0
- package/dist/files/docs.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/draft/draft.d.ts
CHANGED
|
@@ -20,12 +20,15 @@ export type DraftInput = {
|
|
|
20
20
|
name: string;
|
|
21
21
|
/** What the business does, in the owner's words. It becomes the tagline. */
|
|
22
22
|
idea: string;
|
|
23
|
+
/** A tagline the owner picked (an AI suggestion). It replaces the idea as the tagline only:
|
|
24
|
+
* the idea still says what the business does, and the look never moves with it. */
|
|
25
|
+
tagline?: string;
|
|
23
26
|
locale: Locale;
|
|
24
27
|
seed: number;
|
|
25
28
|
picks: DraftPicks;
|
|
26
29
|
};
|
|
27
30
|
/** The longest name (the wordmark's limit) and line (the copy check's tagline limit) a draft
|
|
28
|
-
* takes: every file the kit makes has room for them. */
|
|
31
|
+
* takes: every file the kit makes has room for them. A picked tagline has the line's limit. */
|
|
29
32
|
export declare const DRAFT_LIMITS: {
|
|
30
33
|
readonly name: 40;
|
|
31
34
|
readonly idea: 60;
|
|
@@ -55,7 +58,8 @@ export declare function newDraftSeed(): number;
|
|
|
55
58
|
export declare function draftBrand(input: DraftInput, ctx: {
|
|
56
59
|
fonts: FontResolver;
|
|
57
60
|
}): Promise<Brand>;
|
|
58
|
-
/** The draft as link parameters: name, idea, locale, seed, colors, fonts and
|
|
61
|
+
/** The draft as link parameters: name, idea, a picked tagline, locale, seed, colors, fonts and
|
|
62
|
+
* logo. */
|
|
59
63
|
export declare function draftParams(input: DraftInput): URLSearchParams;
|
|
60
64
|
/** A draft read back from link parameters, or null when any part is missing or out of range. */
|
|
61
65
|
export declare function readDraftParams(params: URLSearchParams): DraftInput | null;
|
package/dist/draft/draft.js
CHANGED
|
@@ -4,7 +4,7 @@ import { catalogFont } from "../fonts/pick.js";
|
|
|
4
4
|
import { iconMark, initials, matchIcons, monogramMark } from "../marks/draw.js";
|
|
5
5
|
import { engineFor } from "../scene/render.js";
|
|
6
6
|
/** The longest name (the wordmark's limit) and line (the copy check's tagline limit) a draft
|
|
7
|
-
* takes: every file the kit makes has room for them. */
|
|
7
|
+
* takes: every file the kit makes has room for them. A picked tagline has the line's limit. */
|
|
8
8
|
export const DRAFT_LIMITS = { name: 40, idea: 60 };
|
|
9
9
|
/**
|
|
10
10
|
* The font pairs a draft picks from. Few on purpose: a browser carries every file
|
|
@@ -199,6 +199,106 @@ function lineMood(idea) {
|
|
|
199
199
|
const haystack = plain(idea);
|
|
200
200
|
return MOOD_WORDS.find((row) => row.words.some((word) => haystack.includes(` ${word}`)));
|
|
201
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Colors a name or an idea can say, in pt-BR, en and es, as OKLCH hue ranges: "Salão Ametista"
|
|
204
|
+
* starts purple, "Loja Rubi" red. A trailing space means the whole word. Short words that are also
|
|
205
|
+
* everyday words (mar, sol, céu) are left out, so colors don't jump while a name is typed.
|
|
206
|
+
*/
|
|
207
|
+
const COLOR_WORDS = [
|
|
208
|
+
{
|
|
209
|
+
hues: [18, 34],
|
|
210
|
+
words: [
|
|
211
|
+
"vermelh",
|
|
212
|
+
"rubi",
|
|
213
|
+
"ruby",
|
|
214
|
+
"rojo ",
|
|
215
|
+
"roja ",
|
|
216
|
+
"carmim",
|
|
217
|
+
"carmin",
|
|
218
|
+
"cereja",
|
|
219
|
+
"cherry",
|
|
220
|
+
],
|
|
221
|
+
},
|
|
222
|
+
{ hues: [24, 40], words: ["coral", "terracota", "terracotta"] },
|
|
223
|
+
{ hues: [48, 64], words: ["laranj", "orange", "naranj", "tangerin", "damasco", "apricot"] },
|
|
224
|
+
{
|
|
225
|
+
hues: [50, 66],
|
|
226
|
+
words: ["marrom", "brown", "chocolat", "cacau", "cacao", "canela", "cinnamon"],
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
hues: [86, 104],
|
|
230
|
+
words: [
|
|
231
|
+
"amarel",
|
|
232
|
+
"yellow",
|
|
233
|
+
"amarill",
|
|
234
|
+
"dourad",
|
|
235
|
+
"dorad",
|
|
236
|
+
"golden",
|
|
237
|
+
"ouro ",
|
|
238
|
+
"girassol",
|
|
239
|
+
"sunflower",
|
|
240
|
+
"girasol",
|
|
241
|
+
],
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
hues: [132, 156],
|
|
245
|
+
words: [
|
|
246
|
+
"verde",
|
|
247
|
+
"green",
|
|
248
|
+
"esmerald",
|
|
249
|
+
"emerald",
|
|
250
|
+
"menta",
|
|
251
|
+
"mint ",
|
|
252
|
+
"oliva",
|
|
253
|
+
"olive",
|
|
254
|
+
"jade",
|
|
255
|
+
"salvia",
|
|
256
|
+
"sage ",
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
{ hues: [180, 200], words: ["turques", "turquoise", "turquesa", "aqua "] },
|
|
260
|
+
{
|
|
261
|
+
hues: [244, 266],
|
|
262
|
+
words: [
|
|
263
|
+
"azul",
|
|
264
|
+
"blue",
|
|
265
|
+
"safira",
|
|
266
|
+
"sapphire",
|
|
267
|
+
"zafiro",
|
|
268
|
+
"celeste",
|
|
269
|
+
"anil",
|
|
270
|
+
"indigo",
|
|
271
|
+
"marinho",
|
|
272
|
+
"navy",
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
{
|
|
276
|
+
hues: [296, 316],
|
|
277
|
+
words: [
|
|
278
|
+
"roxo",
|
|
279
|
+
"roxa",
|
|
280
|
+
"purple",
|
|
281
|
+
"morad",
|
|
282
|
+
"lilas",
|
|
283
|
+
"lilac",
|
|
284
|
+
"lila ",
|
|
285
|
+
"violet",
|
|
286
|
+
"ametist",
|
|
287
|
+
"amethyst",
|
|
288
|
+
"amatist",
|
|
289
|
+
"lavand",
|
|
290
|
+
"lavender",
|
|
291
|
+
],
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
hues: [338, 356],
|
|
295
|
+
words: ["rosa ", "pink", "magenta", "fucsia", "fuchsia", "rubor", "blush"],
|
|
296
|
+
},
|
|
297
|
+
];
|
|
298
|
+
function colorHues(text) {
|
|
299
|
+
const haystack = plain(text);
|
|
300
|
+
return COLOR_WORDS.find((row) => row.words.some((word) => haystack.includes(` ${word}`)))?.hues;
|
|
301
|
+
}
|
|
202
302
|
/** FNV-1a, 32 bits: a stable number for a string. */
|
|
203
303
|
function hash(text) {
|
|
204
304
|
let h = 0x811c9dc5;
|
|
@@ -229,7 +329,8 @@ function draftColors(input) {
|
|
|
229
329
|
const fromLine = lineMood(`${input.name} ${input.idea}`);
|
|
230
330
|
const base = fromLine?.mood ?? MOODS[Math.floor(roll(input.seed, "mood") * MOODS.length)];
|
|
231
331
|
const mood = base ?? "calm";
|
|
232
|
-
|
|
332
|
+
// A color the name says comes first, then one the idea says, then the business's own range.
|
|
333
|
+
const [from, to] = colorHues(input.name) ?? colorHues(input.idea) ?? fromLine?.hues ?? [0, 360];
|
|
233
334
|
const firstHue = from + roll(input.seed, "hue") * (to - from);
|
|
234
335
|
const k = input.picks.colors;
|
|
235
336
|
// The business's own mood holds for two presses, then the moods take turns.
|
|
@@ -307,7 +408,9 @@ export async function draftBrand(input, ctx) {
|
|
|
307
408
|
ink: light.onPrimary,
|
|
308
409
|
});
|
|
309
410
|
}
|
|
310
|
-
const
|
|
411
|
+
const picked = (input.tagline ?? "").trim().slice(0, DRAFT_LIMITS.idea);
|
|
412
|
+
const tagline = picked || idea || name;
|
|
413
|
+
const subtitle = picked || idea;
|
|
311
414
|
const draft = {
|
|
312
415
|
$schema: BRAND_SCHEMA_URL,
|
|
313
416
|
schemaVersion: 1,
|
|
@@ -318,8 +421,9 @@ export async function draftBrand(input, ctx) {
|
|
|
318
421
|
copy: {
|
|
319
422
|
[input.locale]: {
|
|
320
423
|
tagline,
|
|
321
|
-
|
|
322
|
-
|
|
424
|
+
// What the business does, which a picked tagline doesn't replace.
|
|
425
|
+
description: idea || tagline,
|
|
426
|
+
card: { title: name, ...(subtitle ? { subtitle } : {}) },
|
|
323
427
|
},
|
|
324
428
|
},
|
|
325
429
|
mark: {
|
|
@@ -344,14 +448,18 @@ export async function draftBrand(input, ctx) {
|
|
|
344
448
|
return parsed.brand;
|
|
345
449
|
}
|
|
346
450
|
const PICK_KEYS = ["colors", "fonts", "logo"];
|
|
347
|
-
/** The draft as link parameters: name, idea, locale, seed, colors, fonts and
|
|
451
|
+
/** The draft as link parameters: name, idea, a picked tagline, locale, seed, colors, fonts and
|
|
452
|
+
* logo. */
|
|
348
453
|
export function draftParams(input) {
|
|
349
454
|
const params = new URLSearchParams({
|
|
350
455
|
name: input.name.trim().slice(0, DRAFT_LIMITS.name),
|
|
351
456
|
idea: input.idea.trim().slice(0, DRAFT_LIMITS.idea),
|
|
352
|
-
locale: input.locale,
|
|
353
|
-
seed: String(input.seed),
|
|
354
457
|
});
|
|
458
|
+
const tagline = input.tagline?.trim().slice(0, DRAFT_LIMITS.idea);
|
|
459
|
+
if (tagline)
|
|
460
|
+
params.set("tagline", tagline);
|
|
461
|
+
params.set("locale", input.locale);
|
|
462
|
+
params.set("seed", String(input.seed));
|
|
355
463
|
for (const key of PICK_KEYS)
|
|
356
464
|
params.set(key, String(input.picks[key]));
|
|
357
465
|
return params;
|
|
@@ -366,11 +474,12 @@ function count(value, max) {
|
|
|
366
474
|
export function readDraftParams(params) {
|
|
367
475
|
const name = params.get("name")?.trim() ?? "";
|
|
368
476
|
const idea = params.get("idea")?.trim() ?? "";
|
|
477
|
+
const tagline = params.get("tagline")?.trim() ?? "";
|
|
369
478
|
const locale = LOCALES.find((code) => code === params.get("locale"));
|
|
370
479
|
const seed = count(params.get("seed"), 2147483647);
|
|
371
480
|
if (!name || name.length > DRAFT_LIMITS.name || idea.length > DRAFT_LIMITS.idea)
|
|
372
481
|
return null;
|
|
373
|
-
if (!locale || !seed)
|
|
482
|
+
if (tagline.length > DRAFT_LIMITS.idea || !locale || !seed)
|
|
374
483
|
return null;
|
|
375
484
|
const picks = { colors: 0, fonts: 0, logo: 0 };
|
|
376
485
|
for (const key of PICK_KEYS) {
|
|
@@ -379,5 +488,5 @@ export function readDraftParams(params) {
|
|
|
379
488
|
return null;
|
|
380
489
|
picks[key] = value;
|
|
381
490
|
}
|
|
382
|
-
return { name, idea, locale, seed, picks };
|
|
491
|
+
return { name, idea, ...(tagline ? { tagline } : {}), locale, seed, picks };
|
|
383
492
|
}
|
package/dist/files/docs.d.ts
CHANGED
|
@@ -23,6 +23,8 @@ export type HeadOptions = {
|
|
|
23
23
|
base?: string;
|
|
24
24
|
/** The absolute URL of the share card, like https://acme.com/og.png. */
|
|
25
25
|
ogImage?: string;
|
|
26
|
+
/** The card's alt text when the card is a page's own (generate's `pages`), not the brand's. */
|
|
27
|
+
imageAlt?: string;
|
|
26
28
|
locale?: Locale;
|
|
27
29
|
/** The page title, when it is not the brand's name. */
|
|
28
30
|
title?: string;
|
package/dist/files/docs.js
CHANGED
|
@@ -247,7 +247,7 @@ export function headTags(brand, options = {}) {
|
|
|
247
247
|
`<meta property="og:description" content="${escapeHtml(copy.description)}">`,
|
|
248
248
|
];
|
|
249
249
|
if (options.ogImage) {
|
|
250
|
-
tags.push(`<meta property="og:image" content="${escapeHtml(options.ogImage)}">`, '<meta property="og:image:width" content="1200">', '<meta property="og:image:height" content="630">', `<meta property="og:image:alt" content="${escapeHtml(ogAlt(brand, options.locale))}">`, '<meta name="twitter:card" content="summary_large_image">');
|
|
250
|
+
tags.push(`<meta property="og:image" content="${escapeHtml(options.ogImage)}">`, '<meta property="og:image:width" content="1200">', '<meta property="og:image:height" content="630">', `<meta property="og:image:alt" content="${escapeHtml(options.imageAlt ?? ogAlt(brand, options.locale))}">`, '<meta name="twitter:card" content="summary_large_image">');
|
|
251
251
|
}
|
|
252
252
|
return tags;
|
|
253
253
|
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** The kit's version, kept equal to package.json's (src/brand/schema.test.ts checks it). */
|
|
2
|
-
export declare const VERSION = "0.1.0-next.
|
|
2
|
+
export declare const VERSION = "0.1.0-next.3";
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** The kit's version, kept equal to package.json's (src/brand/schema.test.ts checks it). */
|
|
2
|
-
export const VERSION = "0.1.0-next.
|
|
2
|
+
export const VERSION = "0.1.0-next.3";
|
package/package.json
CHANGED