@mindlogic-ai/logician-ui 5.0.0-alpha.20 → 5.0.0-alpha.22
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/components/Code/shikiAdapter.d.ts +3 -1
- package/dist/components/Code/shikiAdapter.d.ts.map +1 -1
- package/dist/components/Code/shikiAdapter.js +29 -8
- package/dist/components/Code/shikiAdapter.js.map +1 -1
- package/dist/components/Code/shikiAdapter.mjs +29 -8
- package/dist/components/Code/shikiAdapter.mjs.map +1 -1
- package/dist/components/ExpandableText/ExpandableText.d.ts.map +1 -1
- package/dist/components/ExpandableText/ExpandableText.js +1 -1
- package/dist/components/ExpandableText/ExpandableText.js.map +1 -1
- package/dist/components/ExpandableText/ExpandableText.mjs +1 -1
- package/dist/components/ExpandableText/ExpandableText.mjs.map +1 -1
- package/dist/theme/palette.generated.d.ts +8 -8
- package/dist/theme/palette.generated.js +8 -8
- package/dist/theme/palette.generated.mjs +8 -8
- package/package.json +1 -1
- package/src/components/Code/Code.test.tsx +116 -0
- package/src/components/Code/shikiAdapter.ts +38 -9
- package/src/components/ExpandableText/ExpandableText.tsx +0 -1
- package/src/components/ExpandableText/ExpandableText.usage.mdx +6 -4
- package/src/components/a11y.kwcag.test.tsx +12 -21
- package/src/theme/SemanticTokens.mdx +8 -2
- package/src/theme/palette.generated.ts +8 -8
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { BundledLanguage } from 'shiki';
|
|
2
2
|
export declare const BUNDLED_LANGUAGES: BundledLanguage[];
|
|
3
|
-
|
|
3
|
+
declare const baseAdapter: import("@chakra-ui/react").CodeBlockAdapter;
|
|
4
|
+
export declare const shikiAdapter: typeof baseAdapter;
|
|
5
|
+
export {};
|
|
4
6
|
//# sourceMappingURL=shikiAdapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shikiAdapter.d.ts","sourceRoot":"","sources":["../../../src/components/Code/shikiAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAoC,MAAM,OAAO,CAAC;AAE/E,eAAO,MAAM,iBAAiB,EAAE,eAAe,EA8B9C,CAAC;
|
|
1
|
+
{"version":3,"file":"shikiAdapter.d.ts","sourceRoot":"","sources":["../../../src/components/Code/shikiAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAoC,MAAM,OAAO,CAAC;AAE/E,eAAO,MAAM,iBAAiB,EAAE,eAAe,EA8B9C,CAAC;AA+BF,QAAA,MAAM,WAAW,6CAGf,CAAC;AAKH,eAAO,MAAM,YAAY,EAAE,OAAO,WAGjC,CAAC"}
|
|
@@ -34,16 +34,37 @@ const BUNDLED_LANGUAGES = [
|
|
|
34
34
|
'xml',
|
|
35
35
|
'yaml',
|
|
36
36
|
];
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
// One highlighter for the whole app. Every <Code> mounts its own
|
|
38
|
+
// AdapterProvider, and Chakra calls `load()` once per provider. Without this
|
|
39
|
+
// cache a chat with 136 code blocks built 136 highlighters, each compiling all
|
|
40
|
+
// BUNDLED_LANGUAGES, and froze the tab for tens of seconds.
|
|
41
|
+
let highlighterPromise = null;
|
|
42
|
+
const loadHighlighter = () => {
|
|
43
|
+
highlighterPromise ?? (highlighterPromise = Promise.resolve().then(function () { return require('../../node_modules/shiki/dist/index.js'); })
|
|
44
|
+
.then(({ createHighlighter }) => createHighlighter({
|
|
45
|
+
langs: BUNDLED_LANGUAGES,
|
|
46
|
+
themes: ['github-dark'],
|
|
47
|
+
}))
|
|
48
|
+
.catch((error) => {
|
|
49
|
+
// Chakra does not catch a rejected load, so resolve to null instead: the
|
|
50
|
+
// block renders as plain text. Clear the cache so the next mount retries.
|
|
51
|
+
console.error('[logician-ui] Failed to load the Shiki highlighter', error);
|
|
52
|
+
highlighterPromise = null;
|
|
53
|
+
return null;
|
|
54
|
+
}));
|
|
55
|
+
return highlighterPromise;
|
|
56
|
+
};
|
|
57
|
+
const baseAdapter = react.createShikiAdapter({
|
|
58
|
+
load: loadHighlighter,
|
|
45
59
|
theme: 'github-dark',
|
|
46
60
|
});
|
|
61
|
+
// Chakra's default `unloadContext` calls `dispose()` when a provider unmounts.
|
|
62
|
+
// The highlighter is shared, so one block unmounting would break highlighting
|
|
63
|
+
// in every other block. Keep it alive for the life of the page.
|
|
64
|
+
const shikiAdapter = {
|
|
65
|
+
...baseAdapter,
|
|
66
|
+
unloadContext: () => { },
|
|
67
|
+
};
|
|
47
68
|
|
|
48
69
|
exports.BUNDLED_LANGUAGES = BUNDLED_LANGUAGES;
|
|
49
70
|
exports.shikiAdapter = shikiAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shikiAdapter.js","sources":["../../../src/components/Code/shikiAdapter.ts"],"sourcesContent":[null],"names":["createShikiAdapter"],"mappings":";;;;;AAGO,MAAM,iBAAiB,GAAsB;IAClD,MAAM;IACN,GAAG;IACH,QAAQ;IACR,KAAK;IACL,MAAM;IACN,YAAY;IACZ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,YAAY;IACZ,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,GAAG;IACH,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,MAAM;IACN,KAAK;IACL,YAAY;IACZ,KAAK;IACL,MAAM;;
|
|
1
|
+
{"version":3,"file":"shikiAdapter.js","sources":["../../../src/components/Code/shikiAdapter.ts"],"sourcesContent":[null],"names":["createShikiAdapter"],"mappings":";;;;;AAGO,MAAM,iBAAiB,GAAsB;IAClD,MAAM;IACN,GAAG;IACH,QAAQ;IACR,KAAK;IACL,MAAM;IACN,YAAY;IACZ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,YAAY;IACZ,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,GAAG;IACH,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,MAAM;IACN,KAAK;IACL,YAAY;IACZ,KAAK;IACL,MAAM;;AAKR;AACA;AACA;AACA;AACA,IAAI,kBAAkB,GAAuC,IAAI;AAEjE,MAAM,eAAe,GAAG,MAAkC;AACxD,IAAA,kBAAkB,KAAlB,kBAAkB,GAAK,oDAAO,wCAAO;SAClC,IAAI,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAC1B,iBAAiB,CAAC;AAChB,QAAA,KAAK,EAAE,iBAAiB;QACxB,MAAM,EAAE,CAAC,aAAa,CAAC;AACxB,KAAA,CAAC;AAEH,SAAA,KAAK,CAAC,CAAC,KAAc,KAAI;;;AAGxB,QAAA,OAAO,CAAC,KAAK,CACX,oDAAoD,EACpD,KAAK,CACN;QACD,kBAAkB,GAAG,IAAI;AACzB,QAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC,CAAA;AACJ,IAAA,OAAO,kBAAkB;AAC3B,CAAC;AAED,MAAM,WAAW,GAAGA,wBAAkB,CAAqB;AACzD,IAAA,IAAI,EAAE,eAAe;AACrB,IAAA,KAAK,EAAE,aAAa;AACrB,CAAA,CAAC;AAEF;AACA;AACA;AACO,MAAM,YAAY,GAAuB;AAC9C,IAAA,GAAG,WAAW;AACd,IAAA,aAAa,EAAE,MAAK,EAAE,CAAC;;;;;;"}
|
|
@@ -32,16 +32,37 @@ const BUNDLED_LANGUAGES = [
|
|
|
32
32
|
'xml',
|
|
33
33
|
'yaml',
|
|
34
34
|
];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
// One highlighter for the whole app. Every <Code> mounts its own
|
|
36
|
+
// AdapterProvider, and Chakra calls `load()` once per provider. Without this
|
|
37
|
+
// cache a chat with 136 code blocks built 136 highlighters, each compiling all
|
|
38
|
+
// BUNDLED_LANGUAGES, and froze the tab for tens of seconds.
|
|
39
|
+
let highlighterPromise = null;
|
|
40
|
+
const loadHighlighter = () => {
|
|
41
|
+
highlighterPromise ?? (highlighterPromise = import('../../node_modules/shiki/dist/index.mjs')
|
|
42
|
+
.then(({ createHighlighter }) => createHighlighter({
|
|
43
|
+
langs: BUNDLED_LANGUAGES,
|
|
44
|
+
themes: ['github-dark'],
|
|
45
|
+
}))
|
|
46
|
+
.catch((error) => {
|
|
47
|
+
// Chakra does not catch a rejected load, so resolve to null instead: the
|
|
48
|
+
// block renders as plain text. Clear the cache so the next mount retries.
|
|
49
|
+
console.error('[logician-ui] Failed to load the Shiki highlighter', error);
|
|
50
|
+
highlighterPromise = null;
|
|
51
|
+
return null;
|
|
52
|
+
}));
|
|
53
|
+
return highlighterPromise;
|
|
54
|
+
};
|
|
55
|
+
const baseAdapter = createShikiAdapter({
|
|
56
|
+
load: loadHighlighter,
|
|
43
57
|
theme: 'github-dark',
|
|
44
58
|
});
|
|
59
|
+
// Chakra's default `unloadContext` calls `dispose()` when a provider unmounts.
|
|
60
|
+
// The highlighter is shared, so one block unmounting would break highlighting
|
|
61
|
+
// in every other block. Keep it alive for the life of the page.
|
|
62
|
+
const shikiAdapter = {
|
|
63
|
+
...baseAdapter,
|
|
64
|
+
unloadContext: () => { },
|
|
65
|
+
};
|
|
45
66
|
|
|
46
67
|
export { BUNDLED_LANGUAGES, shikiAdapter };
|
|
47
68
|
//# sourceMappingURL=shikiAdapter.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shikiAdapter.mjs","sources":["../../../src/components/Code/shikiAdapter.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGO,MAAM,iBAAiB,GAAsB;IAClD,MAAM;IACN,GAAG;IACH,QAAQ;IACR,KAAK;IACL,MAAM;IACN,YAAY;IACZ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,YAAY;IACZ,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,GAAG;IACH,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,MAAM;IACN,KAAK;IACL,YAAY;IACZ,KAAK;IACL,MAAM;;
|
|
1
|
+
{"version":3,"file":"shikiAdapter.mjs","sources":["../../../src/components/Code/shikiAdapter.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAGO,MAAM,iBAAiB,GAAsB;IAClD,MAAM;IACN,GAAG;IACH,QAAQ;IACR,KAAK;IACL,MAAM;IACN,YAAY;IACZ,IAAI;IACJ,MAAM;IACN,MAAM;IACN,YAAY;IACZ,MAAM;IACN,KAAK;IACL,QAAQ;IACR,KAAK;IACL,UAAU;IACV,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,GAAG;IACH,MAAM;IACN,MAAM;IACN,OAAO;IACP,KAAK;IACL,OAAO;IACP,MAAM;IACN,KAAK;IACL,YAAY;IACZ,KAAK;IACL,MAAM;;AAKR;AACA;AACA;AACA;AACA,IAAI,kBAAkB,GAAuC,IAAI;AAEjE,MAAM,eAAe,GAAG,MAAkC;AACxD,IAAA,kBAAkB,KAAlB,kBAAkB,GAAK,OAAO,yCAAO;SAClC,IAAI,CAAC,CAAC,EAAE,iBAAiB,EAAE,KAC1B,iBAAiB,CAAC;AAChB,QAAA,KAAK,EAAE,iBAAiB;QACxB,MAAM,EAAE,CAAC,aAAa,CAAC;AACxB,KAAA,CAAC;AAEH,SAAA,KAAK,CAAC,CAAC,KAAc,KAAI;;;AAGxB,QAAA,OAAO,CAAC,KAAK,CACX,oDAAoD,EACpD,KAAK,CACN;QACD,kBAAkB,GAAG,IAAI;AACzB,QAAA,OAAO,IAAI;AACb,IAAA,CAAC,CAAC,CAAA;AACJ,IAAA,OAAO,kBAAkB;AAC3B,CAAC;AAED,MAAM,WAAW,GAAG,kBAAkB,CAAqB;AACzD,IAAA,IAAI,EAAE,eAAe;AACrB,IAAA,KAAK,EAAE,aAAa;AACrB,CAAA,CAAC;AAEF;AACA;AACA;AACO,MAAM,YAAY,GAAuB;AAC9C,IAAA,GAAG,WAAW;AACd,IAAA,aAAa,EAAE,MAAK,EAAE,CAAC;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpandableText.d.ts","sourceRoot":"","sources":["../../../src/components/ExpandableText/ExpandableText.tsx"],"names":[],"mappings":"AAGA,OAAO,EAUL,eAAe,EAChB,MAAM,yBAAyB,CAAC;AAMjC,QAAA,MAAM,eAAe;;;;;;;;;CASX,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE7D,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B,GAAG,eAAe,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GAAI,oEAM5B,mBAAmB,
|
|
1
|
+
{"version":3,"file":"ExpandableText.d.ts","sourceRoot":"","sources":["../../../src/components/ExpandableText/ExpandableText.tsx"],"names":[],"mappings":"AAGA,OAAO,EAUL,eAAe,EAChB,MAAM,yBAAyB,CAAC;AAMjC,QAAA,MAAM,eAAe;;;;;;;;;CASX,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,MAAM,OAAO,eAAe,CAAC;AAE7D,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B,GAAG,eAAe,CAAC;AAEpB;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,cAAc,GAAI,oEAM5B,mBAAmB,4CAkCrB,CAAC"}
|
|
@@ -49,7 +49,7 @@ const ExpandableText = ({ lineClamp = 3, charLimit: _charLimit, component = 'Tex
|
|
|
49
49
|
// and the cut always lands between them. Where `lh` is unsupported the
|
|
50
50
|
// declaration is dropped and the text simply shows in full — degraded,
|
|
51
51
|
// not broken.
|
|
52
|
-
maxHeight: maxHeight ?? `${lineClamp}lh`, animationStyle: "travel", transitionProperty: "max-height", children: children }), (isOverflowing || isExpanded) && (jsxRuntime.jsx(Link.Link, { as: "button",
|
|
52
|
+
maxHeight: maxHeight ?? `${lineClamp}lh`, animationStyle: "travel", transitionProperty: "max-height", children: children }), (isOverflowing || isExpanded) && (jsxRuntime.jsx(Link.Link, { as: "button", _hover: { color: 'fg.default' }, onClick: handleToggle, "aria-expanded": isExpanded, children: isExpanded ? translate('see_less') : translate('see_more') }))] }));
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
exports.ExpandableText = ExpandableText;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpandableText.js","sources":["../../../src/components/ExpandableText/ExpandableText.tsx"],"sourcesContent":[null],"names":["Text","Subtitle","Subtext","H1","H2","H3","H4","H5","useTranslate","useExpandableText","_jsxs","_jsx","Box","Link"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA;AACA,MAAM,eAAe,GAAG;UACtBA,SAAI;cACJC,iBAAQ;aACRC,eAAO;QACPC,KAAE;QACFC,KAAE;QACFC,KAAE;QACFC,KAAE;QACFC,KAAE;CACM;AAmBV;;;;;;;;;;;AAWG;AACI,MAAM,cAAc,GAAG,CAAC,EAC7B,SAAS,GAAG,CAAC,EACb,SAAS,EAAE,UAAU,EACrB,SAAS,GAAG,MAAM,EAClB,QAAQ,EACR,GAAG,IAAI,EACa,KAAI;AACxB,IAAA,MAAM,SAAS,GAAGC,yBAAY,EAAE;AAChC,IAAA,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GACtEC,mCAAiB,CAAC,SAAS,CAAC;AAE9B,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;AAE5C,IAAA,QACEC,eAAA,CAAC,SAAS,EAAA,EAAA,GAAK,IAAI,EAAA,QAAA,EAAA,CACjBC,cAAA,CAACC,SAAG,EAAA,EACF,GAAG,EAAE,UAAU,EACf,QAAQ,EAAC,QAAQ;;;;;AAKjB,gBAAA,SAAS,EAAE,SAAS,IAAI,CAAA,EAAG,SAAS,CAAA,EAAA,CAAI,EACxC,cAAc,EAAC,QAAQ,EACvB,kBAAkB,EAAC,YAAY,EAAA,QAAA,EAE9B,QAAQ,EAAA,CACL,EACL,CAAC,aAAa,IAAI,UAAU,MAC3BD,cAAA,CAACE,SAAI,EAAA,EACH,EAAE,EAAC,QAAQ,EACX,
|
|
1
|
+
{"version":3,"file":"ExpandableText.js","sources":["../../../src/components/ExpandableText/ExpandableText.tsx"],"sourcesContent":[null],"names":["Text","Subtitle","Subtext","H1","H2","H3","H4","H5","useTranslate","useExpandableText","_jsxs","_jsx","Box","Link"],"mappings":";;;;;;;;;;;;;;;;;;;AAmBA;AACA,MAAM,eAAe,GAAG;UACtBA,SAAI;cACJC,iBAAQ;aACRC,eAAO;QACPC,KAAE;QACFC,KAAE;QACFC,KAAE;QACFC,KAAE;QACFC,KAAE;CACM;AAmBV;;;;;;;;;;;AAWG;AACI,MAAM,cAAc,GAAG,CAAC,EAC7B,SAAS,GAAG,CAAC,EACb,SAAS,EAAE,UAAU,EACrB,SAAS,GAAG,MAAM,EAClB,QAAQ,EACR,GAAG,IAAI,EACa,KAAI;AACxB,IAAA,MAAM,SAAS,GAAGC,yBAAY,EAAE;AAChC,IAAA,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GACtEC,mCAAiB,CAAC,SAAS,CAAC;AAE9B,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;AAE5C,IAAA,QACEC,eAAA,CAAC,SAAS,EAAA,EAAA,GAAK,IAAI,EAAA,QAAA,EAAA,CACjBC,cAAA,CAACC,SAAG,EAAA,EACF,GAAG,EAAE,UAAU,EACf,QAAQ,EAAC,QAAQ;;;;;AAKjB,gBAAA,SAAS,EAAE,SAAS,IAAI,CAAA,EAAG,SAAS,CAAA,EAAA,CAAI,EACxC,cAAc,EAAC,QAAQ,EACvB,kBAAkB,EAAC,YAAY,EAAA,QAAA,EAE9B,QAAQ,EAAA,CACL,EACL,CAAC,aAAa,IAAI,UAAU,MAC3BD,cAAA,CAACE,SAAI,EAAA,EACH,EAAE,EAAC,QAAQ,EACX,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAC/B,OAAO,EAAE,YAAY,EAAA,eAAA,EACN,UAAU,EAAA,QAAA,EAExB,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,EAAA,CACtD,CACR,CAAA,EAAA,CACS;AAEhB;;;;"}
|
|
@@ -47,7 +47,7 @@ const ExpandableText = ({ lineClamp = 3, charLimit: _charLimit, component = 'Tex
|
|
|
47
47
|
// and the cut always lands between them. Where `lh` is unsupported the
|
|
48
48
|
// declaration is dropped and the text simply shows in full — degraded,
|
|
49
49
|
// not broken.
|
|
50
|
-
maxHeight: maxHeight ?? `${lineClamp}lh`, animationStyle: "travel", transitionProperty: "max-height", children: children }), (isOverflowing || isExpanded) && (jsx(Link, { as: "button",
|
|
50
|
+
maxHeight: maxHeight ?? `${lineClamp}lh`, animationStyle: "travel", transitionProperty: "max-height", children: children }), (isOverflowing || isExpanded) && (jsx(Link, { as: "button", _hover: { color: 'fg.default' }, onClick: handleToggle, "aria-expanded": isExpanded, children: isExpanded ? translate('see_less') : translate('see_more') }))] }));
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
export { ExpandableText };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpandableText.mjs","sources":["../../../src/components/ExpandableText/ExpandableText.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;;;;;;;;;;AAmBA;AACA,MAAM,eAAe,GAAG;IACtB,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,EAAE;IACF,EAAE;IACF,EAAE;IACF,EAAE;IACF,EAAE;CACM;AAmBV;;;;;;;;;;;AAWG;AACI,MAAM,cAAc,GAAG,CAAC,EAC7B,SAAS,GAAG,CAAC,EACb,SAAS,EAAE,UAAU,EACrB,SAAS,GAAG,MAAM,EAClB,QAAQ,EACR,GAAG,IAAI,EACa,KAAI;AACxB,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;AAChC,IAAA,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GACtE,iBAAiB,CAAC,SAAS,CAAC;AAE9B,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;AAE5C,IAAA,QACEA,IAAA,CAAC,SAAS,EAAA,EAAA,GAAK,IAAI,EAAA,QAAA,EAAA,CACjBC,GAAA,CAAC,GAAG,EAAA,EACF,GAAG,EAAE,UAAU,EACf,QAAQ,EAAC,QAAQ;;;;;AAKjB,gBAAA,SAAS,EAAE,SAAS,IAAI,CAAA,EAAG,SAAS,CAAA,EAAA,CAAI,EACxC,cAAc,EAAC,QAAQ,EACvB,kBAAkB,EAAC,YAAY,EAAA,QAAA,EAE9B,QAAQ,EAAA,CACL,EACL,CAAC,aAAa,IAAI,UAAU,MAC3BA,GAAA,CAAC,IAAI,EAAA,EACH,EAAE,EAAC,QAAQ,EACX,
|
|
1
|
+
{"version":3,"file":"ExpandableText.mjs","sources":["../../../src/components/ExpandableText/ExpandableText.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":";;;;;;;;;;;;;;;;;AAmBA;AACA,MAAM,eAAe,GAAG;IACtB,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,EAAE;IACF,EAAE;IACF,EAAE;IACF,EAAE;IACF,EAAE;CACM;AAmBV;;;;;;;;;;;AAWG;AACI,MAAM,cAAc,GAAG,CAAC,EAC7B,SAAS,GAAG,CAAC,EACb,SAAS,EAAE,UAAU,EACrB,SAAS,GAAG,MAAM,EAClB,QAAQ,EACR,GAAG,IAAI,EACa,KAAI;AACxB,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;AAChC,IAAA,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,GACtE,iBAAiB,CAAC,SAAS,CAAC;AAE9B,IAAA,MAAM,SAAS,GAAG,eAAe,CAAC,SAAS,CAAC;AAE5C,IAAA,QACEA,IAAA,CAAC,SAAS,EAAA,EAAA,GAAK,IAAI,EAAA,QAAA,EAAA,CACjBC,GAAA,CAAC,GAAG,EAAA,EACF,GAAG,EAAE,UAAU,EACf,QAAQ,EAAC,QAAQ;;;;;AAKjB,gBAAA,SAAS,EAAE,SAAS,IAAI,CAAA,EAAG,SAAS,CAAA,EAAA,CAAI,EACxC,cAAc,EAAC,QAAQ,EACvB,kBAAkB,EAAC,YAAY,EAAA,QAAA,EAE9B,QAAQ,EAAA,CACL,EACL,CAAC,aAAa,IAAI,UAAU,MAC3BA,GAAA,CAAC,IAAI,EAAA,EACH,EAAE,EAAC,QAAQ,EACX,MAAM,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAC/B,OAAO,EAAE,YAAY,EAAA,eAAA,EACN,UAAU,EAAA,QAAA,EAExB,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC,UAAU,CAAC,EAAA,CACtD,CACR,CAAA,EAAA,CACS;AAEhB;;;;"}
|
|
@@ -312,7 +312,7 @@ export declare const SCHEMES: {
|
|
|
312
312
|
readonly "disabled-fg": "#8A8A8A";
|
|
313
313
|
readonly "disabled-fgGhost": "#C2C2C2";
|
|
314
314
|
readonly "fg-link": "#48607A";
|
|
315
|
-
readonly "fg-linkHover": "#
|
|
315
|
+
readonly "fg-linkHover": "#304760";
|
|
316
316
|
readonly focus: "#252525";
|
|
317
317
|
readonly "danger-bg": "#FEE9E6";
|
|
318
318
|
readonly "danger-border": "#F3C3BD";
|
|
@@ -403,7 +403,7 @@ export declare const SCHEMES: {
|
|
|
403
403
|
readonly "disabled-fg": "#737373";
|
|
404
404
|
readonly "disabled-fgGhost": "#4A4A4A";
|
|
405
405
|
readonly "fg-link": "#AFC7E1";
|
|
406
|
-
readonly "fg-linkHover": "#
|
|
406
|
+
readonly "fg-linkHover": "#C5DEF8";
|
|
407
407
|
readonly focus: "#D6D3CD";
|
|
408
408
|
readonly "danger-bg": "#47211E";
|
|
409
409
|
readonly "danger-border": "#6E3530";
|
|
@@ -494,7 +494,7 @@ export declare const SCHEMES: {
|
|
|
494
494
|
readonly "disabled-fg": "#8A8A8A";
|
|
495
495
|
readonly "disabled-fgGhost": "#C2C2C2";
|
|
496
496
|
readonly "fg-link": "#3B536C";
|
|
497
|
-
readonly "fg-linkHover": "#
|
|
497
|
+
readonly "fg-linkHover": "#304760";
|
|
498
498
|
readonly focus: "#252525";
|
|
499
499
|
readonly "danger-bg": "#FEE9E6";
|
|
500
500
|
readonly "danger-border": "#AA7E79";
|
|
@@ -585,7 +585,7 @@ export declare const SCHEMES: {
|
|
|
585
585
|
readonly "disabled-fg": "#737373";
|
|
586
586
|
readonly "disabled-fgGhost": "#4A4A4A";
|
|
587
587
|
readonly "fg-link": "#BED7F1";
|
|
588
|
-
readonly "fg-linkHover": "#
|
|
588
|
+
readonly "fg-linkHover": "#C5DEF8";
|
|
589
589
|
readonly focus: "#D6D3CD";
|
|
590
590
|
readonly "danger-bg": "#47211E";
|
|
591
591
|
readonly "danger-border": "#A2645D";
|
|
@@ -678,7 +678,7 @@ export declare const SCHEMES: {
|
|
|
678
678
|
readonly "disabled-fg": "#8A8A8A";
|
|
679
679
|
readonly "disabled-fgGhost": "#C2C2C2";
|
|
680
680
|
readonly "fg-link": "#48607A";
|
|
681
|
-
readonly "fg-linkHover": "#
|
|
681
|
+
readonly "fg-linkHover": "#304760";
|
|
682
682
|
readonly focus: "#1F2534";
|
|
683
683
|
readonly "danger-bg": "#FEE9E6";
|
|
684
684
|
readonly "danger-border": "#F3C3BD";
|
|
@@ -769,7 +769,7 @@ export declare const SCHEMES: {
|
|
|
769
769
|
readonly "disabled-fg": "#737373";
|
|
770
770
|
readonly "disabled-fgGhost": "#4A4A4A";
|
|
771
771
|
readonly "fg-link": "#AFC7E1";
|
|
772
|
-
readonly "fg-linkHover": "#
|
|
772
|
+
readonly "fg-linkHover": "#C5DEF8";
|
|
773
773
|
readonly focus: "#D5D9E1";
|
|
774
774
|
readonly "danger-bg": "#47211E";
|
|
775
775
|
readonly "danger-border": "#6E3530";
|
|
@@ -860,7 +860,7 @@ export declare const SCHEMES: {
|
|
|
860
860
|
readonly "disabled-fg": "#8A8A8A";
|
|
861
861
|
readonly "disabled-fgGhost": "#C2C2C2";
|
|
862
862
|
readonly "fg-link": "#3C536C";
|
|
863
|
-
readonly "fg-linkHover": "#
|
|
863
|
+
readonly "fg-linkHover": "#304760";
|
|
864
864
|
readonly focus: "#1F2534";
|
|
865
865
|
readonly "danger-bg": "#FEE9E6";
|
|
866
866
|
readonly "danger-border": "#AA7E79";
|
|
@@ -951,7 +951,7 @@ export declare const SCHEMES: {
|
|
|
951
951
|
readonly "disabled-fg": "#737373";
|
|
952
952
|
readonly "disabled-fgGhost": "#4A4A4A";
|
|
953
953
|
readonly "fg-link": "#C7DFFA";
|
|
954
|
-
readonly "fg-linkHover": "#
|
|
954
|
+
readonly "fg-linkHover": "#C6DFF9";
|
|
955
955
|
readonly focus: "#D5D9E1";
|
|
956
956
|
readonly "danger-bg": "#47211E";
|
|
957
957
|
readonly "danger-border": "#A2645D";
|
|
@@ -318,7 +318,7 @@ const SCHEMES = {
|
|
|
318
318
|
"disabled-fg": "#8A8A8A",
|
|
319
319
|
"disabled-fgGhost": "#C2C2C2",
|
|
320
320
|
"fg-link": "#48607A",
|
|
321
|
-
"fg-linkHover": "#
|
|
321
|
+
"fg-linkHover": "#304760",
|
|
322
322
|
"focus": "#252525",
|
|
323
323
|
"danger-bg": "#FEE9E6",
|
|
324
324
|
"danger-border": "#F3C3BD",
|
|
@@ -409,7 +409,7 @@ const SCHEMES = {
|
|
|
409
409
|
"disabled-fg": "#737373",
|
|
410
410
|
"disabled-fgGhost": "#4A4A4A",
|
|
411
411
|
"fg-link": "#AFC7E1",
|
|
412
|
-
"fg-linkHover": "#
|
|
412
|
+
"fg-linkHover": "#C5DEF8",
|
|
413
413
|
"focus": "#D6D3CD",
|
|
414
414
|
"danger-bg": "#47211E",
|
|
415
415
|
"danger-border": "#6E3530",
|
|
@@ -500,7 +500,7 @@ const SCHEMES = {
|
|
|
500
500
|
"disabled-fg": "#8A8A8A",
|
|
501
501
|
"disabled-fgGhost": "#C2C2C2",
|
|
502
502
|
"fg-link": "#3B536C",
|
|
503
|
-
"fg-linkHover": "#
|
|
503
|
+
"fg-linkHover": "#304760",
|
|
504
504
|
"focus": "#252525",
|
|
505
505
|
"danger-bg": "#FEE9E6",
|
|
506
506
|
"danger-border": "#AA7E79",
|
|
@@ -591,7 +591,7 @@ const SCHEMES = {
|
|
|
591
591
|
"disabled-fg": "#737373",
|
|
592
592
|
"disabled-fgGhost": "#4A4A4A",
|
|
593
593
|
"fg-link": "#BED7F1",
|
|
594
|
-
"fg-linkHover": "#
|
|
594
|
+
"fg-linkHover": "#C5DEF8",
|
|
595
595
|
"focus": "#D6D3CD",
|
|
596
596
|
"danger-bg": "#47211E",
|
|
597
597
|
"danger-border": "#A2645D",
|
|
@@ -684,7 +684,7 @@ const SCHEMES = {
|
|
|
684
684
|
"disabled-fg": "#8A8A8A",
|
|
685
685
|
"disabled-fgGhost": "#C2C2C2",
|
|
686
686
|
"fg-link": "#48607A",
|
|
687
|
-
"fg-linkHover": "#
|
|
687
|
+
"fg-linkHover": "#304760",
|
|
688
688
|
"focus": "#1F2534",
|
|
689
689
|
"danger-bg": "#FEE9E6",
|
|
690
690
|
"danger-border": "#F3C3BD",
|
|
@@ -775,7 +775,7 @@ const SCHEMES = {
|
|
|
775
775
|
"disabled-fg": "#737373",
|
|
776
776
|
"disabled-fgGhost": "#4A4A4A",
|
|
777
777
|
"fg-link": "#AFC7E1",
|
|
778
|
-
"fg-linkHover": "#
|
|
778
|
+
"fg-linkHover": "#C5DEF8",
|
|
779
779
|
"focus": "#D5D9E1",
|
|
780
780
|
"danger-bg": "#47211E",
|
|
781
781
|
"danger-border": "#6E3530",
|
|
@@ -866,7 +866,7 @@ const SCHEMES = {
|
|
|
866
866
|
"disabled-fg": "#8A8A8A",
|
|
867
867
|
"disabled-fgGhost": "#C2C2C2",
|
|
868
868
|
"fg-link": "#3C536C",
|
|
869
|
-
"fg-linkHover": "#
|
|
869
|
+
"fg-linkHover": "#304760",
|
|
870
870
|
"focus": "#1F2534",
|
|
871
871
|
"danger-bg": "#FEE9E6",
|
|
872
872
|
"danger-border": "#AA7E79",
|
|
@@ -957,7 +957,7 @@ const SCHEMES = {
|
|
|
957
957
|
"disabled-fg": "#737373",
|
|
958
958
|
"disabled-fgGhost": "#4A4A4A",
|
|
959
959
|
"fg-link": "#C7DFFA",
|
|
960
|
-
"fg-linkHover": "#
|
|
960
|
+
"fg-linkHover": "#C6DFF9",
|
|
961
961
|
"focus": "#D5D9E1",
|
|
962
962
|
"danger-bg": "#47211E",
|
|
963
963
|
"danger-border": "#A2645D",
|
|
@@ -316,7 +316,7 @@ const SCHEMES = {
|
|
|
316
316
|
"disabled-fg": "#8A8A8A",
|
|
317
317
|
"disabled-fgGhost": "#C2C2C2",
|
|
318
318
|
"fg-link": "#48607A",
|
|
319
|
-
"fg-linkHover": "#
|
|
319
|
+
"fg-linkHover": "#304760",
|
|
320
320
|
"focus": "#252525",
|
|
321
321
|
"danger-bg": "#FEE9E6",
|
|
322
322
|
"danger-border": "#F3C3BD",
|
|
@@ -407,7 +407,7 @@ const SCHEMES = {
|
|
|
407
407
|
"disabled-fg": "#737373",
|
|
408
408
|
"disabled-fgGhost": "#4A4A4A",
|
|
409
409
|
"fg-link": "#AFC7E1",
|
|
410
|
-
"fg-linkHover": "#
|
|
410
|
+
"fg-linkHover": "#C5DEF8",
|
|
411
411
|
"focus": "#D6D3CD",
|
|
412
412
|
"danger-bg": "#47211E",
|
|
413
413
|
"danger-border": "#6E3530",
|
|
@@ -498,7 +498,7 @@ const SCHEMES = {
|
|
|
498
498
|
"disabled-fg": "#8A8A8A",
|
|
499
499
|
"disabled-fgGhost": "#C2C2C2",
|
|
500
500
|
"fg-link": "#3B536C",
|
|
501
|
-
"fg-linkHover": "#
|
|
501
|
+
"fg-linkHover": "#304760",
|
|
502
502
|
"focus": "#252525",
|
|
503
503
|
"danger-bg": "#FEE9E6",
|
|
504
504
|
"danger-border": "#AA7E79",
|
|
@@ -589,7 +589,7 @@ const SCHEMES = {
|
|
|
589
589
|
"disabled-fg": "#737373",
|
|
590
590
|
"disabled-fgGhost": "#4A4A4A",
|
|
591
591
|
"fg-link": "#BED7F1",
|
|
592
|
-
"fg-linkHover": "#
|
|
592
|
+
"fg-linkHover": "#C5DEF8",
|
|
593
593
|
"focus": "#D6D3CD",
|
|
594
594
|
"danger-bg": "#47211E",
|
|
595
595
|
"danger-border": "#A2645D",
|
|
@@ -682,7 +682,7 @@ const SCHEMES = {
|
|
|
682
682
|
"disabled-fg": "#8A8A8A",
|
|
683
683
|
"disabled-fgGhost": "#C2C2C2",
|
|
684
684
|
"fg-link": "#48607A",
|
|
685
|
-
"fg-linkHover": "#
|
|
685
|
+
"fg-linkHover": "#304760",
|
|
686
686
|
"focus": "#1F2534",
|
|
687
687
|
"danger-bg": "#FEE9E6",
|
|
688
688
|
"danger-border": "#F3C3BD",
|
|
@@ -773,7 +773,7 @@ const SCHEMES = {
|
|
|
773
773
|
"disabled-fg": "#737373",
|
|
774
774
|
"disabled-fgGhost": "#4A4A4A",
|
|
775
775
|
"fg-link": "#AFC7E1",
|
|
776
|
-
"fg-linkHover": "#
|
|
776
|
+
"fg-linkHover": "#C5DEF8",
|
|
777
777
|
"focus": "#D5D9E1",
|
|
778
778
|
"danger-bg": "#47211E",
|
|
779
779
|
"danger-border": "#6E3530",
|
|
@@ -864,7 +864,7 @@ const SCHEMES = {
|
|
|
864
864
|
"disabled-fg": "#8A8A8A",
|
|
865
865
|
"disabled-fgGhost": "#C2C2C2",
|
|
866
866
|
"fg-link": "#3C536C",
|
|
867
|
-
"fg-linkHover": "#
|
|
867
|
+
"fg-linkHover": "#304760",
|
|
868
868
|
"focus": "#1F2534",
|
|
869
869
|
"danger-bg": "#FEE9E6",
|
|
870
870
|
"danger-border": "#AA7E79",
|
|
@@ -955,7 +955,7 @@ const SCHEMES = {
|
|
|
955
955
|
"disabled-fg": "#737373",
|
|
956
956
|
"disabled-fgGhost": "#4A4A4A",
|
|
957
957
|
"fg-link": "#C7DFFA",
|
|
958
|
-
"fg-linkHover": "#
|
|
958
|
+
"fg-linkHover": "#C6DFF9",
|
|
959
959
|
"focus": "#D5D9E1",
|
|
960
960
|
"danger-bg": "#47211E",
|
|
961
961
|
"danger-border": "#A2645D",
|
package/package.json
CHANGED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ChakraProvider } from '@chakra-ui/react';
|
|
2
|
+
import { render, waitFor } from '@testing-library/react';
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
|
|
5
|
+
import { system } from '../../theme';
|
|
6
|
+
|
|
7
|
+
const shiki = vi.hoisted(() => ({
|
|
8
|
+
createHighlighter: vi.fn(),
|
|
9
|
+
dispose: vi.fn(),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
// The real Shiki compiles grammars through WASM, which is slow in jsdom and
|
|
13
|
+
// not what these tests are about. The fake marks highlighted output with a
|
|
14
|
+
// class so a test can tell highlighted text from the plain-text fallback.
|
|
15
|
+
vi.mock('shiki', () => ({
|
|
16
|
+
createHighlighter: shiki.createHighlighter,
|
|
17
|
+
}));
|
|
18
|
+
|
|
19
|
+
const fakeHighlighter = {
|
|
20
|
+
codeToHtml: (code: string) =>
|
|
21
|
+
`<pre><code><span class="test-highlighted">${code}</span></code></pre>`,
|
|
22
|
+
dispose: shiki.dispose,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// shikiAdapter caches the highlighter at module level. Re-import Code per test
|
|
26
|
+
// so each one starts with an empty cache.
|
|
27
|
+
const loadCode = async () => (await import('./Code')).Code;
|
|
28
|
+
|
|
29
|
+
const wrap = (ui: React.ReactNode) =>
|
|
30
|
+
render(<ChakraProvider value={system}>{ui}</ChakraProvider>);
|
|
31
|
+
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
vi.resetModules();
|
|
34
|
+
shiki.createHighlighter.mockReset();
|
|
35
|
+
shiki.createHighlighter.mockResolvedValue(fakeHighlighter);
|
|
36
|
+
shiki.dispose.mockReset();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('Code highlighter', () => {
|
|
40
|
+
it('creates one highlighter for many code blocks', async () => {
|
|
41
|
+
const Code = await loadCode();
|
|
42
|
+
const { container } = wrap(
|
|
43
|
+
<>
|
|
44
|
+
{Array.from({ length: 20 }, (_, i) => (
|
|
45
|
+
<Code key={i} language="javascript">{`const n = ${i};`}</Code>
|
|
46
|
+
))}
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
await waitFor(() =>
|
|
51
|
+
expect(container.querySelectorAll('.test-highlighted')).toHaveLength(20)
|
|
52
|
+
);
|
|
53
|
+
expect(shiki.createHighlighter).toHaveBeenCalledTimes(1);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('keeps highlighting the other blocks when one block unmounts', async () => {
|
|
57
|
+
const Code = await loadCode();
|
|
58
|
+
const Blocks = ({ showFirst }: { showFirst: boolean }) => (
|
|
59
|
+
<>
|
|
60
|
+
{showFirst && <Code language="javascript">first</Code>}
|
|
61
|
+
<Code language="javascript">second</Code>
|
|
62
|
+
</>
|
|
63
|
+
);
|
|
64
|
+
const { container, rerender } = wrap(<Blocks showFirst />);
|
|
65
|
+
await waitFor(() =>
|
|
66
|
+
expect(container.querySelectorAll('.test-highlighted')).toHaveLength(2)
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
rerender(
|
|
70
|
+
<ChakraProvider value={system}>
|
|
71
|
+
<Blocks showFirst={false} />
|
|
72
|
+
</ChakraProvider>
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
expect(shiki.dispose).not.toHaveBeenCalled();
|
|
76
|
+
expect(container.querySelectorAll('.test-highlighted')).toHaveLength(1);
|
|
77
|
+
|
|
78
|
+
// A block mounted later reuses the same highlighter.
|
|
79
|
+
rerender(
|
|
80
|
+
<ChakraProvider value={system}>
|
|
81
|
+
<Blocks showFirst />
|
|
82
|
+
</ChakraProvider>
|
|
83
|
+
);
|
|
84
|
+
await waitFor(() =>
|
|
85
|
+
expect(container.querySelectorAll('.test-highlighted')).toHaveLength(2)
|
|
86
|
+
);
|
|
87
|
+
expect(shiki.createHighlighter).toHaveBeenCalledTimes(1);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('retries on the next mount when loading fails', async () => {
|
|
91
|
+
const consoleError = vi
|
|
92
|
+
.spyOn(console, 'error')
|
|
93
|
+
.mockImplementation(() => {});
|
|
94
|
+
shiki.createHighlighter.mockRejectedValueOnce(new Error('load failed'));
|
|
95
|
+
const Code = await loadCode();
|
|
96
|
+
|
|
97
|
+
const first = wrap(<Code language="javascript">a</Code>);
|
|
98
|
+
await waitFor(() =>
|
|
99
|
+
expect(consoleError).toHaveBeenCalledWith(
|
|
100
|
+
expect.stringContaining('Failed to load the Shiki highlighter'),
|
|
101
|
+
expect.any(Error)
|
|
102
|
+
)
|
|
103
|
+
);
|
|
104
|
+
// The failed block falls back to plain text instead of throwing.
|
|
105
|
+
expect(first.container).toHaveTextContent('a');
|
|
106
|
+
expect(first.container.querySelector('.test-highlighted')).toBeNull();
|
|
107
|
+
first.unmount();
|
|
108
|
+
|
|
109
|
+
const { container } = wrap(<Code language="javascript">b</Code>);
|
|
110
|
+
await waitFor(() =>
|
|
111
|
+
expect(container.querySelectorAll('.test-highlighted')).toHaveLength(1)
|
|
112
|
+
);
|
|
113
|
+
expect(shiki.createHighlighter).toHaveBeenCalledTimes(2);
|
|
114
|
+
consoleError.mockRestore();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
@@ -33,15 +33,44 @@ export const BUNDLED_LANGUAGES: BundledLanguage[] = [
|
|
|
33
33
|
'yaml',
|
|
34
34
|
];
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
type Highlighter = HighlighterGeneric<BundledLanguage, BundledTheme>;
|
|
37
|
+
|
|
38
|
+
// One highlighter for the whole app. Every <Code> mounts its own
|
|
39
|
+
// AdapterProvider, and Chakra calls `load()` once per provider. Without this
|
|
40
|
+
// cache a chat with 136 code blocks built 136 highlighters, each compiling all
|
|
41
|
+
// BUNDLED_LANGUAGES, and froze the tab for tens of seconds.
|
|
42
|
+
let highlighterPromise: Promise<Highlighter | null> | null = null;
|
|
43
|
+
|
|
44
|
+
const loadHighlighter = (): Promise<Highlighter | null> => {
|
|
45
|
+
highlighterPromise ??= import('shiki')
|
|
46
|
+
.then(({ createHighlighter }) =>
|
|
47
|
+
createHighlighter({
|
|
48
|
+
langs: BUNDLED_LANGUAGES,
|
|
49
|
+
themes: ['github-dark'],
|
|
50
|
+
})
|
|
51
|
+
)
|
|
52
|
+
.catch((error: unknown) => {
|
|
53
|
+
// Chakra does not catch a rejected load, so resolve to null instead: the
|
|
54
|
+
// block renders as plain text. Clear the cache so the next mount retries.
|
|
55
|
+
console.error(
|
|
56
|
+
'[logician-ui] Failed to load the Shiki highlighter',
|
|
57
|
+
error
|
|
58
|
+
);
|
|
59
|
+
highlighterPromise = null;
|
|
60
|
+
return null;
|
|
44
61
|
});
|
|
45
|
-
|
|
62
|
+
return highlighterPromise;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const baseAdapter = createShikiAdapter<Highlighter | null>({
|
|
66
|
+
load: loadHighlighter,
|
|
46
67
|
theme: 'github-dark',
|
|
47
68
|
});
|
|
69
|
+
|
|
70
|
+
// Chakra's default `unloadContext` calls `dispose()` when a provider unmounts.
|
|
71
|
+
// The highlighter is shared, so one block unmounting would break highlighting
|
|
72
|
+
// in every other block. Keep it alive for the life of the page.
|
|
73
|
+
export const shikiAdapter: typeof baseAdapter = {
|
|
74
|
+
...baseAdapter,
|
|
75
|
+
unloadContext: () => {},
|
|
76
|
+
};
|
|
@@ -114,8 +114,9 @@ What you still have to do:
|
|
|
114
114
|
|
|
115
115
|
## Tokens
|
|
116
116
|
|
|
117
|
-
The toggle is a `Link
|
|
118
|
-
|
|
117
|
+
The toggle is a `Link`, underlined like every other link (it sits right after
|
|
118
|
+
body text, so colour alone would not set it apart — WCAG 1.4.1). On hover it
|
|
119
|
+
turns `fg.default` instead of `fg.linkHover`, and the underline thickens.
|
|
119
120
|
|
|
120
121
|
</En>
|
|
121
122
|
|
|
@@ -148,8 +149,9 @@ ExpandableText가 알아서 하는 일
|
|
|
148
149
|
|
|
149
150
|
## 토큰
|
|
150
151
|
|
|
151
|
-
펼침 버튼은 `Link
|
|
152
|
-
|
|
152
|
+
펼침 버튼은 `Link`이고, 다른 링크처럼 밑줄이 있습니다. 본문 바로 뒤에 붙어 있어
|
|
153
|
+
색만으로는 구분되지 않기 때문입니다(WCAG 1.4.1). 호버하면 `fg.linkHover`가 아니라
|
|
154
|
+
`fg.default`로 바뀌고, 밑줄이 굵어집니다.
|
|
153
155
|
|
|
154
156
|
</Ko>
|
|
155
157
|
|
|
@@ -459,27 +459,18 @@ describe('브랜드 색 대비 — Link · Tab 램프', () => {
|
|
|
459
459
|
expect(hover).toBeGreaterThan(resting);
|
|
460
460
|
});
|
|
461
461
|
|
|
462
|
-
//
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
//
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
DARK_CANVAS
|
|
475
|
-
);
|
|
476
|
-
const hover = contrast(
|
|
477
|
-
resolve(LINK_RAMP.defaultHover, '_dark'),
|
|
478
|
-
DARK_CANVAS
|
|
479
|
-
);
|
|
480
|
-
expect(hover).toBeGreaterThan(resting);
|
|
481
|
-
}
|
|
482
|
-
);
|
|
462
|
+
// The BAZE guide's dark `fg.linkHover` #8BB7E3 went TOWARD the background
|
|
463
|
+
// (6.52:1 on bg.surface against the resting link's 7.89:1) and sat here as
|
|
464
|
+
// `it.fails`. Fixed by making the dark hover lighter than the resting link
|
|
465
|
+
// (#C5DEF8, 10.66:1 on bg.surface).
|
|
466
|
+
it('hover 가 배경 반대쪽으로 간다 — 다크', () => {
|
|
467
|
+
const resting = contrast(resolve(LINK_RAMP.default, '_dark'), DARK_CANVAS);
|
|
468
|
+
const hover = contrast(
|
|
469
|
+
resolve(LINK_RAMP.defaultHover, '_dark'),
|
|
470
|
+
DARK_CANVAS
|
|
471
|
+
);
|
|
472
|
+
expect(hover).toBeGreaterThan(resting);
|
|
473
|
+
});
|
|
483
474
|
|
|
484
475
|
it('선택된 가로 탭의 레이블이 라이트·다크 양쪽에서 4.5:1 을 넘는다', () => {
|
|
485
476
|
// Measured against the RAISED surface (bg.surface), not the page canvas:
|
|
@@ -32,7 +32,7 @@ createLogicianTheme({ neutral: 'slate' }) // cool gray — app code unchanged
|
|
|
32
32
|
| Raised surface (card, menu, popover, input) | `bg.surface` |
|
|
33
33
|
| Body · secondary · caption text | `fg.default` · `fg.muted` · `fg.subtle` |
|
|
34
34
|
| Icon · placeholder | `fg.icon` · `fg.placeholder` |
|
|
35
|
-
| Link | `fg.link` + underline
|
|
35
|
+
| Link | `fg.link` + 1px underline at rest; hover `fg.linkHover` + 2px underline |
|
|
36
36
|
| Divider · card border · input/checkbox border | `border.subtle` · `border.default` · `border.control` |
|
|
37
37
|
| Primary (black) fill · text on it | `primary.main` / `.hover` / `.active` · `fg.onPrimary` |
|
|
38
38
|
| Hover / press wash, selected row | `primary.wash` / `primary.washActive` · `primary.selected` |
|
|
@@ -57,8 +57,14 @@ that is what `category.*` is for.
|
|
|
57
57
|
Blue is the one hue BAZE gives a meaning outside status: **data and links**.
|
|
58
58
|
Use it for both, and for nothing decorative.
|
|
59
59
|
|
|
60
|
-
- **Links** — `fg.link`
|
|
60
|
+
- **Links** — `fg.link` (blue ink, #48607A light / #AFC7E1 dark), in chat
|
|
61
61
|
messages, markdown and app copy alike. Never ink-black or coral for a link.
|
|
62
|
+
**Always underlined, at rest too**: next to body text (#252525) the blue is
|
|
63
|
+
only 2.36:1, under the 3:1 that colour alone would need (WCAG 1.4.1), so the
|
|
64
|
+
underline is what marks it as a link. Hover is `fg.linkHover` — further from
|
|
65
|
+
the canvas than rest, never toward it: #304760 light (9.56:1 on white vs
|
|
66
|
+
6.50:1 at rest), #C5DEF8 dark (10.66:1 vs 8.48:1 on `bg.surface`) — and the
|
|
67
|
+
underline thickens to 2px.
|
|
62
68
|
- **Data visualisation** — usage/share bars, single-measure bar charts, maps,
|
|
63
69
|
heatmaps, progress-by-share: the `data.*` ramp, a **blue monochrome ramp**,
|
|
64
70
|
never a rainbow and never a grey ramp. Steps differ in lightness only (the
|
|
@@ -320,7 +320,7 @@ export const SCHEMES = {
|
|
|
320
320
|
"disabled-fg": "#8A8A8A",
|
|
321
321
|
"disabled-fgGhost": "#C2C2C2",
|
|
322
322
|
"fg-link": "#48607A",
|
|
323
|
-
"fg-linkHover": "#
|
|
323
|
+
"fg-linkHover": "#304760",
|
|
324
324
|
"focus": "#252525",
|
|
325
325
|
"danger-bg": "#FEE9E6",
|
|
326
326
|
"danger-border": "#F3C3BD",
|
|
@@ -411,7 +411,7 @@ export const SCHEMES = {
|
|
|
411
411
|
"disabled-fg": "#737373",
|
|
412
412
|
"disabled-fgGhost": "#4A4A4A",
|
|
413
413
|
"fg-link": "#AFC7E1",
|
|
414
|
-
"fg-linkHover": "#
|
|
414
|
+
"fg-linkHover": "#C5DEF8",
|
|
415
415
|
"focus": "#D6D3CD",
|
|
416
416
|
"danger-bg": "#47211E",
|
|
417
417
|
"danger-border": "#6E3530",
|
|
@@ -502,7 +502,7 @@ export const SCHEMES = {
|
|
|
502
502
|
"disabled-fg": "#8A8A8A",
|
|
503
503
|
"disabled-fgGhost": "#C2C2C2",
|
|
504
504
|
"fg-link": "#3B536C",
|
|
505
|
-
"fg-linkHover": "#
|
|
505
|
+
"fg-linkHover": "#304760",
|
|
506
506
|
"focus": "#252525",
|
|
507
507
|
"danger-bg": "#FEE9E6",
|
|
508
508
|
"danger-border": "#AA7E79",
|
|
@@ -593,7 +593,7 @@ export const SCHEMES = {
|
|
|
593
593
|
"disabled-fg": "#737373",
|
|
594
594
|
"disabled-fgGhost": "#4A4A4A",
|
|
595
595
|
"fg-link": "#BED7F1",
|
|
596
|
-
"fg-linkHover": "#
|
|
596
|
+
"fg-linkHover": "#C5DEF8",
|
|
597
597
|
"focus": "#D6D3CD",
|
|
598
598
|
"danger-bg": "#47211E",
|
|
599
599
|
"danger-border": "#A2645D",
|
|
@@ -686,7 +686,7 @@ export const SCHEMES = {
|
|
|
686
686
|
"disabled-fg": "#8A8A8A",
|
|
687
687
|
"disabled-fgGhost": "#C2C2C2",
|
|
688
688
|
"fg-link": "#48607A",
|
|
689
|
-
"fg-linkHover": "#
|
|
689
|
+
"fg-linkHover": "#304760",
|
|
690
690
|
"focus": "#1F2534",
|
|
691
691
|
"danger-bg": "#FEE9E6",
|
|
692
692
|
"danger-border": "#F3C3BD",
|
|
@@ -777,7 +777,7 @@ export const SCHEMES = {
|
|
|
777
777
|
"disabled-fg": "#737373",
|
|
778
778
|
"disabled-fgGhost": "#4A4A4A",
|
|
779
779
|
"fg-link": "#AFC7E1",
|
|
780
|
-
"fg-linkHover": "#
|
|
780
|
+
"fg-linkHover": "#C5DEF8",
|
|
781
781
|
"focus": "#D5D9E1",
|
|
782
782
|
"danger-bg": "#47211E",
|
|
783
783
|
"danger-border": "#6E3530",
|
|
@@ -868,7 +868,7 @@ export const SCHEMES = {
|
|
|
868
868
|
"disabled-fg": "#8A8A8A",
|
|
869
869
|
"disabled-fgGhost": "#C2C2C2",
|
|
870
870
|
"fg-link": "#3C536C",
|
|
871
|
-
"fg-linkHover": "#
|
|
871
|
+
"fg-linkHover": "#304760",
|
|
872
872
|
"focus": "#1F2534",
|
|
873
873
|
"danger-bg": "#FEE9E6",
|
|
874
874
|
"danger-border": "#AA7E79",
|
|
@@ -959,7 +959,7 @@ export const SCHEMES = {
|
|
|
959
959
|
"disabled-fg": "#737373",
|
|
960
960
|
"disabled-fgGhost": "#4A4A4A",
|
|
961
961
|
"fg-link": "#C7DFFA",
|
|
962
|
-
"fg-linkHover": "#
|
|
962
|
+
"fg-linkHover": "#C6DFF9",
|
|
963
963
|
"focus": "#D5D9E1",
|
|
964
964
|
"danger-bg": "#47211E",
|
|
965
965
|
"danger-border": "#A2645D",
|