chore: updated reference design to app changes and fixes

This commit is contained in:
Florian Sylvain committed 2026-10-29 18:07:06 +01:00
1 parent 8cdd70bd81
commit c6d49db95e
25 files changed
+287 -104

No files matched your search

+10 -7
View File
@@ -29,7 +29,7 @@ class Component extends DCLogic {
const TONES = ['var(--rc-sand)', 'var(--ui-bg-accented)', 'color-mix(in srgb, var(--ui-border-accented) 35%, var(--ui-bg))', 'var(--ui-bg-elevated)']
const mark = h('svg', { width: 28, height: 28, viewBox: '0 0 16 16', shapeRendering: 'crispEdges' }, h('rect', { width: 16, height: 16, fill: '#111' }), h('path', { fill: '#fff', fillRule: 'evenodd', d: 'M4 3h6v1h1v1h1v3h-1v1h-1v1h1v1h1v2h-2v-2h-1v-1H6v3H4zm2 2v3h4V5z' }))
const Th = (im, t = '', z = 24) => D('position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;color:var(--ui-text-muted);background:' + (im.alpha ? CHECK : 'repeating-linear-gradient(135deg, var(--ui-border) 0 1px, transparent 1px 12px), ' + TONES[im.tone % 4]) + ';' + t, im.svg ? mark : I('image', z, 'opacity:0.55'))
const BADGE = { unused: ['background:var(--rc-warning-soft);color:var(--ui-warning)', 'unlink'], dup: ['background:var(--rc-info-soft);color:var(--ui-info)', 'copy'], used: ['border:1px solid var(--ui-border-accented);color:var(--ui-text-toned)'], on: ['background:var(--ui-bg-inverted);color:var(--ui-text-inverted)', 'globe'], draft: ['border:1px solid var(--ui-border-accented);color:var(--ui-text-toned)', 'pencil-line'], vars: ['background:var(--rc-info-soft);color:var(--ui-info)', 'layers'] }
const BADGE = { unused: ['background:var(--rc-warning-soft);color:var(--ui-warning)', 'unlink'], dup: ['background:var(--rc-info-soft);color:var(--ui-info)', 'copy'], used: ['border:1px solid var(--ui-border-accented);background:var(--ui-bg);color:var(--ui-text-toned)'], on: ['background:var(--ui-bg-inverted);color:var(--ui-text-inverted)', 'globe'], draft: ['border:1px solid var(--ui-border-accented);background:var(--ui-bg);color:var(--ui-text-toned)', 'pencil-line'], vars: ['background:var(--rc-info-soft);color:var(--ui-info)', 'layers'] }
const varsBadge = im => im.vc > 0 && Bd(im.vc + (im.vc === 1 ? ' variant' : ' variants'), 'vars')
const Bd = (t, k, sz = 20) => S('height:' + sz + 'px;padding:0 6px;display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:500;white-space:nowrap;' + BADGE[k][0], BADGE[k][1] && I(BADGE[k][1], 12), t)
const Cb = (on, z = 20, ind) => S('width:' + z + 'px;height:' + z + 'px;flex-shrink:0;display:flex;align-items:center;justify-content:center;border:1px solid ' + (on || ind ? 'var(--ui-primary)' : 'var(--ui-border-accented)') + ';background:' + (on || ind ? 'var(--ui-primary)' : 'var(--ui-bg)') + ';color:var(--ui-bg)', (on || ind) && I(ind ? 'minus' : 'check', z - 6))
@@ -54,16 +54,17 @@ class Component extends DCLogic {
const VC = { 1: 4, 2: 5, 3: 5, 4: 0, 5: 3, 6: 0, 7: 2, 8: 0, 9: 1, 10: 3, 11: 4, 12: 5 }
IM.forEach(x => { x.vc = VC[x.id] || 0 })
const ENT = { 10: 3, 11: 5 }
IM.forEach(x => { x.ent = s.ent ? (ENT[x.id] || 0) : 0 })
IM.forEach(x => { x.ent = s.ent ? (ENT[x.id] || 0) : 0; x.ex = 0 })
const byId = id => IM.find(x => x.id === id)
if (s.panel && s.panel.ext) byId(s.panel.id).ex = s.panel.ext === 'both' ? 2 : s.panel.ext === 'none' ? 0 : 1
const AR = [['How we price a bathroom renovation', 1], ['Winter checklist for timber windows', 0], ['Before and after: the Rue Verte kitchen', 1], ['Why we reuse original floorboards', 1], ['Choosing lime plaster for old stone walls', 0]]
const usedList = n => AR.slice(0, Math.min(n, 5))
const ids = s.ids || IM.map(x => x.id)
const imgs = ids.map(byId)
const sel = s.sel || []
const pl = n => n + (n === 1 ? ' article' : ' articles')
const label = im => im.n + ', ' + im.sz + ', ' + (im.used + im.ent ? 'used in ' + [im.used && pl(im.used), im.ent && (im.ent + (im.ent === 1 ? ' entry' : ' entries'))].filter(Boolean).join(' and ') : 'unused')
const usedBadge = im => { const n = im.used + im.ent, b = n ? Bd('Used in ' + n, 'used') : Bd('Unused', 'unused'); return s.tip === im.id ? S('position:relative;display:inline-flex', b, D('position:absolute;left:0;top:26px;z-index:10;padding:6px 8px;background:var(--ui-bg-inverted);color:var(--ui-text-inverted);font-size:12px;line-height:18px;white-space:nowrap;box-shadow:var(--rc-shadow-pop)', im.used > 0 && D('', 'Used in articles: ' + im.used), D('', 'Used in entries: ' + im.ent))) : b }
const label = im => im.n + ', ' + im.sz + ', ' + (im.used + im.ent + (im.ex || 0) ? 'used in ' + [im.used && pl(im.used), im.ent && (im.ent + (im.ent === 1 ? ' entry' : ' entries')), im.ex && (im.ex + ' other ' + (im.ex === 1 ? 'place' : 'places'))].filter(Boolean).join(' and ') : 'unused')
const usedBadge = im => { const n = im.used + im.ent + (im.ex || 0), b = n ? Bd('Used in ' + n, 'used') : Bd('Unused', 'unused'); return s.tip === im.id ? S('position:relative;display:inline-flex', b, D('position:absolute;left:0;top:26px;z-index:10;padding:6px 8px;background:var(--ui-bg-inverted);color:var(--ui-text-inverted);font-size:12px;line-height:18px;white-space:nowrap;box-shadow:var(--rc-shadow-pop)', im.used > 0 && D('', 'Used in articles: ' + im.used), D('', 'Used in entries: ' + im.ent))) : b }
// ---------- Media page pieces
const Card = im => {
@@ -200,6 +201,7 @@ class Component extends DCLogic {
// ---------- detail panel
const ENTL = [['Events', 'Lime plaster workshop'], ['Events', 'Heritage stone walk'], ['Events', 'Winter open day']]
const EntBox = im => D('display:flex;flex-direction:column;gap:8px', S('font:600 14px/22px \'IBM Plex Sans\',sans-serif;color:var(--ui-text-highlighted)', 'Used in entries'), D('border:1px solid var(--ui-border)', ...ENTL.map(([ty, tt], i) => D('display:flex;align-items:center;gap:8px;min-height:' + (m ? 48 : 36) + 'px;padding:0 12px;border-top:' + (i ? '1px solid var(--ui-border-muted)' : '0'), S('width:52px;flex-shrink:0;font-size:12px;color:var(--ui-text-muted)', ty), S('flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;text-decoration:underline;text-underline-offset:3px;color:var(--ui-text-highlighted)', tt), I('arrow-up-right', 14, 'color:var(--ui-text-muted)'))), im.ent > 3 && D('padding:8px 12px;border-top:1px solid var(--ui-border-muted);color:var(--ui-text-muted)', 'and ' + (im.ent - 3) + ' more')))
const ExtBox = ext => D('display:flex;flex-direction:column;gap:8px', S('font:600 14px/22px \'IBM Plex Sans\',sans-serif;color:var(--ui-text-highlighted)', 'Used elsewhere'), D('border:1px solid var(--ui-border)', ...[['avatar', 'Author avatar', '/authors'], ['site', 'Site default social image', '/settings/sites']].filter(r => ext === 'both' || ext === r[0]).map(([k, t, href], i) => D('display:flex;align-items:center;gap:8px;min-height:' + (m ? 48 : 40) + 'px;padding:0 12px;border-top:' + (i ? '1px solid var(--ui-border-muted)' : '0'), S('flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;text-decoration:underline;text-underline-offset:3px;color:var(--ui-text-highlighted)', t), S('font:400 12px \'IBM Plex Mono\',monospace;color:var(--ui-text-muted)', href), I('arrow-up-right', 14, 'color:var(--ui-text-muted)')))))
const Panel = () => {
const im = byId(s.panel.id), list = usedList(im.used)
const meta = [['Type', im.ty], ['Size', im.sz], ['Dimensions', im.dim], ['Uploaded', im.d], ['Uploaded by', im.by]]
@@ -209,13 +211,14 @@ class Component extends DCLogic {
D('height:' + (m ? 56 : 56) + 'px;flex-shrink:0;display:flex;align-items:center;gap:' + (m ? 4 : 12) + 'px;padding:0 ' + (m ? 6 : 20) + 'px;border-bottom:1px solid var(--ui-border)', m && S('width:44px;height:44px;display:flex;align-items:center;justify-content:center', I('arrow-left', 20)), S('flex:1;min-width:0;font:600 16px/24px \'IBM Plex Sans\',sans-serif;color:var(--ui-text-highlighted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap', im.n), !m && S('width:28px;height:28px;display:flex;align-items:center;justify-content:center;color:var(--ui-text-muted)', I('x'))),
D('flex:1;min-height:0;overflow:hidden;padding:' + (m ? 16 : 20) + 'px;display:flex;flex-direction:column;gap:20px',
Th(im, 'aspect-ratio:' + (im.ent ? (m ? '16/3.6' : '16/6') : m ? '4/3' : '16/10') + ';border:1px solid var(--ui-border);flex-shrink:0', 40),
D('display:flex', usedBadge(im)),
D('display:flex;gap:8px;' + (m ? 'flex-wrap:wrap' : ''), B('Copy URL', { icon: 'link', full: m }), B('Rename', { icon: 'pencil', full: m }), B('Delete', { k: 'del', icon: 'trash-2', full: m })),
im.dup && Alert('info', 'copy', 'Identical to 2 other images', 'floorboards-copy.jpg and IMG_2208.jpg have the same content.', 'Review duplicates', { icon: 'arrow-right' }),
D('display:grid;grid-template-columns:110px minmax(0,1fr);gap:8px 12px;color:var(--ui-text-toned)', ...meta.flatMap(([k, v]) => [S('color:var(--ui-text-muted)', k), S('color:var(--ui-text-highlighted)', v)]), S('color:var(--ui-text-muted)', 'URL'), S('font:400 12px/20px \'IBM Plex Mono\',monospace;color:var(--ui-text-highlighted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap', 'cms.renew.example/media/' + im.n)),
D('display:flex;flex-direction:column;gap:8px', S('font:600 14px/22px \'IBM Plex Sans\',sans-serif;color:var(--ui-text-highlighted)', im.used ? 'Used in ' + pl(im.used) : 'Not used in any article'),
D('display:flex;flex-direction:column;gap:8px', S('font:600 14px/22px \'IBM Plex Sans\',sans-serif;color:var(--ui-text-highlighted)', im.used ? 'Used in ' + pl(im.used) : (im.ent || im.ex) ? 'Articles' : 'Not used in any article'),
im.used ? D('border:1px solid var(--ui-border)', ...list.map(([t, on], i) => D('display:flex;align-items:center;gap:8px;min-height:' + (m ? 48 : 40) + 'px;padding:0 12px;border-top:' + (i ? '1px solid var(--ui-border-muted)' : '0'), S('flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500;text-decoration:underline;text-underline-offset:3px;color:var(--ui-text-highlighted)', t), on ? Bd('Online', 'on', 22) : Bd('Draft', 'draft', 22), I('arrow-up-right', 14, 'color:var(--ui-text-muted)'))))
: S('color:var(--ui-text-muted)', im.ent ? 'No article shows it.' : 'This image is safe to delete. No article shows it.'),
im.used ? S('color:var(--ui-text-muted);font-size:12px', 'Counted from the text of your articles each time you open this page.') : null), im.ent > 0 && EntBox(im))))
: S('color:var(--ui-text-muted)', im.ent || im.ex ? 'No article shows it.' : 'This image is safe to delete. No article shows it.'),
im.used ? S('color:var(--ui-text-muted);font-size:12px', 'Counted from the text of your articles each time you open this page.') : null), im.ent > 0 && EntBox(im), im.ex > 0 && ExtBox(s.panel.ext))))
}
// ---------- modal