tosijs-ui 1.7.2 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/color-input.d.ts +0 -1
- package/dist/color-input.js +24 -10
- package/dist/doc-browser.js +4 -2
- package/dist/doc-system/doc-system-styles.d.ts +2 -0
- package/dist/doc-system/doc-system-styles.js +15 -1
- package/dist/doc-system/site/check-examples-cli.js +5 -3
- package/dist/doc-system/site/check-examples.d.ts +13 -0
- package/dist/doc-system/site/check-examples.js +26 -10
- package/dist/doc-system/site/orchestrator.js +15 -2
- package/dist/form.d.ts +0 -1
- package/dist/form.js +35 -21
- package/dist/hydrate/hydrate.js +82 -82
- package/dist/hydrate/hydrate.js.map +15 -14
- package/dist/iife.js +114 -114
- package/dist/iife.js.map +15 -14
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/live-example/code-transform.d.ts +14 -0
- package/dist/live-example/code-transform.js +20 -2
- package/dist/live-example/component.d.ts +24 -51
- package/dist/live-example/component.js +44 -51
- package/dist/live-example/styles.d.ts +22 -50
- package/dist/live-example/styles.js +48 -49
- package/dist/live-example/types.d.ts +2 -2
- package/dist/pocket-bar.d.ts +99 -0
- package/dist/pocket-bar.js +298 -0
- package/dist/pop-float.d.ts +1 -1
- package/dist/pop-float.js +13 -7
- package/dist/segmented.d.ts +0 -1
- package/dist/segmented.js +38 -20
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/llms.txt +3 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
import { Dialect, ExampleContext, TransformFn } from './types';
|
|
2
2
|
export declare const AsyncFunction: Function;
|
|
3
|
+
/**
|
|
4
|
+
* Thrown by `rewriteImports` when an example has a static import the environment
|
|
5
|
+
* can't satisfy (a non-context package with no import-resolver). This is NOT a code
|
|
6
|
+
* defect — the code is fine, the doc environment just doesn't provide the dependency
|
|
7
|
+
* — so the build check treats it as a *warning* (the block is display-only) rather
|
|
8
|
+
* than a fatal error, and can tell it apart from a real syntax/transpile error.
|
|
9
|
+
*/
|
|
10
|
+
export declare class UnsupportedImportError extends Error {
|
|
11
|
+
/** The offending `import …` statement. */
|
|
12
|
+
readonly statement: string;
|
|
13
|
+
constructor(message: string,
|
|
14
|
+
/** The offending `import …` statement. */
|
|
15
|
+
statement: string);
|
|
16
|
+
}
|
|
3
17
|
/**
|
|
4
18
|
* Sanitize a context module key into a JS identifier used as the binding name
|
|
5
19
|
* in rewritten imports and as the AsyncFunction parameter. Must be applied
|
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
export const AsyncFunction = (async () => {
|
|
2
2
|
/* placeholder */
|
|
3
3
|
}).constructor;
|
|
4
|
+
/**
|
|
5
|
+
* Thrown by `rewriteImports` when an example has a static import the environment
|
|
6
|
+
* can't satisfy (a non-context package with no import-resolver). This is NOT a code
|
|
7
|
+
* defect — the code is fine, the doc environment just doesn't provide the dependency
|
|
8
|
+
* — so the build check treats it as a *warning* (the block is display-only) rather
|
|
9
|
+
* than a fatal error, and can tell it apart from a real syntax/transpile error.
|
|
10
|
+
*/
|
|
11
|
+
export class UnsupportedImportError extends Error {
|
|
12
|
+
statement;
|
|
13
|
+
constructor(message,
|
|
14
|
+
/** The offending `import …` statement. */
|
|
15
|
+
statement) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.statement = statement;
|
|
18
|
+
this.name = 'UnsupportedImportError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
4
21
|
/**
|
|
5
22
|
* Sanitize a context module key into a JS identifier used as the binding name
|
|
6
23
|
* in rewritten imports and as the AsyncFunction parameter. Must be applied
|
|
@@ -90,12 +107,13 @@ importPrefix = resolverPrefix()) {
|
|
|
90
107
|
// Anything still a static import is unsupported — fail loudly with the line.
|
|
91
108
|
const leftover = result.match(/^\s*import\s+['"{*\w][^\n]*/m);
|
|
92
109
|
if (leftover) {
|
|
93
|
-
|
|
110
|
+
const statement = leftover[0].trim();
|
|
111
|
+
throw new UnsupportedImportError(`live example: unsupported import \`${statement}\` — imports ` +
|
|
94
112
|
`from the example context (${contextKeys.join(', ')}) are supported in ` +
|
|
95
113
|
`{ named }, * as ns, or default form` +
|
|
96
114
|
(importPrefix
|
|
97
115
|
? `, and other packages resolve via the import-resolver.`
|
|
98
|
-
: ` (enable importResolver to import other packages).`));
|
|
116
|
+
: ` (enable importResolver to import other packages).`), statement);
|
|
99
117
|
}
|
|
100
118
|
return result;
|
|
101
119
|
}
|
|
@@ -27,7 +27,7 @@ export declare class LiveExample extends Component<ExampleParts> {
|
|
|
27
27
|
boxShadow: string;
|
|
28
28
|
overflow: string;
|
|
29
29
|
};
|
|
30
|
-
':host.-locally-edited [part="exampleWidgets"]': {
|
|
30
|
+
':host.-locally-edited > [part="example"] > [part="exampleWidgets"]': {
|
|
31
31
|
outline: string;
|
|
32
32
|
outlineOffset: string;
|
|
33
33
|
borderRadius: string;
|
|
@@ -53,7 +53,7 @@ export declare class LiveExample extends Component<ExampleParts> {
|
|
|
53
53
|
':host.-vertical .layout-indicator': {
|
|
54
54
|
transform: string;
|
|
55
55
|
};
|
|
56
|
-
':host.-maximize .hide-if-maximized, :host:not(.-maximize) .show-if-maximized': {
|
|
56
|
+
':host.-maximize > [part="example"] > [part="exampleWidgets"] .hide-if-maximized, :host:not(.-maximize) > [part="example"] > [part="exampleWidgets"] .show-if-maximized': {
|
|
57
57
|
display: string;
|
|
58
58
|
};
|
|
59
59
|
':host [part="example"]': {
|
|
@@ -89,17 +89,23 @@ export declare class LiveExample extends Component<ExampleParts> {
|
|
|
89
89
|
};
|
|
90
90
|
':host [part="exampleWidgets"]': {
|
|
91
91
|
position: string;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
'--widget-color': string;
|
|
95
|
-
borderRadius: string;
|
|
96
|
-
width: string;
|
|
97
|
-
height: string;
|
|
98
|
-
lineHeight: string;
|
|
92
|
+
top: string;
|
|
93
|
+
right: string;
|
|
99
94
|
zIndex: string;
|
|
95
|
+
color: string;
|
|
96
|
+
'--widget-color': string;
|
|
97
|
+
'--tosi-pocket-handle-color': string;
|
|
98
|
+
};
|
|
99
|
+
':host [part="exampleWidgets"] button': {
|
|
100
|
+
'--text-color': string;
|
|
100
101
|
};
|
|
101
|
-
':host [part="exampleWidgets"]
|
|
102
|
-
|
|
102
|
+
':host [part="exampleWidgets"] .tests-toggle input': {
|
|
103
|
+
display: string;
|
|
104
|
+
};
|
|
105
|
+
':host [part="exampleWidgets"] .tests-toggle': {
|
|
106
|
+
opacity: string;
|
|
107
|
+
filter: string;
|
|
108
|
+
transition: string;
|
|
103
109
|
};
|
|
104
110
|
':host .code-editors': {
|
|
105
111
|
overflow: string;
|
|
@@ -134,33 +140,6 @@ export declare class LiveExample extends Component<ExampleParts> {
|
|
|
134
140
|
':host .sizer': {
|
|
135
141
|
cursor: string;
|
|
136
142
|
};
|
|
137
|
-
':host [part="testIndicator"]': {
|
|
138
|
-
position: string;
|
|
139
|
-
top: string;
|
|
140
|
-
right: string;
|
|
141
|
-
width: string;
|
|
142
|
-
height: string;
|
|
143
|
-
borderRadius: string;
|
|
144
|
-
background: string;
|
|
145
|
-
zIndex: string;
|
|
146
|
-
display: string;
|
|
147
|
-
};
|
|
148
|
-
':host.-has-tests [part="testIndicator"]': {
|
|
149
|
-
display: string;
|
|
150
|
-
opacity: string;
|
|
151
|
-
};
|
|
152
|
-
':host.-test-running [part="testIndicator"]': {
|
|
153
|
-
background: string;
|
|
154
|
-
animation: string;
|
|
155
|
-
};
|
|
156
|
-
':host.-test-passed [part="testIndicator"]': {
|
|
157
|
-
background: string;
|
|
158
|
-
animation: string;
|
|
159
|
-
};
|
|
160
|
-
':host.-test-failed [part="testIndicator"]': {
|
|
161
|
-
background: string;
|
|
162
|
-
animation: string;
|
|
163
|
-
};
|
|
164
143
|
'@keyframes test-pulse': {
|
|
165
144
|
'0%, 100%': {
|
|
166
145
|
opacity: string;
|
|
@@ -169,21 +148,14 @@ export declare class LiveExample extends Component<ExampleParts> {
|
|
|
169
148
|
opacity: string;
|
|
170
149
|
};
|
|
171
150
|
};
|
|
172
|
-
'
|
|
173
|
-
'
|
|
174
|
-
|
|
175
|
-
};
|
|
176
|
-
'50%': {
|
|
177
|
-
opacity: string;
|
|
178
|
-
};
|
|
179
|
-
'100%': {
|
|
180
|
-
opacity: string;
|
|
181
|
-
};
|
|
151
|
+
':host.-test-running > [part="example"] > [part="exampleWidgets"]': {
|
|
152
|
+
'--widget-color': string;
|
|
153
|
+
animation: string;
|
|
182
154
|
};
|
|
183
|
-
':host.-test-passed [part="exampleWidgets"]': {
|
|
155
|
+
':host.-test-passed > [part="example"] > [part="exampleWidgets"]': {
|
|
184
156
|
'--widget-color': string;
|
|
185
157
|
};
|
|
186
|
-
':host.-test-failed [part="exampleWidgets"]': {
|
|
158
|
+
':host.-test-failed > [part="example"] > [part="exampleWidgets"]': {
|
|
187
159
|
'--widget-color': string;
|
|
188
160
|
};
|
|
189
161
|
':host [part="testResults"]': {
|
|
@@ -291,7 +263,8 @@ export declare class LiveExample extends Component<ExampleParts> {
|
|
|
291
263
|
get isMaximized(): boolean;
|
|
292
264
|
flipLayout: () => void;
|
|
293
265
|
saveToSource: () => Promise<void>;
|
|
294
|
-
|
|
266
|
+
handleTestsToggle: (event: Event) => void;
|
|
267
|
+
updateExampleWidgets: () => void;
|
|
295
268
|
handleShortcuts: (event: KeyboardEvent) => void;
|
|
296
269
|
content: () => any[];
|
|
297
270
|
private buildEditorPanel;
|
|
@@ -413,6 +413,7 @@ import { Component, elements, tosi } from 'tosijs';
|
|
|
413
413
|
import { codeEditor, CodeEditor } from '../code-editor';
|
|
414
414
|
import { tosiTabs } from '../tab-selector';
|
|
415
415
|
import { icons } from '../icons';
|
|
416
|
+
import { tosiPocketBar } from '../pocket-bar';
|
|
416
417
|
import { postNotification } from '../notifications';
|
|
417
418
|
import { popMenu } from '../menu';
|
|
418
419
|
import { loadTransform, loadTjsTestApi, rewriteImports, contextVarName, AsyncFunction, } from './code-transform';
|
|
@@ -423,7 +424,7 @@ import { rewriteExampleBlocks, groupExamples, findFencedBlocks, } from './save-t
|
|
|
423
424
|
import { exampleEditKey, saveExampleEdit, loadExampleEdit, clearExampleEdit, hasExampleEdit, } from './example-store';
|
|
424
425
|
import { liveExampleStyleSpec } from './styles';
|
|
425
426
|
import { runTests } from './test-harness';
|
|
426
|
-
const { div, tosiSlot, style, button, pre, span } = elements;
|
|
427
|
+
const { div, tosiSlot, style, button, pre, span, label, input } = elements;
|
|
427
428
|
// Test mode: controlled by localStorage, defaults to enabled on localhost
|
|
428
429
|
const TESTS_ENABLED_KEY = 'tosijs-ui-tests-enabled';
|
|
429
430
|
const isLocalhost = typeof window !== 'undefined' &&
|
|
@@ -495,7 +496,11 @@ export class LiveExample extends Component {
|
|
|
495
496
|
return m;
|
|
496
497
|
if (m)
|
|
497
498
|
console.warn(`<tosi-example>: unknown mode "${m}" — running inline`);
|
|
498
|
-
|
|
499
|
+
// STRICT boolean: only an explicit `true` means iframe. `iframe` is a
|
|
500
|
+
// presence-only boolean attribute aliasing mode; a loose `this.iframe ?` would
|
|
501
|
+
// treat a stray non-boolean value ('', 'false', an attribute string) as truthy
|
|
502
|
+
// and silently force EVERY example into an iframe. Default is inline.
|
|
503
|
+
return this.iframe === true ? 'iframe' : 'inline';
|
|
499
504
|
}
|
|
500
505
|
prefix = 'lx';
|
|
501
506
|
storageKey = STORAGE_KEY;
|
|
@@ -874,43 +879,21 @@ export class LiveExample extends Component {
|
|
|
874
879
|
window.alert('Save failed.');
|
|
875
880
|
}
|
|
876
881
|
};
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
},
|
|
893
|
-
null,
|
|
894
|
-
{
|
|
895
|
-
icon: this.isMaximized ? 'minimize' : 'maximize',
|
|
896
|
-
caption: this.isMaximized ? 'restore preview' : 'maximize preview',
|
|
897
|
-
action: this.toggleMaximize,
|
|
898
|
-
},
|
|
899
|
-
null,
|
|
900
|
-
{
|
|
901
|
-
icon: testsOn ? 'check' : '',
|
|
902
|
-
caption: 'Run tests',
|
|
903
|
-
action: () => {
|
|
904
|
-
if (testsOn) {
|
|
905
|
-
disableTests();
|
|
906
|
-
}
|
|
907
|
-
else {
|
|
908
|
-
enableTests();
|
|
909
|
-
}
|
|
910
|
-
},
|
|
911
|
-
},
|
|
912
|
-
],
|
|
913
|
-
});
|
|
882
|
+
handleTestsToggle = (event) => {
|
|
883
|
+
if (event.target.checked)
|
|
884
|
+
enableTests();
|
|
885
|
+
else
|
|
886
|
+
disableTests();
|
|
887
|
+
};
|
|
888
|
+
// The maximize icon + title toggle purely in CSS (.hide-if-maximized /
|
|
889
|
+
// .show-if-maximized); only the run-tests checkbox needs a JS sync so its state
|
|
890
|
+
// is correct on first paint and after the global flag changes. (Its greyed /
|
|
891
|
+
// monochrome look keys off the --tests-enabled CSS var, which is global.)
|
|
892
|
+
updateExampleWidgets = () => {
|
|
893
|
+
if (!this.hydrated)
|
|
894
|
+
return;
|
|
895
|
+
if (this.parts.testsCheckbox)
|
|
896
|
+
this.parts.testsCheckbox.checked = testManager.enabled.value;
|
|
914
897
|
};
|
|
915
898
|
handleShortcuts = (event) => {
|
|
916
899
|
if (event.metaKey || event.ctrlKey) {
|
|
@@ -938,11 +921,14 @@ export class LiveExample extends Component {
|
|
|
938
921
|
}
|
|
939
922
|
};
|
|
940
923
|
content = () => [
|
|
941
|
-
div({ part: 'example' }, style({ part: 'style' }),
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
}, icons.code())
|
|
924
|
+
div({ part: 'example' }, style({ part: 'style' }), pre({ part: 'testResults', hidden: true }),
|
|
925
|
+
// The example toolbar: a pocket bar whose collapsed `<>` handle carries the
|
|
926
|
+
// test-status colour (via --widget-color). Pinned top-right, growing left, so
|
|
927
|
+
// it never covers the editor in side-by-side mode.
|
|
928
|
+
tosiPocketBar({ part: 'exampleWidgets', icon: 'code', direction: 'w' }, button({ title: 'view/edit code', onClick: this.showCode }, icons.edit2()), button({ title: 'view/edit code in a new window', onClick: this.openEditorWindow }, icons.edit()), button({ title: 'toggle preview size', onClick: this.toggleMaximize },
|
|
929
|
+
// Both icons render; the existing .hide-if-maximized / .show-if-maximized
|
|
930
|
+
// CSS shows the right one for the current state — no JS icon swap.
|
|
931
|
+
icons.maximize({ class: 'hide-if-maximized' }), icons.minimize({ class: 'show-if-maximized' })), label({ class: 'tests-toggle', title: 'run tests' }, input({ type: 'checkbox', part: 'testsCheckbox', onChange: this.handleTestsToggle }), icons.check()))),
|
|
946
932
|
// Empty until first showCode. buildEditorPanel() fills it lazily so a reader
|
|
947
933
|
// who never opens a panel never constructs a <tosi-code> (and never pulls the
|
|
948
934
|
// CodeMirror chunk). See ensureEditors().
|
|
@@ -1046,6 +1032,10 @@ export class LiveExample extends Component {
|
|
|
1046
1032
|
// does not fire reliably during page unload.
|
|
1047
1033
|
this.beforeUnloadHandler = () => this.remoteSync?.sendClose();
|
|
1048
1034
|
addEventListener('beforeunload', this.beforeUnloadHandler);
|
|
1035
|
+
// Reflect maximize state + tests-enabled on the pocket-bar controls. The
|
|
1036
|
+
// run-tests icon greys globally via the --tests-enabled CSS var (maintained on
|
|
1037
|
+
// <body>), so no per-instance observer is needed to keep examples in sync.
|
|
1038
|
+
this.updateExampleWidgets();
|
|
1049
1039
|
}
|
|
1050
1040
|
disconnectedCallback() {
|
|
1051
1041
|
super.disconnectedCallback();
|
|
@@ -1505,12 +1495,13 @@ export class LiveExample extends Component {
|
|
|
1505
1495
|
}
|
|
1506
1496
|
};
|
|
1507
1497
|
displayTestResults() {
|
|
1508
|
-
const { testResults: resultsEl,
|
|
1498
|
+
const { testResults: resultsEl, exampleWidgets } = this.parts;
|
|
1509
1499
|
const results = this.testResults;
|
|
1510
1500
|
if (!results || results.tests.length === 0) {
|
|
1511
1501
|
resultsEl.hidden = true;
|
|
1512
1502
|
this.classList.remove('-test-passed', '-test-failed');
|
|
1513
|
-
|
|
1503
|
+
if (exampleWidgets)
|
|
1504
|
+
exampleWidgets.title = 'no tests';
|
|
1514
1505
|
return;
|
|
1515
1506
|
}
|
|
1516
1507
|
resultsEl.innerHTML = '';
|
|
@@ -1526,11 +1517,12 @@ export class LiveExample extends Component {
|
|
|
1526
1517
|
}
|
|
1527
1518
|
this.classList.toggle('-test-passed', results.failed === 0);
|
|
1528
1519
|
this.classList.toggle('-test-failed', results.failed > 0);
|
|
1529
|
-
//
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1520
|
+
// The `<>` handle colour shows pass/fail; its tooltip carries the detail.
|
|
1521
|
+
if (exampleWidgets)
|
|
1522
|
+
exampleWidgets.title =
|
|
1523
|
+
results.failed === 0
|
|
1524
|
+
? `${results.passed} tests passed`
|
|
1525
|
+
: `${results.failed}/${results.tests.length} tests failed`;
|
|
1534
1526
|
// Update visibility based on tab and failure status
|
|
1535
1527
|
this.updateTestResultsVisibility();
|
|
1536
1528
|
// Dispatch event for doc-browser to track results
|
|
@@ -1584,6 +1576,7 @@ export class LiveExample extends Component {
|
|
|
1584
1576
|
}
|
|
1585
1577
|
render() {
|
|
1586
1578
|
super.render();
|
|
1579
|
+
this.updateExampleWidgets();
|
|
1587
1580
|
if (this.remoteId !== '') {
|
|
1588
1581
|
const data = localStorage.getItem(this.storageKey);
|
|
1589
1582
|
if (data !== null) {
|
|
@@ -14,7 +14,7 @@ export declare const liveExampleStyleSpec: {
|
|
|
14
14
|
boxShadow: string;
|
|
15
15
|
overflow: string;
|
|
16
16
|
};
|
|
17
|
-
':host.-locally-edited [part="exampleWidgets"]': {
|
|
17
|
+
':host.-locally-edited > [part="example"] > [part="exampleWidgets"]': {
|
|
18
18
|
outline: string;
|
|
19
19
|
outlineOffset: string;
|
|
20
20
|
borderRadius: string;
|
|
@@ -40,7 +40,7 @@ export declare const liveExampleStyleSpec: {
|
|
|
40
40
|
':host.-vertical .layout-indicator': {
|
|
41
41
|
transform: string;
|
|
42
42
|
};
|
|
43
|
-
':host.-maximize .hide-if-maximized, :host:not(.-maximize) .show-if-maximized': {
|
|
43
|
+
':host.-maximize > [part="example"] > [part="exampleWidgets"] .hide-if-maximized, :host:not(.-maximize) > [part="example"] > [part="exampleWidgets"] .show-if-maximized': {
|
|
44
44
|
display: string;
|
|
45
45
|
};
|
|
46
46
|
':host [part="example"]': {
|
|
@@ -76,17 +76,23 @@ export declare const liveExampleStyleSpec: {
|
|
|
76
76
|
};
|
|
77
77
|
':host [part="exampleWidgets"]': {
|
|
78
78
|
position: string;
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
'--widget-color': string;
|
|
82
|
-
borderRadius: string;
|
|
83
|
-
width: string;
|
|
84
|
-
height: string;
|
|
85
|
-
lineHeight: string;
|
|
79
|
+
top: string;
|
|
80
|
+
right: string;
|
|
86
81
|
zIndex: string;
|
|
82
|
+
color: string;
|
|
83
|
+
'--widget-color': string;
|
|
84
|
+
'--tosi-pocket-handle-color': string;
|
|
85
|
+
};
|
|
86
|
+
':host [part="exampleWidgets"] button': {
|
|
87
|
+
'--text-color': string;
|
|
87
88
|
};
|
|
88
|
-
':host [part="exampleWidgets"]
|
|
89
|
-
|
|
89
|
+
':host [part="exampleWidgets"] .tests-toggle input': {
|
|
90
|
+
display: string;
|
|
91
|
+
};
|
|
92
|
+
':host [part="exampleWidgets"] .tests-toggle': {
|
|
93
|
+
opacity: string;
|
|
94
|
+
filter: string;
|
|
95
|
+
transition: string;
|
|
90
96
|
};
|
|
91
97
|
':host .code-editors': {
|
|
92
98
|
overflow: string;
|
|
@@ -121,33 +127,6 @@ export declare const liveExampleStyleSpec: {
|
|
|
121
127
|
':host .sizer': {
|
|
122
128
|
cursor: string;
|
|
123
129
|
};
|
|
124
|
-
':host [part="testIndicator"]': {
|
|
125
|
-
position: string;
|
|
126
|
-
top: string;
|
|
127
|
-
right: string;
|
|
128
|
-
width: string;
|
|
129
|
-
height: string;
|
|
130
|
-
borderRadius: string;
|
|
131
|
-
background: string;
|
|
132
|
-
zIndex: string;
|
|
133
|
-
display: string;
|
|
134
|
-
};
|
|
135
|
-
':host.-has-tests [part="testIndicator"]': {
|
|
136
|
-
display: string;
|
|
137
|
-
opacity: string;
|
|
138
|
-
};
|
|
139
|
-
':host.-test-running [part="testIndicator"]': {
|
|
140
|
-
background: string;
|
|
141
|
-
animation: string;
|
|
142
|
-
};
|
|
143
|
-
':host.-test-passed [part="testIndicator"]': {
|
|
144
|
-
background: string;
|
|
145
|
-
animation: string;
|
|
146
|
-
};
|
|
147
|
-
':host.-test-failed [part="testIndicator"]': {
|
|
148
|
-
background: string;
|
|
149
|
-
animation: string;
|
|
150
|
-
};
|
|
151
130
|
'@keyframes test-pulse': {
|
|
152
131
|
'0%, 100%': {
|
|
153
132
|
opacity: string;
|
|
@@ -156,21 +135,14 @@ export declare const liveExampleStyleSpec: {
|
|
|
156
135
|
opacity: string;
|
|
157
136
|
};
|
|
158
137
|
};
|
|
159
|
-
'
|
|
160
|
-
'
|
|
161
|
-
|
|
162
|
-
};
|
|
163
|
-
'50%': {
|
|
164
|
-
opacity: string;
|
|
165
|
-
};
|
|
166
|
-
'100%': {
|
|
167
|
-
opacity: string;
|
|
168
|
-
};
|
|
138
|
+
':host.-test-running > [part="example"] > [part="exampleWidgets"]': {
|
|
139
|
+
'--widget-color': string;
|
|
140
|
+
animation: string;
|
|
169
141
|
};
|
|
170
|
-
':host.-test-passed [part="exampleWidgets"]': {
|
|
142
|
+
':host.-test-passed > [part="example"] > [part="exampleWidgets"]': {
|
|
171
143
|
'--widget-color': string;
|
|
172
144
|
};
|
|
173
|
-
':host.-test-failed [part="exampleWidgets"]': {
|
|
145
|
+
':host.-test-failed > [part="example"] > [part="exampleWidgets"]': {
|
|
174
146
|
'--widget-color': string;
|
|
175
147
|
};
|
|
176
148
|
':host [part="testResults"]': {
|
|
@@ -19,10 +19,14 @@ export const liveExampleStyleSpec = {
|
|
|
19
19
|
boxShadow: 'inset 0 0 0 2px #8883',
|
|
20
20
|
overflow: 'hidden',
|
|
21
21
|
},
|
|
22
|
-
// Local-edit indicator: an accent outline on the always-visible `<>`
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
|
|
22
|
+
// Local-edit indicator: an accent outline on the always-visible `<>` handle when
|
|
23
|
+
// this example differs from its doc source. NB every `:host.STATE [part=…]` rule
|
|
24
|
+
// in this file uses `> [part="example"] > [part="exampleWidgets"]`, not a bare
|
|
25
|
+
// descendant: a light-DOM `:host` is a global `tosi-example …` selector, so a
|
|
26
|
+
// descendant combinator would leak a CONTAINER example's state class onto a
|
|
27
|
+
// NESTED example's widget (the self-hosting demo). The child chain pins each rule
|
|
28
|
+
// to the example's own direct toolbar.
|
|
29
|
+
':host.-locally-edited > [part="example"] > [part="exampleWidgets"]': {
|
|
26
30
|
outline: '2px solid var(--brand-color, #da1167)',
|
|
27
31
|
outlineOffset: '1px',
|
|
28
32
|
borderRadius: '4px',
|
|
@@ -48,7 +52,9 @@ export const liveExampleStyleSpec = {
|
|
|
48
52
|
':host.-vertical .layout-indicator': {
|
|
49
53
|
transform: 'rotateZ(180deg)',
|
|
50
54
|
},
|
|
51
|
-
|
|
55
|
+
// Maximize/restore icon toggle — scoped to the example's own toolbar so a
|
|
56
|
+
// container example's -maximize doesn't hide a nested example's maximize icon.
|
|
57
|
+
':host.-maximize > [part="example"] > [part="exampleWidgets"] .hide-if-maximized, :host:not(.-maximize) > [part="example"] > [part="exampleWidgets"] .show-if-maximized': {
|
|
52
58
|
display: 'none',
|
|
53
59
|
},
|
|
54
60
|
':host [part="example"]': {
|
|
@@ -86,23 +92,42 @@ export const liveExampleStyleSpec = {
|
|
|
86
92
|
height: '100%',
|
|
87
93
|
position: 'relative',
|
|
88
94
|
},
|
|
95
|
+
// The example toolbar (a <tosi-pocket-bar>), pinned top-right so it never covers
|
|
96
|
+
// the editor in side-by-side mode. Only the collapsed `<>` handle carries the
|
|
97
|
+
// test-status colour — the action buttons stay neutral — via the pocket bar's
|
|
98
|
+
// --tosi-pocket-handle-color (the -test-* rules below drive --widget-color).
|
|
89
99
|
':host [part="exampleWidgets"]': {
|
|
90
100
|
position: 'absolute',
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'--widget-color': 'var(--brand-color)',
|
|
94
|
-
borderRadius: '5px',
|
|
95
|
-
width: '44px',
|
|
96
|
-
height: '44px',
|
|
97
|
-
lineHeight: '44px',
|
|
101
|
+
top: '5px',
|
|
102
|
+
right: '5px',
|
|
98
103
|
zIndex: '100',
|
|
104
|
+
// Action controls are neutral (text colour); only the handle carries status.
|
|
105
|
+
color: 'var(--text-color)',
|
|
106
|
+
'--widget-color': 'var(--brand-color)',
|
|
107
|
+
'--tosi-pocket-handle-color': 'var(--widget-color)',
|
|
108
|
+
},
|
|
109
|
+
// The doc site brand-colours bare <button>s by overriding --text-color ON the
|
|
110
|
+
// button (a link affordance). Revert it here so the toolbar's icon buttons are
|
|
111
|
+
// neutral, matching the check <label> (which the button rule never touched).
|
|
112
|
+
':host [part="exampleWidgets"] button': {
|
|
113
|
+
'--text-color': 'inherit',
|
|
114
|
+
},
|
|
115
|
+
// Run-tests toggle: the native checkbox is hidden; its icon is full-colour when
|
|
116
|
+
// tests are on and greyed + monochrome when off. --tests-enabled (0|1, set on
|
|
117
|
+
// <body>) is global, so every example's toggle stays in sync with no JS.
|
|
118
|
+
':host [part="exampleWidgets"] .tests-toggle input': {
|
|
119
|
+
display: 'none',
|
|
99
120
|
},
|
|
100
|
-
':host [part="exampleWidgets"]
|
|
101
|
-
|
|
121
|
+
':host [part="exampleWidgets"] .tests-toggle': {
|
|
122
|
+
opacity: 'calc(0.4 + 0.6 * var(--tests-enabled, 0))',
|
|
123
|
+
filter: 'grayscale(calc(1 - var(--tests-enabled, 0)))',
|
|
124
|
+
transition: 'opacity 0.2s, filter 0.2s',
|
|
102
125
|
},
|
|
103
126
|
':host .code-editors': {
|
|
104
127
|
overflow: 'hidden',
|
|
105
|
-
|
|
128
|
+
// Match the editor surface (neutral off-white; off-black in dark mode) instead
|
|
129
|
+
// of a hardcoded white that wouldn't adapt.
|
|
130
|
+
background: 'var(--code-bg, #fdfdfd)',
|
|
106
131
|
position: 'relative',
|
|
107
132
|
top: '0',
|
|
108
133
|
right: '0',
|
|
@@ -133,47 +158,21 @@ export const liveExampleStyleSpec = {
|
|
|
133
158
|
':host .sizer': {
|
|
134
159
|
cursor: 'nwse-resize',
|
|
135
160
|
},
|
|
136
|
-
// Test status indicator (--tests-enabled CSS var pierces shadow DOM)
|
|
137
|
-
':host [part="testIndicator"]': {
|
|
138
|
-
position: 'absolute',
|
|
139
|
-
top: '8px',
|
|
140
|
-
right: '8px',
|
|
141
|
-
width: '12px',
|
|
142
|
-
height: '12px',
|
|
143
|
-
borderRadius: '50%',
|
|
144
|
-
background: '#888',
|
|
145
|
-
zIndex: '100',
|
|
146
|
-
display: 'none',
|
|
147
|
-
},
|
|
148
|
-
':host.-has-tests [part="testIndicator"]': {
|
|
149
|
-
display: 'block',
|
|
150
|
-
opacity: 'var(--tests-enabled, 1)',
|
|
151
|
-
},
|
|
152
|
-
':host.-test-running [part="testIndicator"]': {
|
|
153
|
-
background: '#fa0',
|
|
154
|
-
animation: 'test-pulse 0.5s ease-in-out infinite',
|
|
155
|
-
},
|
|
156
|
-
':host.-test-passed [part="testIndicator"]': {
|
|
157
|
-
background: '#0a0',
|
|
158
|
-
animation: 'test-fade 2s ease-out forwards',
|
|
159
|
-
},
|
|
160
|
-
':host.-test-failed [part="testIndicator"]': {
|
|
161
|
-
background: '#c00',
|
|
162
|
-
animation: 'test-pulse 1s ease-in-out infinite',
|
|
163
|
-
},
|
|
164
161
|
'@keyframes test-pulse': {
|
|
165
162
|
'0%, 100%': { opacity: '1' },
|
|
166
163
|
'50%': { opacity: '0.4' },
|
|
167
164
|
},
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
165
|
+
// Test status colours the `<>` handle (via --widget-color → the pocket bar's
|
|
166
|
+
// --tosi-pocket-handle-color). The handle is translucent at rest, so the colour
|
|
167
|
+
// reads as a subtle tint until you hover.
|
|
168
|
+
':host.-test-running > [part="example"] > [part="exampleWidgets"]': {
|
|
169
|
+
'--widget-color': '#fa0',
|
|
170
|
+
animation: 'test-pulse 0.75s ease-in-out infinite',
|
|
172
171
|
},
|
|
173
|
-
':host.-test-passed [part="exampleWidgets"]': {
|
|
172
|
+
':host.-test-passed > [part="example"] > [part="exampleWidgets"]': {
|
|
174
173
|
'--widget-color': '#0a0',
|
|
175
174
|
},
|
|
176
|
-
':host.-test-failed [part="exampleWidgets"]': {
|
|
175
|
+
':host.-test-failed > [part="example"] > [part="exampleWidgets"]': {
|
|
177
176
|
'--widget-color': '#f00',
|
|
178
177
|
},
|
|
179
178
|
':host [part="testResults"]': {
|
|
@@ -9,14 +9,14 @@ export interface ExampleParts extends PartsMap {
|
|
|
9
9
|
codeEditors: HTMLElement;
|
|
10
10
|
undo: HTMLButtonElement;
|
|
11
11
|
redo: HTMLButtonElement;
|
|
12
|
-
exampleWidgets:
|
|
12
|
+
exampleWidgets: HTMLElement;
|
|
13
|
+
testsCheckbox: HTMLInputElement;
|
|
13
14
|
editors: TosiTabs;
|
|
14
15
|
code: HTMLElement;
|
|
15
16
|
sources: HTMLElement;
|
|
16
17
|
style: HTMLStyleElement;
|
|
17
18
|
example: HTMLElement;
|
|
18
19
|
testResults: HTMLElement;
|
|
19
|
-
testIndicator: HTMLElement;
|
|
20
20
|
js: CodeEditor;
|
|
21
21
|
html: CodeEditor;
|
|
22
22
|
css: CodeEditor;
|