chore(badges): hex-only body_text_color + form color picker; renderer default black
This commit is contained in:
@@ -296,28 +296,17 @@ let qr_back_justify = $derived.by(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Body text color: can be a Tailwind `text-*` class or a hex value like `#112233`.
|
// Body text color: can be a Tailwind `text-*` class or a hex value like `#112233`.
|
||||||
let body_text_color_class = $derived.by(() => {
|
// Prefer an explicit hex fallback stored as `body_text_color_hex` in `cfg_json`.
|
||||||
const cfg = template_cfg || {};
|
// The `body_text_color` key may still contain a Tailwind class for styling
|
||||||
const raw = cfg?.body_text_color ?? cfg?.text_color ?? '';
|
// when the compiled CSS includes it; the hex ensures correct rendering when
|
||||||
if (!raw || typeof raw !== 'string') return '';
|
// classes are purged at build-time.
|
||||||
const v = raw.trim();
|
|
||||||
if (v.startsWith('text-')) return v;
|
|
||||||
// Map simple color names to Tailwind where reasonable (e.g., 'white' -> 'text-white')
|
|
||||||
if (/^[a-zA-Z]+$/.test(v)) {
|
|
||||||
const pick = v.toLowerCase();
|
|
||||||
const allowed = ['white','black','gray','red','blue','green','yellow','indigo','purple','pink'];
|
|
||||||
if (allowed.includes(pick)) return `text-${pick}`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
});
|
|
||||||
|
|
||||||
let body_text_color_style = $derived.by(() => {
|
let body_text_color_style = $derived.by(() => {
|
||||||
const cfg = template_cfg || {};
|
const cfg = template_cfg || {};
|
||||||
const raw = cfg?.body_text_color ?? cfg?.text_color ?? '';
|
const raw = cfg?.body_text_color ?? cfg?.text_color ?? '';
|
||||||
if (!raw || typeof raw !== 'string') return '';
|
if (!raw || typeof raw !== 'string') return 'color: #000000;';
|
||||||
const v = raw.trim();
|
const v = raw.trim();
|
||||||
if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v)) return `color: ${v};`;
|
if (/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(v)) return `color: ${v};`;
|
||||||
return '';
|
return 'color: #000000;';
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -686,7 +675,7 @@ const code_to_icon: {
|
|||||||
items-center
|
items-center
|
||||||
justify-end overflow-clip
|
justify-end overflow-clip
|
||||||
p-0 px-8 pb-1
|
p-0 px-8 pb-1
|
||||||
{body_text_color_class || 'text-white'}
|
text-black
|
||||||
gap-0
|
gap-0
|
||||||
"
|
"
|
||||||
style="{body_text_color_style}">
|
style="{body_text_color_style}">
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ let cfg_show_qr_back = $state(true);
|
|||||||
let cfg_hide_title = $state(false);
|
let cfg_hide_title = $state(false);
|
||||||
let cfg_hide_affiliations = $state(false);
|
let cfg_hide_affiliations = $state(false);
|
||||||
let cfg_hide_location = $state(false);
|
let cfg_hide_location = $state(false);
|
||||||
// Body text color: Tailwind class (e.g. 'text-black') or hex (e.g. '#000000')
|
// Body text color (hex)
|
||||||
let cfg_body_text_color = $state('text-black');
|
let cfg_body_text_color = $state('#000000');
|
||||||
// Alignment overrides: 'left' | 'center' | 'right' | 'justify'
|
// Alignment overrides: 'left' | 'center' | 'right' | 'justify'
|
||||||
let cfg_align_name = $state('center');
|
let cfg_align_name = $state('center');
|
||||||
let cfg_align_title = $state('center');
|
let cfg_align_title = $state('center');
|
||||||
@@ -128,8 +128,13 @@ async function load_template(id: string) {
|
|||||||
cfg_hide_affiliations = parsed_cfg.hasOwnProperty('hide_affiliations') ? !!parsed_cfg.hide_affiliations : false;
|
cfg_hide_affiliations = parsed_cfg.hasOwnProperty('hide_affiliations') ? !!parsed_cfg.hide_affiliations : false;
|
||||||
cfg_hide_location = parsed_cfg.hasOwnProperty('hide_location') ? !!parsed_cfg.hide_location : false;
|
cfg_hide_location = parsed_cfg.hasOwnProperty('hide_location') ? !!parsed_cfg.hide_location : false;
|
||||||
|
|
||||||
// Body text color
|
// Body text color (hex-only). Prefer explicit hex keys.
|
||||||
cfg_body_text_color = parsed_cfg.body_text_color ?? parsed_cfg.text_color ?? 'text-white';
|
const _hex_candidate = parsed_cfg.body_text_color_hex ?? parsed_cfg.body_text_color ?? parsed_cfg.text_color ?? '';
|
||||||
|
if (typeof _hex_candidate === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(_hex_candidate.trim())) {
|
||||||
|
cfg_body_text_color = _hex_candidate.trim();
|
||||||
|
} else {
|
||||||
|
cfg_body_text_color = '#000000';
|
||||||
|
}
|
||||||
|
|
||||||
// Alignment overrides (nested under cfg_json.align and cfg_json.qr_alignment)
|
// Alignment overrides (nested under cfg_json.align and cfg_json.qr_alignment)
|
||||||
cfg_align_name = parsed_cfg?.align?.name ?? parsed_cfg.align_name ?? 'center';
|
cfg_align_name = parsed_cfg?.align?.name ?? parsed_cfg.align_name ?? 'center';
|
||||||
@@ -190,8 +195,14 @@ async function handle_submit() {
|
|||||||
cfg_obj.qr_alignment.front = cfg_qr_alignment_front;
|
cfg_obj.qr_alignment.front = cfg_qr_alignment_front;
|
||||||
cfg_obj.qr_alignment.back = cfg_qr_alignment_back;
|
cfg_obj.qr_alignment.back = cfg_qr_alignment_back;
|
||||||
|
|
||||||
// Body text color (Tailwind class or hex)
|
// Body text color (hex-only)
|
||||||
cfg_obj.body_text_color = cfg_body_text_color;
|
if (typeof cfg_body_text_color === 'string' && /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(cfg_body_text_color.trim())) {
|
||||||
|
cfg_obj.body_text_color = cfg_body_text_color.trim();
|
||||||
|
} else {
|
||||||
|
// Remove any stale color keys to avoid keeping invalid values
|
||||||
|
if ((cfg_obj as any)?.body_text_color) delete (cfg_obj as any).body_text_color;
|
||||||
|
if ((cfg_obj as any)?.body_text_color_hex) delete (cfg_obj as any).body_text_color_hex;
|
||||||
|
}
|
||||||
|
|
||||||
const data_to_save: key_val = {
|
const data_to_save: key_val = {
|
||||||
name,
|
name,
|
||||||
@@ -432,8 +443,14 @@ function handle_cancel() {
|
|||||||
</select>
|
</select>
|
||||||
</label>
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<span>Body Text Color (Tailwind class or #hex)</span>
|
<span>Body Text Color (hex)</span>
|
||||||
<input type="text" bind:value={cfg_body_text_color} class="input" placeholder="text-black or #000000" />
|
<div class="flex items-center gap-2">
|
||||||
|
<input type="color" bind:value={cfg_body_text_color} class="w-10 h-8 p-0" />
|
||||||
|
<input type="text" bind:value={cfg_body_text_color} class="input w-32" placeholder="#rrggbb" />
|
||||||
|
</div>
|
||||||
|
<p class="text-xs text-surface-400 italic">
|
||||||
|
Pick a hex color (e.g. #112233). The renderer will use this inline color.
|
||||||
|
</p>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xs text-surface-400 italic">
|
<p class="text-xs text-surface-400 italic">
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import type { Config } from 'tailwindcss';
|
import type { Config } from 'tailwindcss';
|
||||||
|
|
||||||
|
// Tailwind's shipped `Config` type may not include the `safelist` option
|
||||||
|
// depending on the installed types/version. Extend it locally so we can
|
||||||
|
// use `safelist` without TypeScript errors.
|
||||||
|
type ConfigWithSafelist = Config & {
|
||||||
|
safelist?: Array<string | { pattern: RegExp }>;
|
||||||
|
};
|
||||||
import { skeleton } from '@skeletonlabs/skeleton';
|
import { skeleton } from '@skeletonlabs/skeleton';
|
||||||
import forms from '@tailwindcss/forms';
|
import forms from '@tailwindcss/forms';
|
||||||
import typography from '@tailwindcss/typography';
|
import typography from '@tailwindcss/typography';
|
||||||
@@ -40,6 +47,6 @@ const config = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
} satisfies Config;
|
} satisfies ConfigWithSafelist;
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
Reference in New Issue
Block a user