@taprootio/espalier 4.18.0 → 4.19.0
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/CHANGELOG.md +13 -0
- package/custom-elements.json +2466 -2399
- package/dist/cli/theme-check.js +2 -2
- package/dist/date-picker/helpers/styles.js +17 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/shared/theme-fit-report.d.ts +38 -2
- package/dist/shared/theme-fit-report.js +1 -1
- package/dist/shared/theme.d.ts +50 -0
- package/dist/shared/theme.js +1 -1
- package/package.json +1 -1
package/dist/cli/theme-check.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{encodeTheme as
|
|
2
|
-
`)}catch(c){return t.error(`Cannot write ${e.updateExpect}: ${c instanceof Error?c.message:String(c)}`),2}o(`Wrote fit tables to ${e.updateExpect}.`)}if(e.expect!==void 0){let c;try{c=t.readFile(e.expect)}catch{return t.error(`Expected fit tables not found at ${e.expect} \u2014 create them with --update-expect ${e.expect}.`),2}let a;try{a=JSON.parse(c)}catch{return t.error(`${e.expect} is not JSON.`),2}if(se(a))return t.error(`${e.expect} was written by espalier \u22644.2.0 \u2014 regenerate it with --update-expect ${e.expect}.`),2;if(!oe(a))return t.error(`${e.expect} is not a fit-table suite \u2014 regenerate it with --update-expect ${e.expect}.`),2;const f=le(a,n);if(f.length>0){s>0&&we(n,s,t);for(const u of f)t.error(`drift: ${u}`);return t.error(`Fit tables drifted from ${e.expect} (${f.length} difference(s)). Review, then refresh deliberately with --update-expect.`),1}o(`Fit tables match ${e.expect}.`)}return e.json?(t.log(JSON.stringify(n,null,2)),s>0?1:0):(xe(n,s,t),s>0?1:0)}function oe(e){if(!p(e)||!k.every(({field:r,kind:i})=>T(e[String(r)],i)))return!1;const t=e;if(!I(t.surfaces))return!1;for(const r of["light","dark"]){const n=t.paletteLints[r].map(g);if(!I(n))return!1;const s=t[r],o=new Set;for(const c of s){if(!pe(c,r)||!t.surfaces.includes(c.surface)||o.has(c.surface))return!1;o.add(c.surface)}}return!0}function se(e){return p(e)&&H(e.surfaces)&&Array.isArray(e.light)&&Array.isArray(e.dark)&&!("dataPalette"in e)&&!("paletteLints"in e)}function ce(e){return typeof e=="number"&&Number.isFinite(e)}function H(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}function I(e){return new Set(e).size===e.length}function ae(e){return p(e)&&M.every(({field:t,kind:r})=>T(e[String(t)],r))}function fe(e){return p(e)&&R.every(({field:t,kind:r})=>T(e[String(t)],r))}function ue(e){return p(e)&&x.every(({field:t,kind:r})=>T(e[String(t)],r))}function T(e,t){switch(t){case"anchor":return e===void 0||V(e,C);case"anchor-record":return p(e)&&Object.keys(e).every(te)&&Object.values(e).every(r=>typeof r=="string");case"apca":return e===void 0||V(e,N);case"boolean":return typeof e=="boolean";case"data-palette-record":return p(e)?["light","dark"].every(r=>{const i=e[r];return p(i)&&w.every(n=>typeof i[n]=="string")}):!1;case"explicit":return e===void 0||Y.includes(e);case"fit-lint-id":return B.includes(e);case"lint-array":return Array.isArray(e)&&e.every(fe);case"message":case"string":return typeof e=="string";case"number":return ce(e);case"palette-lint-id":return X.includes(e);case"palette-lint-record":return p(e)&&["light","dark"].every(r=>Array.isArray(e[r])&&e[r].every(ae));case"report-array":return Array.isArray(e);case"scheme":return e==="light"||e==="dark";case"semantic":return P(e);case"semantic-array":return Array.isArray(e)&&e.every(P);case"series-pair":return de(e);case"simulation":return v.includes(e);case"string-array":return H(e);case"token-array":return Array.isArray(e)&&e.every(ue);case"warning":return Q.includes(e);default:{const r=t;return!1}}}function V(e,t){return p(e)&&t.every(({field:r,kind:i})=>T(e[String(r)],i))}function de(e){if(!Array.isArray(e)||e.length!==2)return!1;const t=w.indexOf(e[0]),r=w.indexOf(e[1]);return t>=0&&r>t}function pe(e,t){if(!p(e)||!_.every(({field:i,kind:n})=>T(e[String(i)],n)))return!1;const r=e;return r.scheme!==t?!1:I(r.tokens.map(i=>i.token))&&I(r.adjustedTokens)&&I(r.lints.map(i=>i.id))}function le(e,t){const r=[];for(const n of k)n.compared&&me(r,n,e,t);return(h(z(e))!==h(z(t))||r.length===0&&h(e)!==h(t))&&r.push("fit tables differ outside compared fields"),r}function me(e,t,r,i){const{field:n,kind:s}=t;if(s==="string-array"){const o=r[n],c=i[n];U(e,String(n),o,c),E(e,String(n),o,c);return}if(s==="data-palette-record"){const o=r[n],c=i[n];for(const a of["light","dark"])for(const f of w)K(e,`${a}/${String(n)}/${f}`,o[a][f],c[a][f]);return}if(s==="palette-lint-record"){const o=r[n],c=i[n];for(const a of["light","dark"])ke(e,a,String(n),o[a],c[a]),E(e,`${a}/${String(n)}`,o[a].map(g),c[a].map(g));return}if(s==="report-array"&&(n==="light"||n==="dark")){he(e,n,r[n],i[n]);return}F(e,"fit tables",String(n),r[n],i[n],s)}function he(e,t,r,i){const n=new Map(r.map(o=>[o.surface,o])),s=new Map(i.map(o=>[o.surface,o]));E(e,`${t}/reports`,r.map(o=>o.surface),i.map(o=>o.surface));for(const o of L(n.keys(),s.keys())){const c=n.get(o),a=s.get(o),f=`${t}/${o}`;if(!c||!a){e.push(`${f}: surface ${c?"removed":"added"}`);continue}ge(e,f,c,a)}}function ge(e,t,r,i){for(const n of _){const{compared:s,field:o,kind:c}=n;if(!(!s||o==="scheme"||o==="surface")){if(c==="anchor-record"){Te(e,`${t}/${String(o)}`,r[o],i[o]);continue}if(c==="semantic-array"){const a=r[o],f=i[o];U(e,`${t}/${String(o)}`,a,f),E(e,`${t}/${String(o)}`,a,f);continue}if(c==="lint-array"){const a=r[o],f=i[o];Se(e,t,String(o),a,f),E(e,`${t}/${String(o)}`,a.map(u=>u.id),f.map(u=>u.id));continue}if(c==="token-array"){$e(e,t,String(o),r[o],i[o]);continue}F(e,t,String(o),r[o],i[o],c)}}}function $e(e,t,r,i,n){const s=new Map(i.map(a=>[a.token,a])),o=new Map(n.map(a=>[a.token,a]));E(e,`${t}/${r}`,i.map(a=>a.token),n.map(a=>a.token));const c=r==="tokens"?t:`${t}/${r}`;for(const a of L(s.keys(),o.keys())){const f=s.get(a),u=o.get(a),S=`${c}/${a}`;if(!f||!u){e.push(`${S}: token ${f?"removed":"added"}`);continue}ye(e,S,f,u)}}function ye(e,t,r,i){for(const{compared:n,field:s,kind:o}of x)if(!(!n||s==="token")){if(o==="anchor"){J(e,t,"anchor",r.anchor,i.anchor,C);continue}if(o==="apca"){J(e,t,"apca",r.apca,i.apca,N);continue}F(e,t,String(s),r[s],i[s],o)}}function J(e,t,r,i,n,s){const o=i,c=n;for(const{compared:a,field:f,kind:u}of s)a&&F(e,t,`${r}.${String(f)}`,o?.[f],c?.[f],u)}function Se(e,t,r,i,n){const s=new Map(i.map(c=>[c.id,c])),o=new Map(n.map(c=>[c.id,c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of R)if(!(!S||d==="id")){if(b==="semantic-array"){Ee(e,u,String(d),a[d],f[d]);continue}F(e,u,String(d),a[d],f[d],b)}}}function ke(e,t,r,i,n){const s=new Map(i.map(c=>[g(c),c])),o=new Map(n.map(c=>[g(c),c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of M)!S||d==="id"||d==="series"||d==="simulation"||F(e,u,String(d),a[d],f[d],b)}}function g(e){return`${e.id}/${e.series[0]}+${e.series[1]}/${e.simulation}`}function Te(e,t,r,i){for(const n of L(Object.keys(r),Object.keys(i)))K(e,`${t}/${n}`,r[n],i[n])}function U(e,t,r,i){const n=new Set(r),s=new Set(i);for(const o of L(n,s))n.has(o)!==s.has(o)&&e.push(`${t}/${o}: ${n.has(o)?"removed":"added"}`)}function E(e,t,r,i){const n=new Set(r),s=new Set(i),o=r.filter(a=>s.has(a)),c=i.filter(a=>n.has(a));o.some((a,f)=>a!==c[f])&&e.push(`${t}: order changed`)}function Ee(e,t,r,i,n){const s=Math.max(i.length,n.length);for(let o=0;o<s;o+=1)W(e,t,`${r}[${o}]`,i[o],n[o])}function K(e,t,r,i){r!==i&&e.push(`${t}: ${j(r)} \u2192 ${j(i)}`)}function W(e,t,r,i,n,s){if(!Object.is(i,n)){if(s==="message"){e.push(`${t}: message changed`);return}e.push(`${t}: ${r} ${j(i)} \u2192 ${j(n)}`)}}function Fe(e,t,r,i,n){h(i)!==h(n)&&e.push(`${t}: ${r} changed`)}function F(e,t,r,i,n,s){if(_e(s)){W(e,t,r,i,n,s);return}Fe(e,t,r,i,n)}const Le={anchor:!1,"anchor-record":!1,apca:!1,boolean:!0,"data-palette-record":!1,explicit:!0,"fit-lint-id":!0,"lint-array":!1,message:!0,number:!0,"palette-lint-id":!0,"palette-lint-record":!1,"report-array":!1,scheme:!0,semantic:!0,"semantic-array":!1,"series-pair":!1,simulation:!0,string:!0,"string-array":!1,"token-array":!1,warning:!0};function _e(e){return Le[e]===!0}function j(e){return e===void 0?"(absent)":e===""?'""':String(e)}function L(e,t){return[...new Set([...e,...t])].sort()}function h(e){return Array.isArray(e)?`[${e.map(h).join(",")}]`:p(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${h(e[t])}`).join(",")}}`:JSON.stringify(e)??"undefined"}function z(e){const t=m(e,$(k)),r=["light","dark"];if(y(k,"dataPalette")){const i=m(e.dataPalette,r);for(const n of r)l(i,n,m(e.dataPalette[n],w));l(t,"dataPalette",i)}if(y(k,"paletteLints")){const i=m(e.paletteLints,r);for(const n of r)l(i,n,q(e.paletteLints[n],g,$(M)));l(t,"paletteLints",i)}for(const i of r){if(!y(k,i))continue;const n=O();for(const s of e[i]){const o=m(s,$(_));if(y(_,"tokens")){const c=O();for(const a of s.tokens){const f=m(a,$(x));a.anchor&&y(x,"anchor")&&l(f,"anchor",m(a.anchor,$(C))),a.apca&&y(x,"apca")&&l(f,"apca",m(a.apca,$(N))),l(c,a.token,f)}l(o,"tokens",c)}y(_,"lints")&&l(o,"lints",q(s.lints,c=>c.id,$(R))),l(n,s.surface,o)}l(t,i,n)}return t}function q(e,t,r){const i=O();for(const n of e)l(i,t(n),m(n,r));return i}function $(e){return e.filter(({compared:t})=>t).map(({field:t})=>t)}function y(e,t){return e.some(r=>r.field===t&&r.compared)}function m(e,t){const r=new Set(t.map(String)),i=O();for(const[n,s]of Object.entries(e))r.has(n)||(i[n]=s);return i}function O(){return Object.create(null)}function l(e,t,r){Object.keys(r).length>0&&(e[t]=r)}function xe(e,t,r){for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.log(` ${i} lint(${n.id}): ${n.message}`);for(const n of e[i]){r.log(be(i,n));for(const s of n.lints)r.log(` lint(${s.id}): ${s.message}`)}}r.log(`Checked ${e.surfaces.length} surface(s) \xD7 2 schemes \u2014 `+(t===0?"no lints.":`${t} lint(s), listed above.`))}function we(e,t,r){r.error(`${t} theme lint(s) are standing while fit-table drift is present:`);for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.error(`lint: ${i}/paletteLints/${g(n)}: ${n.message}`);for(const n of e[i])for(const s of n.lints)r.error(`lint: ${i}/${n.surface}/lints/${s.id}: ${s.message}`)}}function Ae(e){return[...e.light,...e.dark].reduce((r,i)=>r+i.lints.length,0)+e.paletteLints.light.length+e.paletteLints.dark.length}function Ie(e,t){return["light","dark"].some(r=>{const i=`${r}: `;if(!e.startsWith(i))return!1;const n=e.slice(i.length);return t.paletteLints[r].some(s=>ee(n,s))})}function be(e,t){const r=t.adjustedTokens.length===0?"contrast enforcement moved nothing":`contrast enforcement moved ${t.adjustedTokens.join(", ")}`,i=t.tokens.filter(s=>s.explicit==="inherited").length,n=i===0?"":`; ${i} inherited explicit pin(s) \u2014 see the fit tables`;return`${e}/${t.surface}: ${t.tokens.length} tokens, ${r}${n}.`}export{Me as runEspalierCli};
|
|
1
|
+
import{encodeTheme as P,isObjectRecord as p,isSemanticColorName as D,validateThemePair as G}from"../shared/theme.js";import{THEME_FIT_ANCHOR_FIELDS as N,THEME_FIT_APCA_FIELDS as C,THEME_FIT_DATA_PALETTE_LINT_FIELDS as M,THEME_FIT_DATA_PALETTE_LINT_IDS as X,THEME_FIT_EXPLICIT_VALUES as Y,THEME_FIT_LINT_FIELDS as R,THEME_FIT_LINT_IDS as B,THEME_FIT_LINT_SEVERITIES as Q,THEME_FIT_PAIRING_VALUES as Z,THEME_FIT_REPORT_FIELDS as _,THEME_FIT_SUITE_FIELDS as k,THEME_FIT_TOKEN_FIELDS as x,themeFitReportSuite as v}from"../shared/theme-fit-report.js";import{COLOR_VISION_SIMULATIONS as ee,DATA_SERIES_KEYS as A,isPaletteCollisionDescription as te}from"../shared/data-colors.js";import{isSafeKey as re}from"../shared/unsafe-keys.js";const I="usage: espalier theme check <theme.json> [--json] [--expect <fit.json>] [--update-expect <fit.json>]";function Re(e,t){const[r,i,...n]=e;if(r!=="theme"||i!=="check")return t.error(I),2;const s=ne(n,t);return s?oe(s,t):2}function ne(e,t){const r={file:"",json:!1};for(let i=0;i<e.length;i+=1){const n=e[i];if(n==="--json")r.json=!0;else if(n==="--expect"||n==="--update-expect"){const s=e[i+1];if(s===void 0)return t.error(`${n} requires a file path. ${I}`),null;n==="--expect"?r.expect=s:r.updateExpect=s,i+=1}else if(!n.startsWith("--")&&r.file==="")r.file=n;else return t.error(`Unknown argument "${n}". ${I}`),null}return r.file===""?(t.error(I),null):r.expect!==void 0&&r.updateExpect!==void 0?(t.error(`--expect checks the committed fit tables and --update-expect rewrites them \u2014 pick one. ${I}`),null):r}function ie(e,t){let r;try{r=t.readFile(e)}catch(s){return t.error(`Cannot read ${e}: ${s instanceof Error?s.message:String(s)}`),null}let i;try{i=JSON.parse(r)}catch(s){return t.error(`${e} is not JSON: ${s instanceof Error?s.message:String(s)}`),null}if(typeof i!="object"||i===null||Array.isArray(i))return t.error(`${e} must contain a theme object.`),null;const n=i;if("light"in n||"dark"in n){for(const s of["light","dark"]){const o=n[s];if(o!==void 0&&(typeof o!="object"||o===null||Array.isArray(o)))return t.error(`${e}: "${s}" must be a theme object.`),null}return{light:n.light??{},dark:n.dark??{}}}return{light:n,dark:n}}function oe(e,t){const r=ie(e.file,t);if(!r)return 2;const i=G(P(r.light),P(r.dark));if(!i.valid){for(const c of i.warnings)t.error(`warning: ${c}`);for(const c of i.errors)t.error(`error: ${c}`);return t.error(`${e.file}: ${i.errors.length} validation error(s).`),1}const n=v(r.light,r.dark);for(const c of i.warnings)be(c,n)||t.error(`warning: ${c}`);const s=we(n),o=e.json?t.error:t.log;if(e.updateExpect!==void 0){try{t.writeFile(e.updateExpect,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`)}catch(c){return t.error(`Cannot write ${e.updateExpect}: ${c instanceof Error?c.message:String(c)}`),2}o(`Wrote fit tables to ${e.updateExpect}.`)}if(e.expect!==void 0){let c;try{c=t.readFile(e.expect)}catch{return t.error(`Expected fit tables not found at ${e.expect} \u2014 create them with --update-expect ${e.expect}.`),2}let a;try{a=JSON.parse(c)}catch{return t.error(`${e.expect} is not JSON.`),2}if(ce(a))return t.error(`${e.expect} was written by espalier \u22644.2.0 \u2014 regenerate it with --update-expect ${e.expect}.`),2;if(!se(a))return t.error(`${e.expect} is not a fit-table suite \u2014 regenerate it with --update-expect ${e.expect}.`),2;const f=me(a,n);if(f.length>0){s>0&&Ie(n,s,t);for(const u of f)t.error(`drift: ${u}`);return t.error(`Fit tables drifted from ${e.expect} (${f.length} difference(s)). Review, then refresh deliberately with --update-expect.`),1}o(`Fit tables match ${e.expect}.`)}return e.json?(t.log(JSON.stringify(n,null,2)),s>0?1:0):(Ae(n,s,t),s>0?1:0)}function se(e){if(!p(e)||!k.every(({field:r,kind:i})=>T(e[String(r)],i)))return!1;const t=e;if(!w(t.surfaces))return!1;for(const r of["light","dark"]){const n=t.paletteLints[r].map(h);if(!w(n))return!1;const s=t[r],o=new Set;for(const c of s){if(!le(c,r)||!t.surfaces.includes(c.surface)||o.has(c.surface))return!1;o.add(c.surface)}}return!0}function ce(e){return p(e)&&H(e.surfaces)&&Array.isArray(e.light)&&Array.isArray(e.dark)&&!("dataPalette"in e)&&!("paletteLints"in e)}function ae(e){return typeof e=="number"&&Number.isFinite(e)}function H(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")}function w(e){return new Set(e).size===e.length}function fe(e){return p(e)&&M.every(({field:t,kind:r})=>T(e[String(t)],r))}function ue(e){return p(e)&&R.every(({field:t,kind:r})=>T(e[String(t)],r))}function de(e){return p(e)&&x.every(({field:t,kind:r})=>T(e[String(t)],r))}function T(e,t){switch(t){case"anchor":return e===void 0||V(e,N);case"anchor-record":return p(e)&&Object.keys(e).every(re)&&Object.values(e).every(r=>typeof r=="string");case"apca":return e===void 0||V(e,C);case"boolean":return typeof e=="boolean";case"data-palette-record":return p(e)?["light","dark"].every(r=>{const i=e[r];return p(i)&&A.every(n=>typeof i[n]=="string")}):!1;case"explicit":return e===void 0||Y.includes(e);case"fit-lint-id":return B.includes(e);case"lint-array":return Array.isArray(e)&&e.every(ue);case"message":case"string":return typeof e=="string";case"number":return ae(e);case"pairing":return e===void 0||Z.includes(e);case"palette-lint-id":return X.includes(e);case"palette-lint-record":return p(e)&&["light","dark"].every(r=>Array.isArray(e[r])&&e[r].every(fe));case"report-array":return Array.isArray(e);case"scheme":return e==="light"||e==="dark";case"semantic":return D(e);case"semantic-array":return Array.isArray(e)&&e.every(D);case"series-pair":return pe(e);case"simulation":return ee.includes(e);case"string-array":return H(e);case"token-array":return Array.isArray(e)&&e.every(de);case"warning":return Q.includes(e);default:{const r=t;return!1}}}function V(e,t){return p(e)&&t.every(({field:r,kind:i})=>T(e[String(r)],i))}function pe(e){if(!Array.isArray(e)||e.length!==2)return!1;const t=A.indexOf(e[0]),r=A.indexOf(e[1]);return t>=0&&r>t}function le(e,t){if(!p(e)||!_.every(({field:i,kind:n})=>T(e[String(i)],n)))return!1;const r=e;return r.scheme!==t?!1:w(r.tokens.map(i=>i.token))&&w(r.adjustedTokens)&&w(r.lints.map(i=>i.id))}function me(e,t){const r=[];for(const n of k)n.compared&&ge(r,n,e,t);return(g(z(e))!==g(z(t))||r.length===0&&g(e)!==g(t))&&r.push("fit tables differ outside compared fields"),r}function ge(e,t,r,i){const{field:n,kind:s}=t;if(s==="string-array"){const o=r[n],c=i[n];J(e,String(n),o,c),E(e,String(n),o,c);return}if(s==="data-palette-record"){const o=r[n],c=i[n];for(const a of["light","dark"])for(const f of A)K(e,`${a}/${String(n)}/${f}`,o[a][f],c[a][f]);return}if(s==="palette-lint-record"){const o=r[n],c=i[n];for(const a of["light","dark"])Te(e,a,String(n),o[a],c[a]),E(e,`${a}/${String(n)}`,o[a].map(h),c[a].map(h));return}if(s==="report-array"&&(n==="light"||n==="dark")){he(e,n,r[n],i[n]);return}F(e,"fit tables",String(n),r[n],i[n],s)}function he(e,t,r,i){const n=new Map(r.map(o=>[o.surface,o])),s=new Map(i.map(o=>[o.surface,o]));E(e,`${t}/reports`,r.map(o=>o.surface),i.map(o=>o.surface));for(const o of L(n.keys(),s.keys())){const c=n.get(o),a=s.get(o),f=`${t}/${o}`;if(!c||!a){e.push(`${f}: surface ${c?"removed":"added"}`);continue}$e(e,f,c,a)}}function $e(e,t,r,i){for(const n of _){const{compared:s,field:o,kind:c}=n;if(!(!s||o==="scheme"||o==="surface")){if(c==="anchor-record"){Ee(e,`${t}/${String(o)}`,r[o],i[o]);continue}if(c==="semantic-array"){const a=r[o],f=i[o];J(e,`${t}/${String(o)}`,a,f),E(e,`${t}/${String(o)}`,a,f);continue}if(c==="lint-array"){const a=r[o],f=i[o];ke(e,t,String(o),a,f),E(e,`${t}/${String(o)}`,a.map(u=>u.id),f.map(u=>u.id));continue}if(c==="token-array"){ye(e,t,String(o),r[o],i[o]);continue}F(e,t,String(o),r[o],i[o],c)}}}function ye(e,t,r,i,n){const s=new Map(i.map(a=>[a.token,a])),o=new Map(n.map(a=>[a.token,a]));E(e,`${t}/${r}`,i.map(a=>a.token),n.map(a=>a.token));const c=r==="tokens"?t:`${t}/${r}`;for(const a of L(s.keys(),o.keys())){const f=s.get(a),u=o.get(a),S=`${c}/${a}`;if(!f||!u){e.push(`${S}: token ${f?"removed":"added"}`);continue}Se(e,S,f,u)}}function Se(e,t,r,i){for(const{compared:n,field:s,kind:o}of x)if(!(!n||s==="token")){if(o==="anchor"){U(e,t,"anchor",r.anchor,i.anchor,N);continue}if(o==="apca"){U(e,t,"apca",r.apca,i.apca,C);continue}F(e,t,String(s),r[s],i[s],o)}}function U(e,t,r,i,n,s){const o=i,c=n;for(const{compared:a,field:f,kind:u}of s)a&&F(e,t,`${r}.${String(f)}`,o?.[f],c?.[f],u)}function ke(e,t,r,i,n){const s=new Map(i.map(c=>[c.id,c])),o=new Map(n.map(c=>[c.id,c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of R)if(!(!S||d==="id")){if(b==="semantic-array"){Fe(e,u,String(d),a[d],f[d]);continue}F(e,u,String(d),a[d],f[d],b)}}}function Te(e,t,r,i,n){const s=new Map(i.map(c=>[h(c),c])),o=new Map(n.map(c=>[h(c),c]));for(const c of L(s.keys(),o.keys())){const a=s.get(c),f=o.get(c),u=`${t}/${r}/${c}`;if(!a||!f){e.push(`${u}: lint ${a?"removed":"added"}`);continue}for(const{compared:S,field:d,kind:b}of M)!S||d==="id"||d==="series"||d==="simulation"||F(e,u,String(d),a[d],f[d],b)}}function h(e){return`${e.id}/${e.series[0]}+${e.series[1]}/${e.simulation}`}function Ee(e,t,r,i){for(const n of L(Object.keys(r),Object.keys(i)))K(e,`${t}/${n}`,r[n],i[n])}function J(e,t,r,i){const n=new Set(r),s=new Set(i);for(const o of L(n,s))n.has(o)!==s.has(o)&&e.push(`${t}/${o}: ${n.has(o)?"removed":"added"}`)}function E(e,t,r,i){const n=new Set(r),s=new Set(i),o=r.filter(a=>s.has(a)),c=i.filter(a=>n.has(a));o.some((a,f)=>a!==c[f])&&e.push(`${t}: order changed`)}function Fe(e,t,r,i,n){const s=Math.max(i.length,n.length);for(let o=0;o<s;o+=1)W(e,t,`${r}[${o}]`,i[o],n[o])}function K(e,t,r,i){r!==i&&e.push(`${t}: ${j(r)} \u2192 ${j(i)}`)}function W(e,t,r,i,n,s){if(!Object.is(i,n)){if(s==="message"){e.push(`${t}: message changed`);return}e.push(`${t}: ${r} ${j(i)} \u2192 ${j(n)}`)}}function Le(e,t,r,i,n){g(i)!==g(n)&&e.push(`${t}: ${r} changed`)}function F(e,t,r,i,n,s){if(xe(s)){W(e,t,r,i,n,s);return}Le(e,t,r,i,n)}const _e={anchor:!1,"anchor-record":!1,apca:!1,boolean:!0,"data-palette-record":!1,explicit:!0,"fit-lint-id":!0,"lint-array":!1,message:!0,number:!0,pairing:!0,"palette-lint-id":!0,"palette-lint-record":!1,"report-array":!1,scheme:!0,semantic:!0,"semantic-array":!1,"series-pair":!1,simulation:!0,string:!0,"string-array":!1,"token-array":!1,warning:!0};function xe(e){return _e[e]===!0}function j(e){return e===void 0?"(absent)":e===""?'""':String(e)}function L(e,t){return[...new Set([...e,...t])].sort()}function g(e){return Array.isArray(e)?`[${e.map(g).join(",")}]`:p(e)?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${g(e[t])}`).join(",")}}`:JSON.stringify(e)??"undefined"}function z(e){const t=m(e,$(k)),r=["light","dark"];if(y(k,"dataPalette")){const i=m(e.dataPalette,r);for(const n of r)l(i,n,m(e.dataPalette[n],A));l(t,"dataPalette",i)}if(y(k,"paletteLints")){const i=m(e.paletteLints,r);for(const n of r)l(i,n,q(e.paletteLints[n],h,$(M)));l(t,"paletteLints",i)}for(const i of r){if(!y(k,i))continue;const n=O();for(const s of e[i]){const o=m(s,$(_));if(y(_,"tokens")){const c=O();for(const a of s.tokens){const f=m(a,$(x));a.anchor&&y(x,"anchor")&&l(f,"anchor",m(a.anchor,$(N))),a.apca&&y(x,"apca")&&l(f,"apca",m(a.apca,$(C))),l(c,a.token,f)}l(o,"tokens",c)}y(_,"lints")&&l(o,"lints",q(s.lints,c=>c.id,$(R))),l(n,s.surface,o)}l(t,i,n)}return t}function q(e,t,r){const i=O();for(const n of e)l(i,t(n),m(n,r));return i}function $(e){return e.filter(({compared:t})=>t).map(({field:t})=>t)}function y(e,t){return e.some(r=>r.field===t&&r.compared)}function m(e,t){const r=new Set(t.map(String)),i=O();for(const[n,s]of Object.entries(e))r.has(n)||(i[n]=s);return i}function O(){return Object.create(null)}function l(e,t,r){Object.keys(r).length>0&&(e[t]=r)}function Ae(e,t,r){for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.log(` ${i} lint(${n.id}): ${n.message}`);for(const n of e[i]){r.log(je(i,n));for(const s of n.lints)r.log(` lint(${s.id}): ${s.message}`)}}r.log(`Checked ${e.surfaces.length} surface(s) \xD7 2 schemes \u2014 `+(t===0?"no lints.":`${t} lint(s), listed above.`))}function Ie(e,t,r){r.error(`${t} theme lint(s) are standing while fit-table drift is present:`);for(const i of["light","dark"]){for(const n of e.paletteLints[i])r.error(`lint: ${i}/paletteLints/${h(n)}: ${n.message}`);for(const n of e[i])for(const s of n.lints)r.error(`lint: ${i}/${n.surface}/lints/${s.id}: ${s.message}`)}}function we(e){return[...e.light,...e.dark].reduce((r,i)=>r+i.lints.length,0)+e.paletteLints.light.length+e.paletteLints.dark.length}function be(e,t){return["light","dark"].some(r=>{const i=`${r}: `;if(!e.startsWith(i))return!1;const n=e.slice(i.length);return t.paletteLints[r].some(s=>te(n,s))})}function je(e,t){const r=t.adjustedTokens.length===0?"contrast enforcement moved nothing":`contrast enforcement moved ${t.adjustedTokens.join(", ")}`,i=t.tokens.filter(s=>s.explicit==="inherited").length,n=i===0?"":`; ${i} inherited explicit pin(s) \u2014 see the fit tables`;return`${e}/${t.surface}: ${t.tokens.length} tokens, ${r}${n}.`}export{Re as runEspalierCli};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{css as e}from"lit";const
|
|
1
|
+
import{css as e}from"lit";const t=e`
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
.temporal-error {
|
|
@@ -109,7 +109,7 @@ import{css as e}from"lit";const r=e`
|
|
|
109
109
|
|
|
110
110
|
|
|
111
111
|
&:focus-visible {
|
|
112
|
-
outline: 2px solid var(--esp-color-
|
|
112
|
+
outline: 2px solid var(--esp-color-text);
|
|
113
113
|
outline-offset: 2px;
|
|
114
114
|
}
|
|
115
115
|
}
|
|
@@ -135,7 +135,7 @@ import{css as e}from"lit";const r=e`
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
&:focus-visible {
|
|
138
|
-
outline: 2px solid var(--esp-color-
|
|
138
|
+
outline: 2px solid var(--esp-color-text);
|
|
139
139
|
outline-offset: -2px;
|
|
140
140
|
}
|
|
141
141
|
}
|
|
@@ -165,7 +165,7 @@ import{css as e}from"lit";const r=e`
|
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
.day-grid:focus-within .day-cell.focused {
|
|
168
|
-
outline: 2px solid var(--esp-color-
|
|
168
|
+
outline: 2px solid var(--esp-color-text);
|
|
169
169
|
outline-offset: -2px;
|
|
170
170
|
z-index: 1;
|
|
171
171
|
}
|
|
@@ -199,19 +199,29 @@ import{css as e}from"lit";const r=e`
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
&:focus-visible {
|
|
202
|
-
outline: 2px solid var(--esp-color-
|
|
202
|
+
outline: 2px solid var(--esp-color-text);
|
|
203
203
|
outline-offset: -2px;
|
|
204
204
|
z-index: 1;
|
|
205
205
|
}
|
|
206
206
|
|
|
207
207
|
|
|
208
208
|
&.selected {
|
|
209
|
-
background-color: var(--esp-color-
|
|
209
|
+
background-color: var(--esp-color-action-background);
|
|
210
210
|
color: var(--esp-color-action-text);
|
|
211
211
|
font-weight: bold;
|
|
212
212
|
}
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
|
|
216
|
+
.day-grid:focus-within .day-cell.focused.selected,
|
|
217
|
+
.jump-cell.selected:focus-visible {
|
|
218
|
+
outline-color: var(--esp-color-action-text);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.day-cell.today.selected {
|
|
222
|
+
box-shadow: inset 0 0 0 1px var(--esp-color-action-text);
|
|
223
|
+
}
|
|
224
|
+
|
|
215
225
|
.day-cell {
|
|
216
226
|
width: var(--_cell-size);
|
|
217
227
|
height: var(--_cell-size);
|
|
@@ -321,4 +331,4 @@ import{css as e}from"lit";const r=e`
|
|
|
321
331
|
color: var(--esp-color-headings);
|
|
322
332
|
padding: 0 2px;
|
|
323
333
|
}
|
|
324
|
-
`;export{
|
|
334
|
+
`;export{t as datePickerStyles};
|
package/dist/index.d.ts
CHANGED
|
@@ -80,6 +80,6 @@ export { canonicalFontStack, classifyFontStack, customWebSafeFont, isDeviceFontS
|
|
|
80
80
|
export { WEIGHT_LABELS, extractWeights, normalizeWeight, bestAvailableWeight, extractFamily, getFallbackFont, googleFontStylesheetUrl, isLocalFontFamily, normalizeFontFaceWeight, removeRuntimeGoogleFontLink, removeRuntimeGoogleFontLinks, syncRuntimeGoogleFontLink, RUNTIME_GOOGLE_FONT_OWNER_ATTR, type RuntimeGoogleFontLinkOptions, } from "./shared/font-helpers.js";
|
|
81
81
|
export { compileFontPlan, fontFallbackAliases, fontFallbackBaseIndexes, fontFaceRequestKey, type CompileFontPlanOptions, type CompiledFontPlan, type FontFaceRequest, type FontFallbackCatalog, type FontFallbackProfile, type FontPlanProfileMiss, type FontPlanScheme, type FontPlanSlot, type FontPlanStyle, type FontPlanTheme, type ResolvedFontSource, } from "./shared/font-plan.js";
|
|
82
82
|
export { getGoogleFonts } from "./font-picker/esp-font-picker.js";
|
|
83
|
-
export { ROOT_SURFACE, THEME_FIT_ANCHOR_FIELDS, THEME_FIT_APCA_FIELDS, THEME_FIT_DATA_PALETTE_LINT_FIELDS, THEME_FIT_DATA_PALETTE_LINT_IDS, THEME_FIT_EXPLICIT_VALUES, THEME_FIT_LINT_FIELDS, THEME_FIT_LINT_IDS, THEME_FIT_LINT_SEVERITIES, THEME_FIT_REPORT_FIELDS, THEME_FIT_SUITE_FIELDS, THEME_FIT_TOKEN_FIELDS, themeFitReport, themeFitRows, themeFitLints, themeFitReportSuite, printThemeFitReport, type ThemeFitReport, type ThemeFitReportOptions, type ThemeFitToken, type ThemeFitApcaAction, type ThemeFitAnchor, type ThemeFitRow, type ThemeFitLint, type ThemeFitDataPaletteLint, type ThemeFitFieldDescriptor, type ThemeFitFieldKind, type ThemeFitSurfaceReport, type ThemeFitSuite, } from "./shared/theme-fit-report.js";
|
|
83
|
+
export { ROOT_SURFACE, THEME_FIT_ANCHOR_FIELDS, THEME_FIT_APCA_FIELDS, THEME_FIT_DATA_PALETTE_LINT_FIELDS, THEME_FIT_DATA_PALETTE_LINT_IDS, THEME_FIT_EXPLICIT_VALUES, THEME_FIT_LINT_FIELDS, THEME_FIT_LINT_IDS, THEME_FIT_LINT_SEVERITIES, THEME_FIT_PAIRING_VALUES, THEME_FIT_REPORT_FIELDS, THEME_FIT_SUITE_FIELDS, THEME_FIT_TOKEN_FIELDS, themeFitReport, themeFitRows, themeFitLints, themeFitReportSuite, printThemeFitReport, type ThemeFitReport, type ThemeFitReportOptions, type ThemeFitToken, type ThemeFitApcaAction, type ThemeFitAnchor, type ThemeFitRow, type ThemeFitLint, type ThemeFitDataPaletteLint, type ThemeFitFieldDescriptor, type ThemeFitFieldKind, type ThemeFitSurfaceReport, type ThemeFitSuite, } from "./shared/theme-fit-report.js";
|
|
84
84
|
export { ICON_SPRITE, ICON_SPRITE_ID, installIconSprite } from "./icons/index.js";
|
|
85
85
|
export { deriveLightnessRamp, themeFromSwatches, type ThemeFromSwatchesOptions, type ThemeFromSwatchesResult, } from "./shared/theme-swatches.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./image-picker/esp-image-picker.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as ao,DEFAULT_ICON_VIEW_BOX as Io,INTENT_VARIANTS as io,normalizeIntentVariant as lo,getIconHrefForHost as Fo,getIconSpriteUrl as no,getIconSpriteReference as Ao}from"./shared/intent-values.js";import{EspalierElementBase as so}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as Ro}from"./shared/validation.js";import{FormFieldController as Do}from"./shared/form-field-controller.js";import{traverseToClosest as go}from"./shared/utilities.js";import{showToast as Mo}from"./shared/toast-events.js";import{showFlyout as Ho,closeFlyout as Oo}from"./shared/flyout-events.js";import{requestHelp as
|
|
1
|
+
export*from"./box/esp-box.js";export*from"./action-menu/esp-action-menu.js";export*from"./action-menu/esp-action-menu-item.js";export*from"./avatar/esp-avatar.js";export*from"./avatar/esp-profile-chip.js";export*from"./badge/esp-badge.js";export*from"./checkbox/esp-checkbox.js";export*from"./checkbox/esp-checkbox-group.js";export*from"./data-cell/esp-data-cell.js";export*from"./radio-button/esp-radio-button.js";export*from"./radio-button/esp-radio-button-group.js";export*from"./repeater/esp-repeater.js";export*from"./breadcrumbs/esp-breadcrumbs.js";export*from"./button/esp-button.js";export*from"./button/esp-button-group.js";export*from"./color-picker/esp-color-picker.js";export*from"./flyout/esp-flyout.js";export*from"./form/esp-form.js";export*from"./form-item/esp-form-item.js";export*from"./help/esp-help-button.js";export*from"./help/esp-help-provider.js";export*from"./header/index.js";export*from"./page/esp-page.js";export*from"./section/esp-section.js";export*from"./stack/esp-stack.js";export*from"./row/esp-row.js";export*from"./popover/esp-popover.js";export*from"./dialog/esp-dialog.js";export*from"./empty-state/esp-empty-state.js";export*from"./image-upload/esp-image-upload.js";export*from"./image-picker/esp-image-picker.js";export*from"./file-upload/esp-file-upload.js";export*from"./font-picker/esp-font-picker.js";export*from"./focus-picker/esp-focus-picker.js";export*from"./footer/index.js";export*from"./grid/esp-grid.js";export*from"./image/esp-image.js";export*from"./image/image-focus.js";export*from"./lightbox/esp-lightbox.js";export*from"./info/esp-info.js";export*from"./input/esp-input.js";export*from"./textarea/esp-textarea.js";export*from"./pickers/esp-pick-one.js";export*from"./pickers/esp-pick-some.js";export*from"./pickers/esp-picker-menu.js";export*from"./pickers/esp-picker-item.js";export*from"./root/esp-root.js";export*from"./menu/index.js";export*from"./burger/esp-burger.js";export*from"./date-picker/esp-date-picker.js";export*from"./details/esp-details.js";export*from"./details/esp-details-group.js";export*from"./tabs/esp-tab.js";export*from"./tabs/esp-tab-group.js";export*from"./slider/esp-slider.js";export*from"./switch/esp-switch.js";export*from"./toaster/esp-toaster.js";export*from"./tooltip/esp-tooltip.js";export*from"./progress/esp-progress.js";export*from"./search/esp-search.js";export*from"./status-indicator/esp-status-indicator.js";export*from"./tree/esp-tree.js";export*from"./tree/esp-tree-item.js";import{DEFAULT_ICON_SPRITE_URL as ao,DEFAULT_ICON_VIEW_BOX as Io,INTENT_VARIANTS as io,normalizeIntentVariant as lo,getIconHrefForHost as Fo,getIconSpriteUrl as no,getIconSpriteReference as Ao}from"./shared/intent-values.js";import{EspalierElementBase as so}from"./shared/esp-element-base.js";import{VALIDITY_CHANGED_EVENT as Ro}from"./shared/validation.js";import{FormFieldController as Do}from"./shared/form-field-controller.js";import{traverseToClosest as go}from"./shared/utilities.js";import{showToast as Mo}from"./shared/toast-events.js";import{showFlyout as Ho,closeFlyout as Oo}from"./shared/flyout-events.js";import{requestHelp as Uo}from"./shared/help-events.js";import{getEspBus as bo}from"./shared/bus-events.js";export*from"./shared/events.js";import{getImageDetails as ko,releasePreviewUrl as yo}from"./image-upload/image-helpers.js";import{calculateAlbumLayout as vo,calculatePhotoLayout as wo,DEFAULT_ALBUM_MAX_ROW_HEIGHT_VH as Bo,normalizeAlbumMaxRowHeightVh as zo,normalizeMaxImagesPerRow as Ko}from"./shared/justified-layout.js";import{encodeTheme as qo,parseTheme as Yo,mergePartials as jo,layerThemes as Jo,validateThemePair as Qo,resolveContextTheme as Zo,isObjectRecord as $o,isSemanticColorName as oe,buildTaprootLightTheme as ee,buildTaprootDarkTheme as re,NESTED_THEME_KEYS as te}from"./shared/theme.js";import{auditDataPalette as pe,describePaletteCollision as fe,generateSequentialRamp as Te,generateDivergingRamp as xe,COLOR_VISION_SIMULATIONS as _e,DATA_SERIES_KEYS as Ee,DEFAULT_DATA_PALETTE as ae,DEFAULT_DATA_RAMP_STEPS as Ie,DEFAULT_DIVERGING_NEUTRAL as ie,MAX_DATA_RAMP_STEPS as le,MIN_DATA_COLOR_DISTANCE as Fe,MIN_DATA_RAMP_LIGHTNESS_STEP as ne,MIN_DATA_RAMP_STEPS as Ae}from"./shared/data-colors.js";import{canonicalFontStack as se,classifyFontStack as Le,customWebSafeFont as Re,isDeviceFontStack as ce,matchWebSafeFont as De,parseFontStack as Ne,webSafeFontWeights as ge}from"./shared/font-stacks.js";import{WEIGHT_LABELS as Me,extractWeights as Pe,normalizeWeight as He,bestAvailableWeight as Oe,extractFamily as ue,getFallbackFont as Ue,googleFontStylesheetUrl as Ce,isLocalFontFamily as be,normalizeFontFaceWeight as Ge,removeRuntimeGoogleFontLink as Ve,removeRuntimeGoogleFontLinks as ke,syncRuntimeGoogleFontLink as ye,RUNTIME_GOOGLE_FONT_OWNER_ATTR as We}from"./shared/font-helpers.js";import{compileFontPlan as ve,fontFallbackAliases as we,fontFallbackBaseIndexes as Be,fontFaceRequestKey as ze}from"./shared/font-plan.js";import{getGoogleFonts as Xe}from"./font-picker/esp-font-picker.js";import{ROOT_SURFACE as Ye,THEME_FIT_ANCHOR_FIELDS as je,THEME_FIT_APCA_FIELDS as Je,THEME_FIT_DATA_PALETTE_LINT_FIELDS as Qe,THEME_FIT_DATA_PALETTE_LINT_IDS as Ze,THEME_FIT_EXPLICIT_VALUES as $e,THEME_FIT_LINT_FIELDS as or,THEME_FIT_LINT_IDS as er,THEME_FIT_LINT_SEVERITIES as rr,THEME_FIT_PAIRING_VALUES as tr,THEME_FIT_REPORT_FIELDS as mr,THEME_FIT_SUITE_FIELDS as pr,THEME_FIT_TOKEN_FIELDS as fr,themeFitReport as Tr,themeFitRows as xr,themeFitLints as _r,themeFitReportSuite as Er,printThemeFitReport as ar}from"./shared/theme-fit-report.js";import{ICON_SPRITE as ir,ICON_SPRITE_ID as lr,installIconSprite as Fr}from"./icons/index.js";import{deriveLightnessRamp as Ar,themeFromSwatches as Sr}from"./shared/theme-swatches.js";export{_e as COLOR_VISION_SIMULATIONS,Ee as DATA_SERIES_KEYS,Bo as DEFAULT_ALBUM_MAX_ROW_HEIGHT_VH,ae as DEFAULT_DATA_PALETTE,Ie as DEFAULT_DATA_RAMP_STEPS,ie as DEFAULT_DIVERGING_NEUTRAL,ao as DEFAULT_ICON_SPRITE_URL,Io as DEFAULT_ICON_VIEW_BOX,so as EspalierElementBase,Do as FormFieldController,ir as ICON_SPRITE,lr as ICON_SPRITE_ID,io as INTENT_VARIANTS,le as MAX_DATA_RAMP_STEPS,Fe as MIN_DATA_COLOR_DISTANCE,ne as MIN_DATA_RAMP_LIGHTNESS_STEP,Ae as MIN_DATA_RAMP_STEPS,te as NESTED_THEME_KEYS,Ye as ROOT_SURFACE,We as RUNTIME_GOOGLE_FONT_OWNER_ATTR,je as THEME_FIT_ANCHOR_FIELDS,Je as THEME_FIT_APCA_FIELDS,Qe as THEME_FIT_DATA_PALETTE_LINT_FIELDS,Ze as THEME_FIT_DATA_PALETTE_LINT_IDS,$e as THEME_FIT_EXPLICIT_VALUES,or as THEME_FIT_LINT_FIELDS,er as THEME_FIT_LINT_IDS,rr as THEME_FIT_LINT_SEVERITIES,tr as THEME_FIT_PAIRING_VALUES,mr as THEME_FIT_REPORT_FIELDS,pr as THEME_FIT_SUITE_FIELDS,fr as THEME_FIT_TOKEN_FIELDS,Ro as VALIDITY_CHANGED_EVENT,Me as WEIGHT_LABELS,pe as auditDataPalette,Oe as bestAvailableWeight,re as buildTaprootDarkTheme,ee as buildTaprootLightTheme,vo as calculateAlbumLayout,wo as calculatePhotoLayout,se as canonicalFontStack,Le as classifyFontStack,Oo as closeFlyout,ve as compileFontPlan,Re as customWebSafeFont,Ar as deriveLightnessRamp,fe as describePaletteCollision,qo as encodeTheme,ue as extractFamily,Pe as extractWeights,ze as fontFaceRequestKey,we as fontFallbackAliases,Be as fontFallbackBaseIndexes,xe as generateDivergingRamp,Te as generateSequentialRamp,bo as getEspBus,Ue as getFallbackFont,Xe as getGoogleFonts,Fo as getIconHrefForHost,Ao as getIconSpriteReference,no as getIconSpriteUrl,ko as getImageDetails,Ce as googleFontStylesheetUrl,Fr as installIconSprite,ce as isDeviceFontStack,be as isLocalFontFamily,$o as isObjectRecord,oe as isSemanticColorName,Jo as layerThemes,De as matchWebSafeFont,jo as mergePartials,zo as normalizeAlbumMaxRowHeightVh,Ge as normalizeFontFaceWeight,lo as normalizeIntentVariant,Ko as normalizeMaxImagesPerRow,He as normalizeWeight,Ne as parseFontStack,Yo as parseTheme,ar as printThemeFitReport,yo as releasePreviewUrl,Ve as removeRuntimeGoogleFontLink,ke as removeRuntimeGoogleFontLinks,Uo as requestHelp,Zo as resolveContextTheme,Ho as showFlyout,Mo as showToast,ye as syncRuntimeGoogleFontLink,_r as themeFitLints,Tr as themeFitReport,Er as themeFitReportSuite,xr as themeFitRows,Sr as themeFromSwatches,go as traverseToClosest,Qo as validateThemePair,ge as webSafeFontWeights};
|
|
@@ -114,6 +114,19 @@ export interface ThemeFitToken {
|
|
|
114
114
|
* since a zone's unexpected value then traces to a root theme line.
|
|
115
115
|
*/
|
|
116
116
|
explicit?: "declared" | "inherited";
|
|
117
|
+
/**
|
|
118
|
+
* Present on a role-paired ink the role layer compiled (ESP0223).
|
|
119
|
+
* `"declared"` means the theme named the slot — a separate claim about
|
|
120
|
+
* this token's family. `"derived"` means it paired off another role,
|
|
121
|
+
* which for `action.ink` is the canvas: the token IS the page ground
|
|
122
|
+
* by contract, and its distance from the anchor it reports describes
|
|
123
|
+
* that contract rather than a theme that missed its brand.
|
|
124
|
+
*
|
|
125
|
+
* Absent when no such role is declared, and absent on a token an
|
|
126
|
+
* explicit mapping pinned — there the pin, not the role, chose the
|
|
127
|
+
* value, and {@link explicit} is the mark that says so.
|
|
128
|
+
*/
|
|
129
|
+
pairing?: "declared" | "derived";
|
|
117
130
|
}
|
|
118
131
|
/**
|
|
119
132
|
* A theme's fit report — the stable JSON shape the docs site renders.
|
|
@@ -184,7 +197,7 @@ export declare function printThemeFitReport(report: ThemeFitReport): void;
|
|
|
184
197
|
/** One cross-token finding over a single surface's emitted values. */
|
|
185
198
|
export interface ThemeFitLint {
|
|
186
199
|
/** Stable lint identifier. */
|
|
187
|
-
id: "action-canvas-separation" | "link-hover-ordering";
|
|
200
|
+
id: "action-anchor-inversion" | "action-canvas-separation" | "apca-target-unmet" | "link-hover-ordering";
|
|
188
201
|
/** Lints describe design-quality hazards, not validation failures. */
|
|
189
202
|
severity: "warning";
|
|
190
203
|
/** The tokens the finding is about, recommended retune target first. */
|
|
@@ -212,7 +225,7 @@ export interface ThemeFitDataPaletteLint {
|
|
|
212
225
|
message: string;
|
|
213
226
|
}
|
|
214
227
|
/** Runtime validation/comparison vocabulary used by the exported field descriptors. */
|
|
215
|
-
export type ThemeFitFieldKind = "anchor" | "anchor-record" | "apca" | "boolean" | "data-palette-record" | "explicit" | "fit-lint-id" | "lint-array" | "message" | "number" | "palette-lint-id" | "palette-lint-record" | "report-array" | "scheme" | "semantic" | "semantic-array" | "series-pair" | "simulation" | "string" | "string-array" | "token-array" | "warning";
|
|
228
|
+
export type ThemeFitFieldKind = "anchor" | "anchor-record" | "apca" | "boolean" | "data-palette-record" | "explicit" | "fit-lint-id" | "lint-array" | "message" | "number" | "pairing" | "palette-lint-id" | "palette-lint-record" | "report-array" | "scheme" | "semantic" | "semantic-array" | "series-pair" | "simulation" | "string" | "string-array" | "token-array" | "warning";
|
|
216
229
|
/** One runtime field descriptor used by fit-suite validation and comparison. */
|
|
217
230
|
export interface ThemeFitFieldDescriptor<Field extends PropertyKey = PropertyKey> {
|
|
218
231
|
readonly field: Field;
|
|
@@ -226,6 +239,8 @@ export declare const THEME_FIT_LINT_IDS: readonly ThemeFitLint["id"][];
|
|
|
226
239
|
export declare const THEME_FIT_DATA_PALETTE_LINT_IDS: readonly ThemeFitDataPaletteLint["id"][];
|
|
227
240
|
/** Every stable explicit-pin provenance value. */
|
|
228
241
|
export declare const THEME_FIT_EXPLICIT_VALUES: readonly NonNullable<ThemeFitToken["explicit"]>[];
|
|
242
|
+
/** Every stable role-paired-ink provenance value. */
|
|
243
|
+
export declare const THEME_FIT_PAIRING_VALUES: readonly NonNullable<ThemeFitToken["pairing"]>[];
|
|
229
244
|
type ThemeFitLintSeverity = ThemeFitLint["severity"] | ThemeFitDataPaletteLint["severity"];
|
|
230
245
|
/** Every stable fit-suite lint severity. */
|
|
231
246
|
export declare const THEME_FIT_LINT_SEVERITIES: readonly ThemeFitLintSeverity[];
|
|
@@ -256,6 +271,27 @@ export declare const THEME_FIT_DATA_PALETTE_LINT_FIELDS: readonly ThemeFitFieldD
|
|
|
256
271
|
* wash itself signals the state and the ink must clear the text tier
|
|
257
272
|
* there; when the wash equals the background (no visible wash), hover
|
|
258
273
|
* must not read weaker than rest — a dimming hover feels disabled.
|
|
274
|
+
* - **action-anchor-inversion** (ESP0223) — the filled action rendered
|
|
275
|
+
* the *opposite way round* from the swatches it names: a surface whose
|
|
276
|
+
* swatch wants dark ink took light ink instead, or a declared pair's
|
|
277
|
+
* rendered lightness order reversed. Anchor drift on its own is by
|
|
278
|
+
* design — a stop supplies lightness (ADR-015) — and a raw distance
|
|
279
|
+
* cannot tell "a deeper rose" from "the gold became brown": a coral
|
|
280
|
+
* action drifts ΔE 0.29 and reads correctly, while a gold one drifts
|
|
281
|
+
* 0.34 and reads as a different design. The sign does tell them
|
|
282
|
+
* apart, and needs no threshold. This is also the one anchor drift an
|
|
283
|
+
* author cannot chase down: the action's stop is chosen by the engine,
|
|
284
|
+
* so seating the ramp — the remedy the lightness-ramps guide gives for
|
|
285
|
+
* every other token — cannot move it, and the fix is a pin.
|
|
286
|
+
* - **apca-target-unmet** (ESP0223) — enforcement moved a text token as
|
|
287
|
+
* far as its ramp allows and the pair still misses the legibility
|
|
288
|
+
* floor. The per-token `apca` block has always carried the numbers;
|
|
289
|
+
* nothing read them, so a theme could pin a surface no ink can carry
|
|
290
|
+
* and check clean.
|
|
291
|
+
*
|
|
292
|
+
* The two ESP0223 lints read `anchor`, `pairing` and `apca` rather than
|
|
293
|
+
* only `resolved`, because both findings are about how a token got where
|
|
294
|
+
* it is, which a colour alone cannot say.
|
|
259
295
|
*/
|
|
260
296
|
export declare function themeFitLints(report: ThemeFitReport): ThemeFitLint[];
|
|
261
297
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{apcaContrast as g,deltaEOK as _,parseOklch as v,serializeOklch as I}from"./color-engine.js";import{DATA_SERIES_KEYS as A,auditDataPalette as j,describePaletteCollision as C}from"./data-colors.js";import{DEFAULT_DARK_THEME as D,DEFAULT_LIGHT_THEME as $,explicitMappingTokens as w,mergeTheme as F,parseAnchorSource as P,resolveContextTheme as N}from"./theme.js";import{computeThemeProperties as y}from"../root/helpers/compute-theme-properties.js";function te(e,t,r={}){return L(e,t,r).report}function L(e,t,r={}){let o=e,s=null;if(r.context!==void 0){const n=N(e,r.context);if(!n)throw new Error(`themeFitReport: context "${r.context}" is not defined by the theme.`);o=n,s=new Set(Object.keys(e.contexts[r.context]?.semanticMappings??{}))}const c=[],m=y(o,t,c),k=w(o),l=c.map(n=>{const a=Y(n);return k.has(a.token)&&(a.explicit=s===null||s.has(a.token)?"declared":"inherited"),a});return{properties:m,report:{scheme:t,seedColor:o.seedColor,anchors:G(o.anchors),tokens:l,adjustedTokens:l.filter(n=>n.adjusted).map(n=>n.token)}}}function B(e){return e.tokens.map(t=>({token:t.token,source:t.source,requested:t.requested,resolved:t.resolved,apca:X(t),anchor:W(t)}))}function re(e){const t=e.adjustedTokens.length>0?`APCA moved ${e.adjustedTokens.join(", ")}`:"APCA moved nothing";console.info(`Espalier theme fit \u2014 ${e.scheme} scheme, seed ${e.seedColor}. ${t}.`),console.table(B(e))}function E(e){const t=Object.entries(e).map(([r,o])=>Object.freeze({field:r,kind:o.kind,compared:o.compared}));return Object.freeze(t)}const V={"action-canvas-separation":!0,"link-hover-ordering":!0},oe=Object.freeze(Object.keys(V)),q={"data-palette-cvd-collision":!0},ne=Object.freeze(Object.keys(q)),z={declared:!0,inherited:!0},se=Object.freeze(Object.keys(z)),U={warning:!0},ae=Object.freeze(Object.keys(U)),ce=E({token:{kind:"semantic",compared:!0},property:{kind:"string",compared:!0},source:{kind:"string",compared:!0},lightness:{kind:"string",compared:!0},requested:{kind:"string",compared:!0},resolved:{kind:"string",compared:!0},adjusted:{kind:"boolean",compared:!0},sourceResolved:{kind:"boolean",compared:!0},anchor:{kind:"anchor",compared:!0},apca:{kind:"apca",compared:!0},explicit:{kind:"explicit",compared:!0}}),ie=E({reference:{kind:"string",compared:!0},color:{kind:"string",compared:!0},deltaE:{kind:"number",compared:!0}}),de=E({from:{kind:"string",compared:!0},to:{kind:"string",compared:!0},targetLc:{kind:"number",compared:!0},against:{kind:"semantic",compared:!0},againstColor:{kind:"string",compared:!0},fromLc:{kind:"number",compared:!0},toLc:{kind:"number",compared:!0}}),ue=E({id:{kind:"fit-lint-id",compared:!0},severity:{kind:"warning",compared:!0},tokens:{kind:"semantic-array",compared:!0},measured:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),le=E({id:{kind:"palette-lint-id",compared:!0},severity:{kind:"warning",compared:!0},series:{kind:"series-pair",compared:!0},simulation:{kind:"simulation",compared:!0},measured:{kind:"number",compared:!0},threshold:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),x=.045,O=.5,b=75,K=.045;function S(e){const t=[],r=new Map(e.tokens.map(n=>[n.token,n.resolved])),o=n=>{const a=r.get(n);return a===void 0?null:v(a)},s=o("background"),c=o("actionBackground");if(s&&c){const n=_(c,s);if(n<x){const a=u(n,4);t.push({id:"action-canvas-separation",severity:"warning",tokens:["actionBackground","background"],measured:a,message:`actionBackground sits \u0394E ${a} from background (floor ${x}) \u2014 filled actions vanish into this canvas. Retune the surface apart: move the background stop, or pin actionBackground to a separated stop.`})}}const m=o("link"),k=o("linkHover"),l=o("linkHoverBg");if(s&&m&&k&&l){const n=Math.abs(g(m,s)),a=Math.abs(g(k,l));_(l,s)>=K?a+O<b&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHoverBg","linkHover"],measured:u(b-a,1),message:`linkHover reaches only Lc ${u(a,1)} on the linkHoverBg wash it actually paints (tier ${b}) \u2014 retune linkHoverBg before changing linkHover; the wash has one consumer while the ink has many.`}):a+O<n&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHover","link"],measured:u(n-a,1),message:`linkHover reads weaker than link on the same canvas (Lc ${u(a,1)} vs ${u(n,1)}) \u2014 a dimming hover feels disabled. Retune linkHover toward more contrast than the resting link.`})}return t}const R=":root",pe=E({scheme:{kind:"scheme",compared:!0},seedColor:{kind:"string",compared:!0},anchors:{kind:"anchor-record",compared:!0},tokens:{kind:"token-array",compared:!0},adjustedTokens:{kind:"semantic-array",compared:!0},surface:{kind:"string",compared:!0},lints:{kind:"lint-array",compared:!0}}),me=E({surfaces:{kind:"string-array",compared:!0},dataPalette:{kind:"data-palette-record",compared:!0},paletteLints:{kind:"palette-lint-record",compared:!0},light:{kind:"report-array",compared:!0},dark:{kind:"report-array",compared:!0}});function ke(e,t){const r=F($,e),o=F(D,t),s=[R,...[...new Set([...Object.keys(r.contexts),...Object.keys(o.contexts)])].sort()],c=p=>{const i={};for(let d=0;d<A.length;d+=1){const f=A[d],h=`--esp-color-series-${d+1}`,T=p[h];if(T===void 0)throw new Error(`Theme fit report did not emit required property ${h}.`);i[f]=T}return i},m=p=>j(p).map(i=>{const d=u(i.distance,4);return{id:"data-palette-cvd-collision",severity:"warning",series:i.series,simulation:i.simulation,measured:d,threshold:i.threshold,message:C(i)}}),k=(p,i)=>{const d=L(p,i);if(Object.keys(d.properties).length===0)throw new Error(`themeFitReportSuite: ${i} root emitted no properties for seed "${p.seedColor}".`);const f=[{...d.report,surface:R,lints:S(d.report)}];for(const h of s){if(h===R||!(h in p.contexts))continue;const H=L(p,i,{context:h}).report;f.push({...H,surface:h,lints:S(H)})}return{dataPalette:c(d.properties),reports:f}},l=k(r,"light"),n=k(o,"dark"),a={light:l.dataPalette,dark:n.dataPalette};return{surfaces:s,dataPalette:a,paletteLints:{light:m(a.light),dark:m(a.dark)},light:l.reports,dark:n.reports}}function u(e,t){const r=Math.pow(10,t);return Math.round(e*r)/r}function M(e,t){return t===void 0?e:`${e}.${t}`}function G(e){const t={};for(const[r,o]of Object.entries(e)){if(typeof o=="string"){t[r]=o;continue}for(const[s,c]of Object.entries(o))t[s==="color"?r:M(r,s)]=c}return t}function Y(e){const t=v(e.resolved),r=e.requested===void 0?e.resolved:I(e.requested),o={token:e.token,property:e.property,source:e.source,lightness:e.lightness,requested:r,resolved:e.resolved,adjusted:r!==e.resolved,sourceResolved:e.sourceResolved},s=P(e.source);if(s&&e.sourceResolved&&(o.anchor={reference:M(s.name,s.slot),color:I(e.base),deltaE:u(_(e.base,t),4)}),e.contrast){const c=e.contrast.background;o.apca={from:r,to:e.resolved,targetLc:e.contrast.targetLc,against:e.contrast.against,againstColor:I(c),fromLc:u(Math.abs(g(v(r),c)),1),toLc:u(Math.abs(g(t,c)),1)}}return o}function X(e){if(!e.apca)return"";const{targetLc:t,against:r,fromLc:o,toLc:s}=e.apca;return e.adjusted?`Lc ${t} vs ${r} \u2014 pushed from Lc ${o} to Lc ${s}`:`Lc ${t} vs ${r} \u2014 met at Lc ${o}`}function W(e){return e.anchor?`${e.anchor.reference} \u0394E ${e.anchor.deltaE}`:e.sourceResolved?"":"unresolved \u2014 seed used"}export{R as ROOT_SURFACE,ie as THEME_FIT_ANCHOR_FIELDS,de as THEME_FIT_APCA_FIELDS,le as THEME_FIT_DATA_PALETTE_LINT_FIELDS,ne as THEME_FIT_DATA_PALETTE_LINT_IDS,se as THEME_FIT_EXPLICIT_VALUES,ue as THEME_FIT_LINT_FIELDS,oe as THEME_FIT_LINT_IDS,ae as THEME_FIT_LINT_SEVERITIES,pe as THEME_FIT_REPORT_FIELDS,me as THEME_FIT_SUITE_FIELDS,ce as THEME_FIT_TOKEN_FIELDS,re as printThemeFitReport,S as themeFitLints,te as themeFitReport,ke as themeFitReportSuite,B as themeFitRows};
|
|
1
|
+
import{apcaContrast as T,deltaEOK as x,parseOklch as _,serializeOklch as $}from"./color-engine.js";import{DATA_SERIES_KEYS as C,auditDataPalette as q,describePaletteCollision as K}from"./data-colors.js";import{DEFAULT_DARK_THEME as G,DEFAULT_LIGHT_THEME as Y,explicitMappingTokens as W,mergeTheme as j,parseAnchorSource as X,resolveContextTheme as J,roleInkProvenance as Q}from"./theme.js";import{computeThemeProperties as Z}from"../root/helpers/compute-theme-properties.js";function ke(e,t,o={}){return H(e,t,o).report}function H(e,t,o={}){let n=e,c=null;if(o.context!==void 0){const s=J(e,o.context);if(!s)throw new Error(`themeFitReport: context "${o.context}" is not defined by the theme.`);n=s,c=new Set(Object.keys(e.contexts[o.context]?.semanticMappings??{}))}const p=[],v=Z(n,t,p),L=W(n),f=Q(n.roles),E=p.map(s=>{const a=ie(s);if(L.has(a.token))a.explicit=c===null||c.has(a.token)?"declared":"inherited";else{const i=f[a.token];i!==void 0&&(a.pairing=i)}return a});return{properties:v,report:{scheme:t,seedColor:n.seedColor,anchors:ce(n.anchors),tokens:E,adjustedTokens:E.filter(s=>s.adjusted).map(s=>s.token)}}}function ee(e){return e.tokens.map(t=>({token:t.token,source:t.source,requested:t.requested,resolved:t.resolved,apca:de(t),anchor:le(t)}))}function ge(e){const t=e.adjustedTokens.length>0?`APCA moved ${e.adjustedTokens.join(", ")}`:"APCA moved nothing";console.info(`Espalier theme fit \u2014 ${e.scheme} scheme, seed ${e.seedColor}. ${t}.`),console.table(ee(e))}function I(e){const t=Object.entries(e).map(([o,n])=>Object.freeze({field:o,kind:n.kind,compared:n.compared}));return Object.freeze(t)}const te={"action-anchor-inversion":!0,"action-canvas-separation":!0,"apca-target-unmet":!0,"link-hover-ordering":!0},fe=Object.freeze(Object.keys(te)),re={"data-palette-cvd-collision":!0},Ee=Object.freeze(Object.keys(re)),ne={declared:!0,inherited:!0},Te=Object.freeze(Object.keys(ne)),oe={declared:!0,derived:!0},_e=Object.freeze(Object.keys(oe)),ae={warning:!0},ve=Object.freeze(Object.keys(ae)),Le=I({token:{kind:"semantic",compared:!0},property:{kind:"string",compared:!0},source:{kind:"string",compared:!0},lightness:{kind:"string",compared:!0},requested:{kind:"string",compared:!0},resolved:{kind:"string",compared:!0},adjusted:{kind:"boolean",compared:!0},sourceResolved:{kind:"boolean",compared:!0},anchor:{kind:"anchor",compared:!0},apca:{kind:"apca",compared:!0},explicit:{kind:"explicit",compared:!0},pairing:{kind:"pairing",compared:!0}}),Ie=I({reference:{kind:"string",compared:!0},color:{kind:"string",compared:!0},deltaE:{kind:"number",compared:!0}}),be=I({from:{kind:"string",compared:!0},to:{kind:"string",compared:!0},targetLc:{kind:"number",compared:!0},against:{kind:"semantic",compared:!0},againstColor:{kind:"string",compared:!0},fromLc:{kind:"number",compared:!0},toLc:{kind:"number",compared:!0}}),Re=I({id:{kind:"fit-lint-id",compared:!0},severity:{kind:"warning",compared:!0},tokens:{kind:"semantic-array",compared:!0},measured:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),Me=I({id:{kind:"palette-lint-id",compared:!0},severity:{kind:"warning",compared:!0},series:{kind:"series-pair",compared:!0},simulation:{kind:"simulation",compared:!0},measured:{kind:"number",compared:!0},threshold:{kind:"number",compared:!0},message:{kind:"message",compared:!0}}),D=.045,N=.045,M=75,y={l:0,c:0,h:0},P={l:1,c:0,h:0},B=.5,F=75,se=.045;function V(e){const t=[],o=new Map(e.tokens.map(r=>[r.token,r.resolved])),n=r=>{const d=o.get(r);return d===void 0?null:_(d)},c=n("background"),p=n("actionBackground");if(c&&p){const r=x(p,c);if(r<D){const d=u(r,4);t.push({id:"action-canvas-separation",severity:"warning",tokens:["actionBackground","background"],measured:d,message:`actionBackground sits \u0394E ${d} from background (floor ${D}) \u2014 filled actions vanish into this canvas. Retune the surface apart: move the background stop, or pin actionBackground to a separated stop.`})}}const v=n("link"),L=n("linkHover"),f=n("linkHoverBg");if(c&&v&&L&&f){const r=Math.abs(T(v,c)),d=Math.abs(T(L,f));x(f,c)>=se?d+B<F&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHoverBg","linkHover"],measured:u(F-d,1),message:`linkHover reaches only Lc ${u(d,1)} on the linkHoverBg wash it actually paints (tier ${F}) \u2014 retune linkHoverBg before changing linkHover; the wash has one consumer while the ink has many.`}):d+B<r&&t.push({id:"link-hover-ordering",severity:"warning",tokens:["linkHover","link"],measured:u(r-d,1),message:`linkHover reads weaker than link on the same canvas (Lc ${u(d,1)} vs ${u(r,1)}) \u2014 a dimming hover feels disabled. Retune linkHover toward more contrast than the resting link.`})}const E=r=>Math.abs(T(y,r))>=Math.abs(T(P,r))?"dark":"light",s=e.tokens.find(r=>r.token==="actionBackground"),a=e.tokens.find(r=>r.token==="actionText"),i=[],l=[];let m=0;const h=a?.anchor?_(a.anchor.color):null,g=a?_(a.resolved):null,k=s?.anchor?_(s.anchor.color):null,b=s?_(s.resolved):null,O=g&&b?g.l>b.l?"light":"dark":null;s?.anchor&&k&&b&&O&&s.anchor.deltaE>=N&&E(k)!==O&&(i.push("actionBackground"),m=Math.max(m,s.anchor.deltaE),l.push(`"${s.anchor.reference}" wants ${E(k)} ink but actionBackground renders carrying a ${O} label (\u0394E ${u(s.anchor.deltaE,4)})`)),a?.anchor&&a.pairing!=="derived"&&h&&g&&k&&b&&a.anchor.deltaE>=N&&k.l!==h.l&&Math.sign(k.l-h.l)!==Math.sign(b.l-g.l)&&(i.push("actionText"),m=Math.max(m,a.anchor.deltaE),l.push(`the declared pair puts "${s.anchor.reference}" ${k.l>h.l?"above":"below"} "${a.anchor.reference}" in lightness and the rendered pair puts it ${b.l>g.l?"above":"below"} (\u0394E ${u(a.anchor.deltaE,4)})`)),i.length>0&&t.push({id:"action-anchor-inversion",severity:"warning",tokens:i,measured:u(m,4),message:`The filled action renders the opposite way round from the swatches it names: ${l.join("; ")}. `+(s?.explicit===void 0?"A filled action's ramp stop is chosen by the engine near its mid-band target, so seating the ramp cannot move it the way it moves every other anchored token. Retune by pinning semanticMappings.actionBackground to a stop that carries the swatch":"semanticMappings.actionBackground is already pinned, so the engine did not place this \u2014 retune the stop that pin names")+" \u2014 and check the pair still clears its tier there, because a swatch this far off the band often cannot hold a label at its own lightness."});const A=e.tokens.filter(r=>r.apca!==void 0&&r.apca.toLc<Math.min(r.apca.targetLc,M)).sort((r,d)=>Math.min(d.apca.targetLc,M)-d.apca.toLc-(Math.min(r.apca.targetLc,M)-r.apca.toLc)||(r.token<d.token?-1:r.token>d.token?1:0));if(A.length>0){const r=A[0].apca,d=A.map(R=>`${R.token} reaches Lc ${u(R.apca.toLc,1)} on ${R.apca.against} (floor ${Math.min(R.apca.targetLc,M)})`),w=_(r.againstColor),U=w!==null&&Math.max(Math.abs(T(y,w)),Math.abs(T(P,w)))>=Math.min(r.targetLc,M);t.push({id:"apca-target-unmet",severity:"warning",tokens:A.map(R=>R.token),measured:u(Math.min(r.targetLc,M)-r.toLc,1),message:`${d.join(", ")} \u2014 enforcement moved the ink as far as this ramp allows and the pair still falls short. `+(U?"The opposite ink pole does clear the floor on that ground, so the emitted ink is on the weaker side rather than the ground being impossible \u2014 check the pairing before retuning the ground.":"No ink reaches the floor on that ground, so retune the ground each pair reads against toward a lightness that can carry it.")})}return t}const S=":root",Ae=I({scheme:{kind:"scheme",compared:!0},seedColor:{kind:"string",compared:!0},anchors:{kind:"anchor-record",compared:!0},tokens:{kind:"token-array",compared:!0},adjustedTokens:{kind:"semantic-array",compared:!0},surface:{kind:"string",compared:!0},lints:{kind:"lint-array",compared:!0}}),we=I({surfaces:{kind:"string-array",compared:!0},dataPalette:{kind:"data-palette-record",compared:!0},paletteLints:{kind:"palette-lint-record",compared:!0},light:{kind:"report-array",compared:!0},dark:{kind:"report-array",compared:!0}});function Oe(e,t){const o=j(Y,e),n=j(G,t),c=[S,...[...new Set([...Object.keys(o.contexts),...Object.keys(n.contexts)])].sort()],p=a=>{const i={};for(let l=0;l<C.length;l+=1){const m=C[l],h=`--esp-color-series-${l+1}`,g=a[h];if(g===void 0)throw new Error(`Theme fit report did not emit required property ${h}.`);i[m]=g}return i},v=a=>q(a).map(i=>{const l=u(i.distance,4);return{id:"data-palette-cvd-collision",severity:"warning",series:i.series,simulation:i.simulation,measured:l,threshold:i.threshold,message:K(i)}}),L=(a,i)=>{const l=H(a,i);if(Object.keys(l.properties).length===0)throw new Error(`themeFitReportSuite: ${i} root emitted no properties for seed "${a.seedColor}".`);const m=[{...l.report,surface:S,lints:V(l.report)}];for(const h of c){if(h===S||!(h in a.contexts))continue;const k=H(a,i,{context:h}).report;m.push({...k,surface:h,lints:V(k)})}return{dataPalette:p(l.properties),reports:m}},f=L(o,"light"),E=L(n,"dark"),s={light:f.dataPalette,dark:E.dataPalette};return{surfaces:c,dataPalette:s,paletteLints:{light:v(s.light),dark:v(s.dark)},light:f.reports,dark:E.reports}}function u(e,t){const o=Math.pow(10,t);return Math.round(e*o)/o}function z(e,t){return t===void 0?e:`${e}.${t}`}function ce(e){const t={};for(const[o,n]of Object.entries(e)){if(typeof n=="string"){t[o]=n;continue}for(const[c,p]of Object.entries(n))t[c==="color"?o:z(o,c)]=p}return t}function ie(e){const t=_(e.resolved),o=e.requested===void 0?e.resolved:$(e.requested),n={token:e.token,property:e.property,source:e.source,lightness:e.lightness,requested:o,resolved:e.resolved,adjusted:o!==e.resolved,sourceResolved:e.sourceResolved},c=X(e.source);if(c&&e.sourceResolved&&(n.anchor={reference:z(c.name,c.slot),color:$(e.base),deltaE:u(x(e.base,t),4)}),e.contrast){const p=e.contrast.background;n.apca={from:o,to:e.resolved,targetLc:e.contrast.targetLc,against:e.contrast.against,againstColor:$(p),fromLc:u(Math.abs(T(_(o),p)),1),toLc:u(Math.abs(T(t,p)),1)}}return n}function de(e){if(!e.apca)return"";const{targetLc:t,against:o,fromLc:n,toLc:c}=e.apca;return e.adjusted?`Lc ${t} vs ${o} \u2014 pushed from Lc ${n} to Lc ${c}`:`Lc ${t} vs ${o} \u2014 met at Lc ${n}`}function le(e){return e.anchor?`${e.anchor.reference} \u0394E ${e.anchor.deltaE}`:e.sourceResolved?"":"unresolved \u2014 seed used"}export{S as ROOT_SURFACE,Ie as THEME_FIT_ANCHOR_FIELDS,be as THEME_FIT_APCA_FIELDS,Me as THEME_FIT_DATA_PALETTE_LINT_FIELDS,Ee as THEME_FIT_DATA_PALETTE_LINT_IDS,Te as THEME_FIT_EXPLICIT_VALUES,Re as THEME_FIT_LINT_FIELDS,fe as THEME_FIT_LINT_IDS,ve as THEME_FIT_LINT_SEVERITIES,_e as THEME_FIT_PAIRING_VALUES,Ae as THEME_FIT_REPORT_FIELDS,we as THEME_FIT_SUITE_FIELDS,Le as THEME_FIT_TOKEN_FIELDS,ge as printThemeFitReport,V as themeFitLints,ke as themeFitReport,Oe as themeFitReportSuite,ee as themeFitRows};
|
package/dist/shared/theme.d.ts
CHANGED
|
@@ -269,6 +269,32 @@ export declare const ROLE_NAMES: readonly RoleName[];
|
|
|
269
269
|
* following `accent.text` exactly as before.
|
|
270
270
|
*/
|
|
271
271
|
export declare const ROLE_TOKEN_PLAN: Readonly<Record<RoleName, Readonly<Record<string, ReadonlyArray<[SemanticColorName, LightnessKey]>>>>>;
|
|
272
|
+
/**
|
|
273
|
+
* Role slots whose ink lightness is derived from the surface that role
|
|
274
|
+
* actually painted, rather than taken from {@link ROLE_TOKEN_PLAN}.
|
|
275
|
+
*
|
|
276
|
+
* {@link resolvePairedInkStop} used to run only for a slot the theme
|
|
277
|
+
* left *undeclared*, so naming `action.ink` took the plan's `surface`
|
|
278
|
+
* stop verbatim. In a light ramp both rules answer `surface` and the
|
|
279
|
+
* difference never showed. In a dark ramp the plan's stop is the
|
|
280
|
+
* near-black page ground, which is the wrong side of a mid-dark action
|
|
281
|
+
* surface: enforcement had to walk the label the whole way across the
|
|
282
|
+
* ramp and stopped at the first value that cleared the target, emitting
|
|
283
|
+
* a weaker ink than the ramp could give. ADR-016 is explicit that the
|
|
284
|
+
* model's job is to hand enforcement the strongest available starting
|
|
285
|
+
* point on the correct side, so the derivation now runs for a declared
|
|
286
|
+
* slot too (ESP0223).
|
|
287
|
+
*
|
|
288
|
+
* The source still comes from the theme: naming `action.ink` chooses
|
|
289
|
+
* the family, exactly as ADR-015 says an anchor supplies hue and chroma
|
|
290
|
+
* while the ramp supplies lightness.
|
|
291
|
+
*
|
|
292
|
+
* Every entry here must also appear in {@link ROLE_PAIRED_INK}: the
|
|
293
|
+
* compile branch is gated on `paired` first, and
|
|
294
|
+
* {@link roleInkProvenance} walks the pairing table, so an entry in only
|
|
295
|
+
* this set would be silently inert in both.
|
|
296
|
+
*/
|
|
297
|
+
export declare const ROLE_DERIVED_INK: ReadonlySet<string>;
|
|
272
298
|
/**
|
|
273
299
|
* Ink slots that derive from another role when the theme does not
|
|
274
300
|
* declare them.
|
|
@@ -293,6 +319,8 @@ interface CompileRoleOptions {
|
|
|
293
319
|
actionSurfaceContrast?: (source: MappingSource, stop: LightnessKey) => number;
|
|
294
320
|
/** ΔE-OK between an action surface candidate and the theme's background. */
|
|
295
321
|
actionSurfaceSeparation?: (source: MappingSource, stop: LightnessKey) => number;
|
|
322
|
+
/** Which ink pole reads better on a finished action surface at a lightness. */
|
|
323
|
+
actionSurfacePole?: (source: MappingSource, lightness: number) => "dark" | "light";
|
|
296
324
|
}
|
|
297
325
|
/**
|
|
298
326
|
* Compile roles into semantic mappings.
|
|
@@ -304,6 +332,23 @@ interface CompileRoleOptions {
|
|
|
304
332
|
* reach.
|
|
305
333
|
*/
|
|
306
334
|
export declare function compileRoles(roles: ThemeRoles, lightness: LightnessMap, baseMappings: SemanticMappings, options?: CompileRoleOptions): Partial<SemanticMappings>;
|
|
335
|
+
/**
|
|
336
|
+
* Whether each role-paired ink token's *source* was named by the theme
|
|
337
|
+
* or paired off another role (ESP0223).
|
|
338
|
+
*
|
|
339
|
+
* The distinction matters to anything judging how far a token landed
|
|
340
|
+
* from the swatch it names. `action.ink` defaults to the canvas colour,
|
|
341
|
+
* so an undeclared ink IS the page ground by contract — it is re-lit to
|
|
342
|
+
* the opposite end of the ramp on purpose, and the large anchor ΔE that
|
|
343
|
+
* follows describes the contract working, not a theme missing its
|
|
344
|
+
* brand. A theme that names the slot has made a separate claim about
|
|
345
|
+
* the label's family, and the same ΔE then describes a claim that did
|
|
346
|
+
* not survive.
|
|
347
|
+
*
|
|
348
|
+
* A pure read of `roles`: the compile is not re-run, and a role the
|
|
349
|
+
* theme never declared reports nothing rather than guessing.
|
|
350
|
+
*/
|
|
351
|
+
export declare function roleInkProvenance(roles: ThemeRoles): Partial<Record<SemanticColorName, "declared" | "derived">>;
|
|
307
352
|
/** The complete, resolved Espalier theme. */
|
|
308
353
|
export interface EspalierTheme {
|
|
309
354
|
/**
|
|
@@ -665,6 +710,11 @@ export declare const DEFAULT_DARK_LIGHTNESS: Readonly<LightnessMap>;
|
|
|
665
710
|
*
|
|
666
711
|
* Each entry tells the color engine which variant supplies the
|
|
667
712
|
* hue and which lightness key sets the perceived brightness.
|
|
713
|
+
*
|
|
714
|
+
* `actionBackground` carries the **light** scheme's stop; the dark
|
|
715
|
+
* theme overrides it through {@link buildDefaultSemanticMappings}. See
|
|
716
|
+
* {@link DEFAULT_ACTION_BACKGROUND_STOP} for why that one mapping
|
|
717
|
+
* cannot share a name across schemes.
|
|
668
718
|
*/
|
|
669
719
|
export declare const DEFAULT_SEMANTIC_MAPPINGS: Readonly<SemanticMappings>;
|
|
670
720
|
/** Built-in authored stack for body and UI text. */
|