@lapikit/repl 0.0.0-insiders.0c4e011
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/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/Button.svelte +41 -0
- package/dist/Button.svelte.d.ts +9 -0
- package/dist/Files.svelte +64 -0
- package/dist/Files.svelte.d.ts +4 -0
- package/dist/Repl.svelte +283 -0
- package/dist/Repl.svelte.d.ts +4 -0
- package/dist/Toolbar.svelte +127 -0
- package/dist/Toolbar.svelte.d.ts +4 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/languages/css.svg +6 -0
- package/dist/languages/html.svg +6 -0
- package/dist/languages/javascript.svg +6 -0
- package/dist/languages/shell.svg +5 -0
- package/dist/languages/svelte.svg +2 -0
- package/dist/languages/typescript.svg +12 -0
- package/dist/pkg/bun.svg +1 -0
- package/dist/pkg/npm.svg +10 -0
- package/dist/pkg/yarn.svg +2 -0
- package/dist/shiki.d.ts +2 -0
- package/dist/shiki.js +14 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +69 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Nycolaide <https://github.com/Nycolaide>.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# @Lapikit/repl
|
|
2
|
+
|
|
3
|
+
@lapikit/repl is a Svelte component for Lapikit. It's a add-on package for Lapikit library.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -D @lapikit/repl
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
// svelte.config.js
|
|
13
|
+
|
|
14
|
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
|
15
|
+
|
|
16
|
+
const config = {
|
|
17
|
+
preprocess: [vitePreprocess(), lapikitPreprocess({ plugins: ['repl'] })],
|
|
18
|
+
|
|
19
|
+
...
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default config;
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
```svelte
|
|
28
|
+
<kit:repl content="console.log('hello')" />
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```svelte
|
|
32
|
+
<script lang="ts">
|
|
33
|
+
import sampleCounter from './samples/counter.svelte?raw';
|
|
34
|
+
import Counter from './samples/counter.svelte';
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<kit:repl presentation content={sampleCounter}>
|
|
38
|
+
<Counter />
|
|
39
|
+
</kit:repl>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```svelte
|
|
43
|
+
<script lang="ts">
|
|
44
|
+
import sampleJson from './samples/json.json?raw';
|
|
45
|
+
import sampleCounter from './samples/counter.svelte?raw';
|
|
46
|
+
import sampleCss from './samples/css.css?raw';
|
|
47
|
+
import Counter from './samples/counter.svelte';
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<kit:repl
|
|
51
|
+
presentation
|
|
52
|
+
content={{
|
|
53
|
+
'Counter.svelte': { code: sampleCounter, lang: 'svelte' },
|
|
54
|
+
'file.json': { code: sampleJson, lang: 'json' },
|
|
55
|
+
'Styles.css': { code: sampleCss, lang: 'css' }
|
|
56
|
+
}}
|
|
57
|
+
>
|
|
58
|
+
<Counter />
|
|
59
|
+
</kit:repl>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```svelte
|
|
63
|
+
<script lang="ts">
|
|
64
|
+
import sampleJson from './samples/json.json?raw';
|
|
65
|
+
import sampleCounter from './samples/counter.svelte?raw';
|
|
66
|
+
import sampleCss from './samples/css.css?raw';
|
|
67
|
+
import Counter from './samples/counter.svelte';
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<kit:repl
|
|
71
|
+
content={{
|
|
72
|
+
'Counter.svelte': { code: sampleCounter, lang: 'svelte' },
|
|
73
|
+
'file.json': { code: sampleJson, lang: 'json' },
|
|
74
|
+
'Styles.css': { code: sampleCss, lang: 'css' }
|
|
75
|
+
}}
|
|
76
|
+
>
|
|
77
|
+
<Counter />
|
|
78
|
+
</kit:repl>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Props
|
|
82
|
+
|
|
83
|
+
| Prop | Type | Default | Description |
|
|
84
|
+
| ------------ | --------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
85
|
+
| content | string \| Record<string, { code: string; lang?: string }> | '' | The code content to be displayed in the REPL. It can be a single string or an object representing multiple files. |
|
|
86
|
+
| presentation | boolean | false | If true, the REPL will be in presentation mode, showing only the output without the code editor. |
|
|
87
|
+
| tiltle | string | '' | The title displayed on the REPL toolbar. |
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
|
|
4
|
+
let { children, type = 'button', disabled = false, ...rest }: PropsTypeButton = $props();
|
|
5
|
+
|
|
6
|
+
type PropsTypeButton = {
|
|
7
|
+
children?: Snippet;
|
|
8
|
+
type?: 'button' | 'submit' | 'reset';
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
[rest: string]: unknown;
|
|
11
|
+
};
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<button {type} {disabled} {...rest}>
|
|
15
|
+
{@render children?.()}
|
|
16
|
+
</button>
|
|
17
|
+
|
|
18
|
+
<style>
|
|
19
|
+
button {
|
|
20
|
+
background: none;
|
|
21
|
+
border: none;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
display: flex;
|
|
24
|
+
align-self: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
font-size: var(--kit-repl-shiki-size);
|
|
27
|
+
border-radius: var(--kit-repl-radius);
|
|
28
|
+
transition: background-color 0.2s ease;
|
|
29
|
+
padding: 8px;
|
|
30
|
+
color: var(--kit-repl-secondary);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
button:hover {
|
|
34
|
+
color: var(--kit-repl-primary);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
button :global(svg) {
|
|
38
|
+
height: 20px;
|
|
39
|
+
width: 20px;
|
|
40
|
+
}
|
|
41
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
declare const Button: import("svelte").Component<{
|
|
3
|
+
[rest: string]: unknown;
|
|
4
|
+
children?: Snippet;
|
|
5
|
+
type?: "button" | "submit" | "reset";
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
}, {}, "">;
|
|
8
|
+
type Button = ReturnType<typeof Button>;
|
|
9
|
+
export default Button;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { FilesProps } from './types.js';
|
|
3
|
+
import { dictionaryIcons, dictionaryPkgIcons } from './utils.js';
|
|
4
|
+
|
|
5
|
+
let { files, activeIndex = $bindable(), modeState, viewState }: FilesProps = $props();
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
{#if modeState !== 'playground' && viewState === 'code' && files && files.length > 1}
|
|
9
|
+
<div role="tablist" aria-label="Files">
|
|
10
|
+
{#each files as file, index (index)}
|
|
11
|
+
<button
|
|
12
|
+
type="button"
|
|
13
|
+
role="tab"
|
|
14
|
+
aria-selected={activeIndex === index}
|
|
15
|
+
aria-label="Select {file.name}"
|
|
16
|
+
class:active={activeIndex === index}
|
|
17
|
+
onclick={() => (activeIndex = index)}
|
|
18
|
+
>
|
|
19
|
+
{#if dictionaryPkgIcons[file.name.toLowerCase()]}
|
|
20
|
+
<img src={dictionaryPkgIcons[file.name.toLowerCase()]} alt="{file.name} icon" />
|
|
21
|
+
{:else if file.lang && dictionaryIcons[file.lang]}
|
|
22
|
+
<img src={dictionaryIcons[file.lang]} alt="{file.lang} icon" />
|
|
23
|
+
{/if}
|
|
24
|
+
<span>{file.name}</span>
|
|
25
|
+
</button>
|
|
26
|
+
{/each}
|
|
27
|
+
</div>
|
|
28
|
+
{/if}
|
|
29
|
+
|
|
30
|
+
<style>
|
|
31
|
+
div {
|
|
32
|
+
display: flex;
|
|
33
|
+
overflow-x: auto;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
button {
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
padding: 9px 4px;
|
|
40
|
+
gap: var(--kit-repl-spacing);
|
|
41
|
+
font-size: var(--kit-repl-shiki-size);
|
|
42
|
+
transition: all 0.2s ease;
|
|
43
|
+
border: 0;
|
|
44
|
+
white-space: nowrap;
|
|
45
|
+
background-color: transparent;
|
|
46
|
+
border-bottom: 2px solid transparent;
|
|
47
|
+
cursor: pointer;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
button img {
|
|
51
|
+
width: 16px;
|
|
52
|
+
height: 16px;
|
|
53
|
+
border: 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
button:hover {
|
|
57
|
+
border-color: var(--kit-color-accent, var(--kit-repl-secondary));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
button.active {
|
|
61
|
+
border-color: var(--kit-color-accent, var(--kit-repl-primary));
|
|
62
|
+
color: var(--kit-color-accent, var(--kit-repl-primary));
|
|
63
|
+
}
|
|
64
|
+
</style>
|
package/dist/Repl.svelte
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { copyToClipboard } from './utils.js';
|
|
3
|
+
import { getHighlighterSingleton } from './shiki.js';
|
|
4
|
+
import { createTheme } from 'lapikit/actions';
|
|
5
|
+
import type { FileItem, ReplProps } from './types.js';
|
|
6
|
+
|
|
7
|
+
// components
|
|
8
|
+
import Toolbar from './Toolbar.svelte';
|
|
9
|
+
import Files from './Files.svelte';
|
|
10
|
+
|
|
11
|
+
let { title, content, children, presentation }: ReplProps = $props();
|
|
12
|
+
|
|
13
|
+
// refs
|
|
14
|
+
let ref: null | HTMLElement = $state(null);
|
|
15
|
+
|
|
16
|
+
// states
|
|
17
|
+
let language = $state('sh');
|
|
18
|
+
|
|
19
|
+
let modeState: 'code' | 'playground' | 'mixed' = $state('code');
|
|
20
|
+
let copyState = $state(false);
|
|
21
|
+
let viewState: 'code' | 'preview' = $state('code');
|
|
22
|
+
|
|
23
|
+
// theme: mirrors the ambient lapikit theme (light/dark/system) until the
|
|
24
|
+
// toolbar toggle is used. The override only applies to the rendered
|
|
25
|
+
// children/preview area — the toolbar and shiki code always follow
|
|
26
|
+
// the ambient theme.
|
|
27
|
+
const theme = createTheme();
|
|
28
|
+
let themeOverridden = $state(false);
|
|
29
|
+
let themeState = $derived<'light' | 'dark'>(theme.active === 'dark' ? 'dark' : 'light');
|
|
30
|
+
|
|
31
|
+
function toggleTheme() {
|
|
32
|
+
themeOverridden = true;
|
|
33
|
+
theme.set(themeState === 'dark' ? 'light' : 'dark');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let codeHTML = $state<string | null>(null);
|
|
37
|
+
let activeFileIndex = $state(0);
|
|
38
|
+
|
|
39
|
+
let files = $derived.by<FileItem[]>(() => {
|
|
40
|
+
if (typeof content === 'object' && content !== null && 'code' in content) {
|
|
41
|
+
return [
|
|
42
|
+
{
|
|
43
|
+
name: title || 'code',
|
|
44
|
+
content: content.code,
|
|
45
|
+
lang: content.lang || 'sh'
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (typeof content === 'object' && content !== null && !Array.isArray(content)) {
|
|
51
|
+
return Object.entries(content).map(([name, fileContent]) => ({
|
|
52
|
+
name,
|
|
53
|
+
content:
|
|
54
|
+
typeof fileContent === 'string'
|
|
55
|
+
? fileContent
|
|
56
|
+
: (fileContent as Record<string, unknown>).code || '',
|
|
57
|
+
lang:
|
|
58
|
+
typeof fileContent === 'object'
|
|
59
|
+
? ((fileContent as Record<string, unknown>).lang as string)
|
|
60
|
+
: 'sh'
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (Array.isArray(content)) {
|
|
65
|
+
return content.map((item) => ({
|
|
66
|
+
name: item.name,
|
|
67
|
+
content: item.content || item.code || '',
|
|
68
|
+
lang: item.lang || 'sh'
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return [{ name: 'code', content: content || '', lang: 'sh' }];
|
|
73
|
+
});
|
|
74
|
+
let activeFile = $derived(files[activeFileIndex]);
|
|
75
|
+
|
|
76
|
+
$effect.pre(() => {
|
|
77
|
+
if (children && content && !presentation) {
|
|
78
|
+
modeState = 'mixed';
|
|
79
|
+
viewState = 'preview';
|
|
80
|
+
} else if (presentation) {
|
|
81
|
+
modeState = 'mixed';
|
|
82
|
+
viewState = 'code';
|
|
83
|
+
} else if (children && !content) {
|
|
84
|
+
modeState = 'playground';
|
|
85
|
+
viewState = 'preview';
|
|
86
|
+
} else {
|
|
87
|
+
modeState = 'code';
|
|
88
|
+
viewState = 'code';
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
$effect(() => {
|
|
93
|
+
if (copyState) {
|
|
94
|
+
if (ref?.textContent) {
|
|
95
|
+
copyToClipboard(ref?.textContent);
|
|
96
|
+
copyState = true;
|
|
97
|
+
|
|
98
|
+
setTimeout(() => {
|
|
99
|
+
copyState = false;
|
|
100
|
+
}, 1500);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
$effect(() => {
|
|
106
|
+
const file = activeFile;
|
|
107
|
+
|
|
108
|
+
if (file?.content) {
|
|
109
|
+
codeHTML = null;
|
|
110
|
+
language = file.lang || 'sh';
|
|
111
|
+
|
|
112
|
+
(async () => {
|
|
113
|
+
const highlighter = await getHighlighterSingleton();
|
|
114
|
+
const html = highlighter.codeToHtml(file.content, {
|
|
115
|
+
themes: { light: 'github-light', dark: 'github-dark' },
|
|
116
|
+
defaultColor: false,
|
|
117
|
+
lang: file.lang || language
|
|
118
|
+
});
|
|
119
|
+
codeHTML = html;
|
|
120
|
+
})();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
</script>
|
|
124
|
+
|
|
125
|
+
<div class="kit-repl">
|
|
126
|
+
{#if presentation}
|
|
127
|
+
<div class="kit-repl-content" class:kit-repl-content--playground={presentation}>
|
|
128
|
+
<div class="wrapper-playground" use:theme.action={{ overridden: themeOverridden }}>
|
|
129
|
+
{@render children?.()}
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
{/if}
|
|
133
|
+
|
|
134
|
+
<div class="kit-repl-container">
|
|
135
|
+
<Toolbar
|
|
136
|
+
{title}
|
|
137
|
+
{language}
|
|
138
|
+
{presentation}
|
|
139
|
+
{files}
|
|
140
|
+
{themeState}
|
|
141
|
+
onToggleTheme={toggleTheme}
|
|
142
|
+
bind:copyState
|
|
143
|
+
bind:viewState
|
|
144
|
+
bind:modeState
|
|
145
|
+
>
|
|
146
|
+
<Files {files} bind:activeIndex={activeFileIndex} {modeState} {viewState} />
|
|
147
|
+
</Toolbar>
|
|
148
|
+
|
|
149
|
+
{#if modeState !== 'code'}
|
|
150
|
+
<hr />
|
|
151
|
+
{/if}
|
|
152
|
+
|
|
153
|
+
{#if title}
|
|
154
|
+
<Files {files} bind:activeIndex={activeFileIndex} {modeState} {viewState} />
|
|
155
|
+
{/if}
|
|
156
|
+
|
|
157
|
+
<div
|
|
158
|
+
class="kit-repl-content"
|
|
159
|
+
class:kit-repl-content--code={viewState === 'code' && !presentation}
|
|
160
|
+
>
|
|
161
|
+
{#if viewState === 'code'}
|
|
162
|
+
<div class="kit-repl-wrapper-highlight" bind:this={ref}>
|
|
163
|
+
{#if codeHTML !== null}
|
|
164
|
+
<!-- eslint-disable-next-line svelte/no-at-html-tags -->
|
|
165
|
+
{@html codeHTML}
|
|
166
|
+
{:else}
|
|
167
|
+
<pre class="kit-repl-raw"><code>{activeFile?.content ?? ''}</code></pre>
|
|
168
|
+
{/if}
|
|
169
|
+
</div>
|
|
170
|
+
{:else}
|
|
171
|
+
<div class="kit-repl-wrapper-playground" use:theme.action={{ overridden: themeOverridden }}>
|
|
172
|
+
{@render children?.()}
|
|
173
|
+
</div>
|
|
174
|
+
{/if}
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<style>
|
|
180
|
+
.kit-repl {
|
|
181
|
+
/* ui */
|
|
182
|
+
--kit-repl-spacing: var(--kit-space-default, 4px);
|
|
183
|
+
--kit-repl-radius: var(--kit-shape-md, 10px);
|
|
184
|
+
|
|
185
|
+
/* shiki override */
|
|
186
|
+
--kit-repl-shiki-size: var(--kit-font-xs, 13px);
|
|
187
|
+
--kit-repl-shiki-tab-size: 2;
|
|
188
|
+
|
|
189
|
+
/* colors */
|
|
190
|
+
--kit-repl-background: var(--kit-color-surface-1, #f9f9f9);
|
|
191
|
+
--kit-repl-border-color: var(--kit-color-fill, #ebebeb);
|
|
192
|
+
--kit-repl-primary: var(--kit-color-text, #0d0d34);
|
|
193
|
+
--kit-repl-secondary: var(--kit-color-text-muted, #8f8f8f);
|
|
194
|
+
}
|
|
195
|
+
.kit-repl-container {
|
|
196
|
+
background-color: var(--kit-repl-background);
|
|
197
|
+
border-radius: var(--kit-repl-radius);
|
|
198
|
+
border: 1px solid var(--kit-repl-border-color);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.kit-repl-container :global(pre) {
|
|
202
|
+
background-color: var(--kit-repl-background) !important;
|
|
203
|
+
border: 0 !important;
|
|
204
|
+
border-radius: 0 !important;
|
|
205
|
+
border-bottom-left-radius: var(--kit-repl-radius) !important;
|
|
206
|
+
border-bottom-right-radius: var(--kit-repl-radius) !important;
|
|
207
|
+
padding: 10px 0 !important;
|
|
208
|
+
margin-bottom: 0 !important;
|
|
209
|
+
margin-top: 0 !important;
|
|
210
|
+
font-size: var(--kit-repl-shiki-size) !important;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.kit-repl-content {
|
|
214
|
+
display: flow-root;
|
|
215
|
+
padding-left: calc(var(--kit-repl-spacing) * 2);
|
|
216
|
+
/* margin-top: calc(var(--kit-repl-spacing) * 0); */
|
|
217
|
+
/* padding-right: calc(10 * var(--kit-repl-spacing));
|
|
218
|
+
padding-left: calc(5 * var(--kit-repl-spacing));
|
|
219
|
+
padding-bottom: calc(4 * var(--kit-repl-spacing));
|
|
220
|
+
padding-top: calc(3 * var(--kit-repl-spacing)); */
|
|
221
|
+
position: relative;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.kit-repl-content--code {
|
|
225
|
+
padding-top: 0;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.kit-repl-content--playground {
|
|
229
|
+
padding-top: calc(4 * var(--kit-repl-spacing));
|
|
230
|
+
padding-bottom: calc(10 * var(--kit-repl-spacing));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
hr {
|
|
234
|
+
max-width: calc(100% - 2.5rem);
|
|
235
|
+
margin-inline-start: calc(2.5rem / 2);
|
|
236
|
+
display: block;
|
|
237
|
+
border: thin solid var(--kit-repl-border-color);
|
|
238
|
+
margin-top: 0;
|
|
239
|
+
margin-bottom: 0;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.kit-repl-raw {
|
|
243
|
+
font-size: var(--kit-repl-shiki-size);
|
|
244
|
+
-moz-tab-size: var(--kit-repl-shiki-tab-size);
|
|
245
|
+
tab-size: var(--kit-repl-shiki-tab-size);
|
|
246
|
+
white-space: pre-wrap;
|
|
247
|
+
word-break: break-word;
|
|
248
|
+
margin: 0;
|
|
249
|
+
padding: 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
div.kit-repl-container .kit-repl-wrapper-highlight :global(pre code) {
|
|
253
|
+
font-size: var(--kit-repl-shiki-size);
|
|
254
|
+
-moz-tab-size: var(--kit-repl-shiki-tab-size);
|
|
255
|
+
tab-size: var(--kit-repl-shiki-tab-size);
|
|
256
|
+
white-space: pre-wrap;
|
|
257
|
+
word-break: break-word;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* shiki dual-theme: follows the ambient lapikit theme (light/dark/system) */
|
|
261
|
+
.kit-repl-wrapper-highlight :global(.shiki),
|
|
262
|
+
.kit-repl-wrapper-highlight :global(.shiki span) {
|
|
263
|
+
color: var(--shiki-light);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
:global([data-kit-theme='dark']) .kit-repl-wrapper-highlight :global(.shiki),
|
|
267
|
+
:global([data-kit-theme='dark']) .kit-repl-wrapper-highlight :global(.shiki span) {
|
|
268
|
+
color: var(--shiki-dark);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
@media (prefers-color-scheme: dark) {
|
|
272
|
+
:global([data-kit-theme='system']) .kit-repl-wrapper-highlight :global(.shiki),
|
|
273
|
+
:global([data-kit-theme='system']) .kit-repl-wrapper-highlight :global(.shiki span) {
|
|
274
|
+
color: var(--shiki-dark);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
div.kit-repl-container .kit-repl-wrapper-playground {
|
|
279
|
+
background-color: var(--kit-repl-background);
|
|
280
|
+
border-radius: var(--kit-repl-radius);
|
|
281
|
+
padding: calc(4 * var(--kit-repl-spacing));
|
|
282
|
+
}
|
|
283
|
+
</style>
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ToolbarProps } from './types.js';
|
|
3
|
+
import Button from './Button.svelte';
|
|
4
|
+
import { dictionary } from './utils.js';
|
|
5
|
+
import { Copy, Check, Code, Codesandbox, Moon, Sun } from '@lucide/svelte';
|
|
6
|
+
|
|
7
|
+
let {
|
|
8
|
+
children,
|
|
9
|
+
title,
|
|
10
|
+
language,
|
|
11
|
+
presentation,
|
|
12
|
+
files,
|
|
13
|
+
copyState = $bindable(),
|
|
14
|
+
viewState = $bindable(),
|
|
15
|
+
themeState,
|
|
16
|
+
onToggleTheme,
|
|
17
|
+
modeState = $bindable()
|
|
18
|
+
}: ToolbarProps = $props();
|
|
19
|
+
|
|
20
|
+
let languageKey = $derived(
|
|
21
|
+
Object.entries(dictionary).find(([, values]) => values.includes(language))?.[0] || language
|
|
22
|
+
);
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div class="kit-repl--toolbar">
|
|
26
|
+
{#if title}
|
|
27
|
+
<div class="kit-repl--toolbar-title" class:kit-repl--toolbar-title--title={title}>
|
|
28
|
+
<span>{title}</span>
|
|
29
|
+
</div>
|
|
30
|
+
{:else if files && files.length > 1}
|
|
31
|
+
<div class="kit-repl--toolbar-files">
|
|
32
|
+
{@render children?.()}
|
|
33
|
+
</div>
|
|
34
|
+
{:else if language}
|
|
35
|
+
<div class="kit-repl--toolbar-title" class:kit-repl--toolbar-title--language={language}>
|
|
36
|
+
<span>{languageKey}</span>
|
|
37
|
+
</div>
|
|
38
|
+
{/if}
|
|
39
|
+
|
|
40
|
+
<div class="kit-repl--toolbar-actions">
|
|
41
|
+
{#if (modeState !== 'code' && viewState === 'preview') || presentation}
|
|
42
|
+
<Button
|
|
43
|
+
aria-label={themeState === 'light' ? 'Switch to dark theme' : 'Switch to light theme'}
|
|
44
|
+
aria-pressed={themeState === 'dark'}
|
|
45
|
+
onclick={() => onToggleTheme?.()}
|
|
46
|
+
>
|
|
47
|
+
{#if themeState === 'light'}
|
|
48
|
+
<Moon />
|
|
49
|
+
{:else}
|
|
50
|
+
<Sun />
|
|
51
|
+
{/if}
|
|
52
|
+
</Button>
|
|
53
|
+
{/if}
|
|
54
|
+
|
|
55
|
+
{#if modeState === 'mixed' && !presentation}
|
|
56
|
+
<Button
|
|
57
|
+
aria-label={viewState === 'code' ? 'Show preview' : 'Show code'}
|
|
58
|
+
aria-pressed={viewState === 'preview'}
|
|
59
|
+
onclick={() => (viewState = viewState === 'code' ? 'preview' : 'code')}
|
|
60
|
+
>
|
|
61
|
+
{#if viewState === 'code'}
|
|
62
|
+
<Code />
|
|
63
|
+
{:else}
|
|
64
|
+
<Codesandbox />
|
|
65
|
+
{/if}
|
|
66
|
+
</Button>
|
|
67
|
+
{/if}
|
|
68
|
+
|
|
69
|
+
{#if modeState !== 'playground'}
|
|
70
|
+
<Button
|
|
71
|
+
aria-label={copyState ? 'Code copied' : 'Copy code'}
|
|
72
|
+
onclick={() => (copyState = true)}
|
|
73
|
+
>
|
|
74
|
+
{#if copyState}
|
|
75
|
+
<Check />
|
|
76
|
+
{:else}
|
|
77
|
+
<Copy />
|
|
78
|
+
{/if}
|
|
79
|
+
</Button>
|
|
80
|
+
{/if}
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
|
|
84
|
+
<style>
|
|
85
|
+
.kit-repl--toolbar {
|
|
86
|
+
display: grid;
|
|
87
|
+
align-items: center;
|
|
88
|
+
grid-template-columns: 1fr auto;
|
|
89
|
+
padding-left: calc(var(--kit-repl-spacing) * 2);
|
|
90
|
+
background-color: color-mix(in oklab, var(--kit-repl-background) 95%, black);
|
|
91
|
+
border-top-left-radius: var(--kit-repl-radius);
|
|
92
|
+
border-top-right-radius: var(--kit-repl-radius);
|
|
93
|
+
gap: var(--kit-repl-spacing);
|
|
94
|
+
min-height: 36px;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.kit-repl--toolbar .kit-repl--toolbar-title {
|
|
98
|
+
display: flex;
|
|
99
|
+
align-items: center;
|
|
100
|
+
gap: calc(var(--kit-repl-spacing) * 2);
|
|
101
|
+
max-width: 80%;
|
|
102
|
+
min-width: 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.kit-repl--toolbar-title--language {
|
|
106
|
+
font-size: var(--kit-repl-shiki-size);
|
|
107
|
+
line-height: 1;
|
|
108
|
+
color: var(--kit-color-text-muted);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.kit-repl--toolbar-title--title {
|
|
112
|
+
font-size: var(--kit-repl-shiki-size);
|
|
113
|
+
line-height: 1;
|
|
114
|
+
color: var(--kit-color-text-muted);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.kit-repl--toolbar .kit-repl--toolbar-actions {
|
|
118
|
+
display: flex;
|
|
119
|
+
align-items: center;
|
|
120
|
+
gap: calc(var(--kit-repl-spacing) * 2);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.kit-repl--toolbar .kit-repl--toolbar-files {
|
|
124
|
+
width: 100%;
|
|
125
|
+
overflow-x: auto;
|
|
126
|
+
}
|
|
127
|
+
</style>
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as KitRepl } from './Repl.svelte';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M6 28L4 3H28L26 28L16 31L6 28Z" fill="#1172B8"/>
|
|
4
|
+
<path d="M26 5H16V29.5L24 27L26 5Z" fill="#33AADD"/>
|
|
5
|
+
<path d="M19.5 17.5H9.5L9 14L17 11.5H9L8.5 8.5H24L23.5 12L17 14.5H23L22 24L16 26L10 24L9.5 19H12.5L13 21.5L16 22.5L19 21.5L19.5 17.5Z" fill="white"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<path d="M6 28L4 3H28L26 28L16 31L6 28Z" fill="#E44D26"/>
|
|
4
|
+
<path d="M26 5H16V29.5L24 27L26 5Z" fill="#F16529"/>
|
|
5
|
+
<path d="M9.5 17.5L8.5 8H24L23.5 11H11.5L12 14.5H23L22 24L16 26L10 24L9.5 19H12.5L13 21.5L16 22.5L19 21.5L19.5 17.5H9.5Z" fill="white"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<rect x="2" y="2" width="28" height="28" fill="#FFCA28"/>
|
|
4
|
+
<path d="M19 25.2879L21.0615 23.9237C21.2231 24.4313 22.2462 25.6368 23.5385 25.6368C24.8308 25.6368 25.4308 24.931 25.4308 24.463C25.4308 23.1878 24.1112 22.7382 23.4774 22.5223C23.374 22.4871 23.289 22.4581 23.2308 22.4328C23.2009 22.4198 23.1558 22.4025 23.0979 22.3804C22.393 22.1111 19.7923 21.1175 19.7923 18.2373C19.7923 15.065 22.8538 14.7002 23.5462 14.7002C23.9991 14.7002 26.1769 14.7557 27.2615 16.7939L25.2615 18.1898C24.8231 17.3015 24.0946 17.0081 23.6462 17.0081C22.5385 17.0081 22.3077 17.8201 22.3077 18.1898C22.3077 19.227 23.5112 19.6919 24.5273 20.0844C24.7932 20.1871 25.0462 20.2848 25.2615 20.3866C26.3692 20.91 28 21.7666 28 24.463C28 25.8136 26.8672 28.0002 24.0154 28.0002C20.1846 28.0002 19.1692 25.7003 19 25.2879Z" fill="#3E3E3E"/>
|
|
5
|
+
<path d="M9 25.5587L11.1487 24.1953C11.317 24.7026 11.9713 25.638 12.9205 25.638C13.8698 25.638 14.3557 24.663 14.3557 24.1953V15.0002H16.9982V24.1953C17.041 25.4636 16.3376 28.0002 13.2332 28.0002C10.379 28.0002 9.19242 26.3039 9 25.5587Z" fill="#3E3E3E"/>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<rect width="24" height="24" fill="none"/>
|
|
4
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.29291 14.2929C6.90238 14.6834 6.90238 15.3166 7.29291 15.7071C7.68343 16.0976 8.31659 16.0976 8.70712 15.7071L11.2071 13.2071C11.8738 12.5404 11.8738 11.4596 11.2071 10.7929L8.70712 8.29289C8.3166 7.90237 7.68343 7.90237 7.29291 8.29289C6.90238 8.68342 6.90238 9.31658 7.29291 9.70711L9.5858 12L7.29291 14.2929ZM13 14C12.4477 14 12 14.4477 12 15C12 15.5523 12.4477 16 13 16H16C16.5523 16 17 15.5523 17 15C17 14.4477 16.5523 14 16 14H13ZM22 7.93418C22 7.95604 22 7.97799 22 8.00001L22 16.0658C22.0001 16.9523 22.0001 17.7161 21.9179 18.3278C21.8297 18.9833 21.631 19.6117 21.1213 20.1213C20.6117 20.631 19.9833 20.8297 19.3278 20.9179C18.7161 21.0001 17.9523 21.0001 17.0658 21L6.9342 21C6.0477 21.0001 5.28388 21.0001 4.67222 20.9179C4.0167 20.8297 3.38835 20.631 2.87869 20.1213C2.36902 19.6117 2.17028 18.9833 2.08215 18.3278C1.99991 17.7161 1.99995 16.9523 2 16.0658L2 7.9342C1.99995 7.0477 1.99991 6.28388 2.08215 5.67221C2.17028 5.0167 2.36902 4.38835 2.87869 3.87868C3.38835 3.36902 4.0167 3.17028 4.67222 3.08215C5.28388 2.99991 6.04769 2.99995 6.93418 3L17 3.00001C17.022 3.00001 17.044 3 17.0658 3C17.9523 2.99995 18.7161 2.99991 19.3278 3.08215C19.9833 3.17028 20.6117 3.36902 21.1213 3.87869C21.631 4.38835 21.8297 5.0167 21.9179 5.67221C22.0001 6.28387 22.0001 7.04769 22 7.93418Z" fill="#323232"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>file_type_svelte</title><path d="M26.47,5.7A8.973,8.973,0,0,0,14.677,3.246L7.96,7.4a7.461,7.461,0,0,0-3.481,5.009,7.686,7.686,0,0,0,.8,5.058,7.358,7.358,0,0,0-1.151,2.8,7.789,7.789,0,0,0,1.4,6.028,8.977,8.977,0,0,0,11.794,2.458L24.04,24.6a7.468,7.468,0,0,0,3.481-5.009,7.673,7.673,0,0,0-.8-5.062,7.348,7.348,0,0,0,1.152-2.8A7.785,7.785,0,0,0,26.47,5.7" style="fill:#ff3e00"/><path d="M14.022,26.64A5.413,5.413,0,0,1,8.3,24.581a4.678,4.678,0,0,1-.848-3.625,4.307,4.307,0,0,1,.159-.61l.127-.375.344.238a8.76,8.76,0,0,0,2.628,1.274l.245.073-.025.237a1.441,1.441,0,0,0,.271.968,1.63,1.63,0,0,0,1.743.636,1.512,1.512,0,0,0,.411-.175l6.7-4.154a1.366,1.366,0,0,0,.633-.909,1.407,1.407,0,0,0-.244-1.091,1.634,1.634,0,0,0-1.726-.622,1.509,1.509,0,0,0-.413.176l-2.572,1.584a4.934,4.934,0,0,1-1.364.582,5.415,5.415,0,0,1-5.727-2.06A4.678,4.678,0,0,1,7.811,13.1,4.507,4.507,0,0,1,9.9,10.09l6.708-4.154a4.932,4.932,0,0,1,1.364-.581A5.413,5.413,0,0,1,23.7,7.414a4.679,4.679,0,0,1,.848,3.625,4.272,4.272,0,0,1-.159.61l-.127.375-.344-.237a8.713,8.713,0,0,0-2.628-1.274l-.245-.074.025-.237a1.438,1.438,0,0,0-.272-.968,1.629,1.629,0,0,0-1.725-.622,1.484,1.484,0,0,0-.411.176l-6.722,4.14a1.353,1.353,0,0,0-.631.908,1.394,1.394,0,0,0,.244,1.092,1.634,1.634,0,0,0,1.726.621,1.538,1.538,0,0,0,.413-.175l2.562-1.585a4.9,4.9,0,0,1,1.364-.581,5.417,5.417,0,0,1,5.728,2.059,4.681,4.681,0,0,1,.843,3.625A4.5,4.5,0,0,1,22.1,21.905l-6.707,4.154a4.9,4.9,0,0,1-1.364.581" style="fill:#fff"/></svg>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
|
4
|
+
<g>
|
|
5
|
+
<polygon fill="#007ACC" transform="translate(128.000000, 128.000000) scale(1, -1) translate(-128.000000, -128.000000) " points="0 128 0 0 128 0 256 0 256 128 256 256 128 256 0 256">
|
|
6
|
+
|
|
7
|
+
<path d="M146.658132,223.436863 L146.739401,212.953054 L130.079084,212.953054 L113.418767,212.953054 L113.418767,165.613371 L113.418767,118.273689 L101.63464,118.273689 L89.8505126,118.273689 L89.8505126,165.613371 L89.8505126,212.953054 L73.1901951,212.953054 L56.5298776,212.953054 L56.5298776,223.233689 C56.5298776,228.922577 56.6517824,233.676863 56.8143221,233.798768 C56.9362269,233.961308 77.2130522,234.042577 101.797179,234.001943 L146.536227,233.880038 L146.658132,223.436863 Z" fill="#FFFFFF" transform="translate(101.634640, 176.142993) rotate(-180.000000) translate(-101.634640, -176.142993) ">
|
|
8
|
+
|
|
9
|
+
<path d="M206.566631,234.272145 C213.068219,232.646748 218.025679,229.761668 222.57679,225.048018 C224.933616,222.528653 228.428219,217.936907 228.712663,216.839764 C228.793933,216.514684 217.659965,209.037859 210.914568,204.852462 C210.670758,204.689922 209.69552,205.74643 208.598377,207.371827 C205.306949,212.166748 201.852981,214.239129 196.570441,214.604843 C188.809171,215.133097 183.811076,211.069605 183.851711,204.283573 C183.851711,202.292462 184.136155,201.114049 184.948854,199.488653 C186.65552,195.953414 189.825044,193.840399 199.7806,189.533097 C218.106949,181.649922 225.949489,176.448653 230.825679,169.053097 C236.270758,160.804208 237.489806,147.638494 233.792028,137.845478 C229.728536,127.199129 219.651076,119.966113 205.469489,117.568653 C201.080917,116.796589 190.678377,116.918494 185.964727,117.771827 C175.684092,119.600399 165.931711,124.679764 159.917743,131.343891 C157.560917,133.944526 152.969171,140.730557 153.253616,141.218176 C153.37552,141.380716 154.432028,142.030875 155.610441,142.721668 C156.748219,143.371827 161.05552,145.850557 165.119012,148.207383 L172.473933,152.474049 L174.01806,150.198494 C176.171711,146.907065 180.885362,142.396589 183.729806,140.893097 C191.897425,136.585795 203.112663,137.195319 208.639012,142.15278 C210.995838,144.30643 211.971076,146.541351 211.971076,149.83278 C211.971076,152.799129 211.605362,154.099446 210.061235,156.334367 C208.070123,159.178811 204.006631,161.576272 192.466314,166.574367 C179.259965,172.263256 173.571076,175.798494 168.369806,181.406113 C165.362822,184.656907 162.518377,189.858176 161.339965,194.206113 C160.364727,197.822621 160.120917,206.884208 160.892981,210.541351 C163.61552,223.300716 173.245996,232.199764 187.143139,234.841034 C191.653616,235.694367 202.137425,235.369287 206.566631,234.272145 Z" fill="#FFFFFF" transform="translate(194.578507, 176.190240) scale(1, -1) translate(-194.578507, -176.190240) ">
|
|
10
|
+
|
|
11
|
+
</g>
|
|
12
|
+
</svg>
|
package/dist/pkg/bun.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128"><path d="M113.744 41.999a18.558 18.558 0 0 0-.8-.772c-.272-.246-.528-.524-.8-.771s-.528-.525-.8-.771c-.272-.247-.528-.525-.8-.772s-.528-.524-.8-.771-.528-.525-.8-.772-.528-.524-.8-.771c7.936 7.52 12.483 17.752 12.656 28.481 0 25.565-26.912 46.363-60 46.363-18.528 0-35.104-6.526-46.128-16.756l.8.772.8.771.8.772.8.771.8.772.8.771.8.771c11.008 10.662 27.952 17.527 46.928 17.527 33.088 0 60-20.797 60-46.285 0-10.893-4.864-21.215-13.456-29.33z"/><path fill="#fbf0df" d="M116.8 65.08c0 23.467-25.072 42.49-56 42.49s-56-19.023-56-42.49c0-14.55 9.6-27.401 24.352-35.023C43.904 22.435 53.088 14.628 60.8 14.628S75.104 21 92.448 30.058C107.2 37.677 116.8 50.53 116.8 65.08Z"/><path fill="#f6dece" d="M116.8 65.08a32.314 32.314 0 0 0-1.28-8.918c-4.368 51.377-69.36 53.846-94.912 38.48 11.486 8.584 25.66 13.144 40.192 12.928 30.88 0 56-19.054 56-42.49z"/><path fill="#fffefc" d="M39.248 27.234c7.152-4.135 16.656-11.896 26-11.911a15.372 15.372 0 0 0-4.448-.695c-3.872 0-8 1.93-13.2 4.83-1.808 1.018-3.68 2.144-5.664 3.317-3.728 2.222-8 4.736-12.8 7.251C13.904 37.972 4.8 51.071 4.8 65.08v1.836c9.696-33.033 27.312-35.547 34.448-39.682z"/><path fill="#ccbea7" d="M56.192 18.532A24.553 24.553 0 0 1 53.867 29.1a25.407 25.407 0 0 1-6.683 8.671c-.448.386-.096 1.127.48.91 5.392-2.02 12.672-8.068 9.6-20.272-.128-.695-1.072-.51-1.072.123zm3.632 0a24.474 24.474 0 0 1 3.646 10.12c.445 3.587.08 7.224-1.07 10.662-.192.54.496 1.003.88.556 3.504-4.32 6.56-12.899-2.592-22.156-.464-.4-1.184.216-.864.756zm4.416-.262a25.702 25.702 0 0 1 7.521 7.925A24.71 24.71 0 0 1 75.2 36.414c-.016.13.02.26.101.365a.543.543 0 0 0 .718.117.509.509 0 0 0 .221-.313c1.472-5.384.64-14.564-11.472-19.332-.64-.246-1.056.587-.528.957zM34.704 34.315a27.418 27.418 0 0 0 9.91-5.222 26.262 26.262 0 0 0 6.842-8.663c.288-.556 1.2-.34 1.056.277-2.768 12.343-12.032 14.92-17.792 14.58-.608.016-.592-.802-.016-.972z"/><path d="M60.8 111.443c-33.088 0-60-20.798-60-46.363 0-15.429 9.888-29.823 26.448-38.448 4.8-2.469 8.912-4.953 12.576-7.128 2.016-1.203 3.92-2.33 5.76-3.379C51.2 12.916 56 10.771 60.8 10.771c4.8 0 8.992 1.852 14.24 4.845 1.6.88 3.2 1.836 4.912 2.885 3.984 2.376 8.48 5.06 14.4 8.131 16.56 8.625 26.448 23.004 26.448 38.448 0 25.565-26.912 46.363-60 46.363zm0-96.814c-3.872 0-8 1.928-13.2 4.829-1.808 1.018-3.68 2.144-5.664 3.317-3.728 2.222-8 4.736-12.8 7.251C13.904 37.972 4.8 51.071 4.8 65.08c0 23.436 25.12 42.506 56 42.506s56-19.07 56-42.506c0-14.01-9.104-27.108-24.352-35.023-6.048-3.086-10.768-5.986-14.592-8.27-1.744-1.033-3.344-1.99-4.8-2.838-4.848-2.778-8.384-4.32-12.256-4.32z"/><path fill="#b71422" d="M72.08 76.343c-.719 2.839-2.355 5.383-4.672 7.267a11.07 11.07 0 0 1-6.4 2.9 11.13 11.13 0 0 1-6.608-2.9c-2.293-1.892-3.906-4.436-4.608-7.267a1.073 1.073 0 0 1 .05-.5 1.11 1.11 0 0 1 .272-.428 1.19 1.19 0 0 1 .958-.322h19.744a1.185 1.185 0 0 1 .947.33 1.073 1.073 0 0 1 .317.92z"/><path fill="#ff6164" d="M54.4 83.733a11.24 11.24 0 0 0 6.592 2.932 11.239 11.239 0 0 0 6.576-2.932 16.652 16.652 0 0 0 1.6-1.65 10.904 10.904 0 0 0-3.538-2.564 11.26 11.26 0 0 0-4.302-1 10.121 10.121 0 0 0-4.549 1.192 9.71 9.71 0 0 0-3.451 3.097c.368.323.688.632 1.072.925z"/><path d="M54.656 82.514a8.518 8.518 0 0 1 2.97-2.347 8.836 8.836 0 0 1 3.734-.862 9.78 9.78 0 0 1 6.4 2.608c.368-.386.72-.787 1.056-1.188-2.035-1.87-4.726-2.933-7.536-2.978a10.487 10.487 0 0 0-4.335.975 10.125 10.125 0 0 0-3.489 2.666c.378.396.779.772 1.2 1.126z"/><path d="M60.944 87.436a12.078 12.078 0 0 1-7.12-3.086c-2.477-2.02-4.22-4.75-4.976-7.791-.054-.27-.045-.55.027-.817a1.83 1.83 0 0 1 .389-.726 2.25 2.25 0 0 1 .81-.595 2.32 2.32 0 0 1 .998-.192h19.744c.343-.007.683.06.996.196a2.3 2.3 0 0 1 .812.591c.182.212.313.46.382.728.07.267.076.545.018.815-.756 3.042-2.5 5.771-4.976 7.791a12.078 12.078 0 0 1-7.104 3.086zm-9.872-11.417c-.256 0-.32.108-.336.139.676 2.638 2.206 4.999 4.368 6.742a10.122 10.122 0 0 0 5.84 2.7 10.207 10.207 0 0 0 5.84-2.67c2.155-1.745 3.679-4.106 4.352-6.741a.333.333 0 0 0-.14-.113.348.348 0 0 0-.18-.026z"/><path fill="#febbd0" d="M85.152 77.3c5.17 0 9.36-2.377 9.36-5.308s-4.19-5.307-9.36-5.307c-5.17 0-9.36 2.376-9.36 5.307 0 2.931 4.19 5.307 9.36 5.307zm-48.432 0c5.17 0 9.36-2.377 9.36-5.308s-4.19-5.307-9.36-5.307c-5.17 0-9.36 2.376-9.36 5.307 0 2.931 4.19 5.307 9.36 5.307z"/><path d="M41.12 69.863a9.052 9.052 0 0 0 4.902-1.425 8.578 8.578 0 0 0 3.254-3.812 8.22 8.22 0 0 0 .508-4.913 8.41 8.41 0 0 0-2.408-4.357 8.92 8.92 0 0 0-4.514-2.33 9.12 9.12 0 0 0-5.096.48 8.755 8.755 0 0 0-3.96 3.131 8.287 8.287 0 0 0-1.486 4.725c0 2.252.927 4.412 2.577 6.005 1.65 1.594 3.888 2.492 6.223 2.496zm39.632 0a9.054 9.054 0 0 0 4.915-1.403 8.582 8.582 0 0 0 3.275-3.802 8.22 8.22 0 0 0 .528-4.917 8.408 8.408 0 0 0-2.398-4.368 8.92 8.92 0 0 0-4.512-2.344 9.12 9.12 0 0 0-5.103.473 8.756 8.756 0 0 0-3.967 3.13 8.287 8.287 0 0 0-1.49 4.73c-.004 2.245.914 4.4 2.555 5.994 1.64 1.593 3.869 2.495 6.197 2.507z"/><path fill="#fff" d="M38.4 61.902a3.4 3.4 0 0 0 1.844-.531c.547-.35.974-.847 1.227-1.43a3.088 3.088 0 0 0 .195-1.847 3.16 3.16 0 0 0-.902-1.639 3.351 3.351 0 0 0-1.696-.878 3.426 3.426 0 0 0-1.916.179 3.29 3.29 0 0 0-1.489 1.176 3.113 3.113 0 0 0-.559 1.776c0 .844.347 1.654.964 2.253a3.374 3.374 0 0 0 2.332.94zm39.632 0a3.4 3.4 0 0 0 1.844-.531c.547-.35.974-.847 1.227-1.43a3.088 3.088 0 0 0 .195-1.847 3.16 3.16 0 0 0-.902-1.639 3.351 3.351 0 0 0-1.696-.878 3.426 3.426 0 0 0-1.916.179 3.29 3.29 0 0 0-1.489 1.176 3.113 3.113 0 0 0-.559 1.776c0 .84.342 1.644.953 2.242.61.598 1.44.94 2.311.952z"/></svg>
|
package/dist/pkg/npm.svg
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg width="800px" height="800px" viewBox="0 0 256 256" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
|
4
|
+
<g>
|
|
5
|
+
<polygon fill="#C12127" points="0 256 0 0 256 0 256 256">
|
|
6
|
+
|
|
7
|
+
<polygon fill="#FFFFFF" points="48 48 208 48 208 208 176 208 176 80 128 80 128 208 48 208">
|
|
8
|
+
|
|
9
|
+
</g>
|
|
10
|
+
</svg>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title>file_type_yarn</title><path d="M28.208,24.409a10.493,10.493,0,0,0-3.959,1.822,23.743,23.743,0,0,1-5.835,2.642,1.632,1.632,0,0,1-.983.55A62.228,62.228,0,0,1,10.984,30c-1.163.009-1.876-.3-2.074-.776a1.573,1.573,0,0,1,.866-2.074,3.759,3.759,0,0,1-.514-.379c-.171-.171-.352-.514-.406-.388-.225.55-.343,1.894-.947,2.5-.83.839-2.4.559-3.328.072-1.019-.541.072-1.813.072-1.813a.73.73,0,0,1-.992-.343,4.847,4.847,0,0,1-.667-2.949,5.374,5.374,0,0,1,1.749-2.895,9.334,9.334,0,0,1,.658-4.4,10.445,10.445,0,0,1,3.165-3.661S6.628,10.747,7.35,8.817c.469-1.262.658-1.253.812-1.308a3.633,3.633,0,0,0,1.452-.857,5.265,5.265,0,0,1,4.41-1.7S15.2,1.4,16.277,2.09a18.349,18.349,0,0,1,1.533,2.886s1.281-.748,1.425-.469a11.334,11.334,0,0,1,.523,6.132,14.01,14.01,0,0,1-2.6,5.411c-.135.225,1.551.938,2.615,3.887.983,2.7.108,4.96.262,5.212.027.045.036.063.036.063s1.127.09,3.391-1.308A8.5,8.5,0,0,1,27.739,22.3a1.081,1.081,0,0,1,.469,2.11Z" style="fill:#2188b6"/></svg>
|
package/dist/shiki.d.ts
ADDED
package/dist/shiki.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createHighlighter } from 'shiki';
|
|
2
|
+
let highlighter = null;
|
|
3
|
+
const highlighterPromise = createHighlighter({
|
|
4
|
+
themes: ['github-light', 'github-dark'],
|
|
5
|
+
langs: ['svelte', 'typescript', 'javascript', 'html', 'css', 'json', 'bash']
|
|
6
|
+
}).then((h) => {
|
|
7
|
+
highlighter = h;
|
|
8
|
+
return h;
|
|
9
|
+
});
|
|
10
|
+
export async function getHighlighterSingleton() {
|
|
11
|
+
if (highlighter)
|
|
12
|
+
return highlighter;
|
|
13
|
+
return highlighterPromise;
|
|
14
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
export interface ReplProps {
|
|
3
|
+
title?: string;
|
|
4
|
+
content?: string | Record<string, string | Record<string, unknown>>;
|
|
5
|
+
children?: Snippet;
|
|
6
|
+
presentation?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolbarProps {
|
|
9
|
+
title?: string;
|
|
10
|
+
language: string;
|
|
11
|
+
copyState?: boolean;
|
|
12
|
+
presentation?: boolean;
|
|
13
|
+
viewState?: 'code' | 'preview';
|
|
14
|
+
themeState?: 'light' | 'dark';
|
|
15
|
+
onToggleTheme?: () => void;
|
|
16
|
+
modeState?: 'code' | 'playground' | 'mixed';
|
|
17
|
+
children?: Snippet;
|
|
18
|
+
files?: FileItem[];
|
|
19
|
+
}
|
|
20
|
+
export interface FilesProps {
|
|
21
|
+
files?: FileItem[];
|
|
22
|
+
activeIndex: number;
|
|
23
|
+
viewState: 'code' | 'preview';
|
|
24
|
+
modeState: 'code' | 'playground' | 'mixed';
|
|
25
|
+
}
|
|
26
|
+
export interface FileItem {
|
|
27
|
+
name: string;
|
|
28
|
+
content: string;
|
|
29
|
+
lang?: string;
|
|
30
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const copyToClipboard: (value: string) => void;
|
|
2
|
+
export declare const dictionary: {
|
|
3
|
+
[key: string]: string[];
|
|
4
|
+
};
|
|
5
|
+
export declare const dictionaryIcons: {
|
|
6
|
+
[key: string]: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const dictionaryPkgIcons: {
|
|
9
|
+
[key: string]: string;
|
|
10
|
+
};
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import javascript from './languages/javascript.svg';
|
|
2
|
+
import typescript from './languages/typescript.svg';
|
|
3
|
+
import svelte from './languages/svelte.svg';
|
|
4
|
+
import css from './languages/css.svg';
|
|
5
|
+
import html from './languages/html.svg';
|
|
6
|
+
import shell from './languages/shell.svg';
|
|
7
|
+
import npm from './pkg/npm.svg';
|
|
8
|
+
import yarn from './pkg/yarn.svg';
|
|
9
|
+
import bun from './pkg/bun.svg';
|
|
10
|
+
export const copyToClipboard = (value) => {
|
|
11
|
+
if (navigator.clipboard && window.isSecureContext) {
|
|
12
|
+
navigator.clipboard
|
|
13
|
+
.writeText(value)
|
|
14
|
+
.then(function () {
|
|
15
|
+
console.log('Success copy: ' + value);
|
|
16
|
+
})
|
|
17
|
+
.catch(function (err) {
|
|
18
|
+
console.error('Error copying to clipboard: ', err);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
// Fallback (legacy browser)
|
|
23
|
+
const zoneTexte = document.createElement('textarea');
|
|
24
|
+
zoneTexte.value = value;
|
|
25
|
+
zoneTexte.style.position = 'fixed';
|
|
26
|
+
zoneTexte.style.left = '-9999px';
|
|
27
|
+
document.body.appendChild(zoneTexte);
|
|
28
|
+
zoneTexte.focus();
|
|
29
|
+
zoneTexte.select();
|
|
30
|
+
try {
|
|
31
|
+
document.execCommand('copy');
|
|
32
|
+
console.log('Success copy: ' + value);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
console.error('Error copying to clipboard: ', err);
|
|
36
|
+
}
|
|
37
|
+
document.body.removeChild(zoneTexte);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export const dictionary = {
|
|
41
|
+
javascript: ['js', 'javascript'],
|
|
42
|
+
typescript: ['ts', 'typescript'],
|
|
43
|
+
svelte: ['svelte', 'svelte.ts', 'svelte.js'],
|
|
44
|
+
css: ['css', 'scss', 'less'],
|
|
45
|
+
html: ['html', 'htm'],
|
|
46
|
+
json: ['json'],
|
|
47
|
+
shell: ['bash', 'sh', 'shell']
|
|
48
|
+
};
|
|
49
|
+
export const dictionaryIcons = {
|
|
50
|
+
js: javascript,
|
|
51
|
+
ts: typescript,
|
|
52
|
+
'svelte.ts': svelte,
|
|
53
|
+
'svelte.js': svelte,
|
|
54
|
+
svelte: svelte,
|
|
55
|
+
shell: shell,
|
|
56
|
+
bash: shell,
|
|
57
|
+
sh: shell,
|
|
58
|
+
css: css,
|
|
59
|
+
scss: css,
|
|
60
|
+
less: css,
|
|
61
|
+
html: html,
|
|
62
|
+
htm: html,
|
|
63
|
+
json: shell
|
|
64
|
+
};
|
|
65
|
+
export const dictionaryPkgIcons = {
|
|
66
|
+
npm,
|
|
67
|
+
yarn,
|
|
68
|
+
bun
|
|
69
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lapikit/repl",
|
|
3
|
+
"version": "0.0.0-insiders.0c4e011",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"author": {
|
|
9
|
+
"name": "Nycolaide",
|
|
10
|
+
"email": "contact@lapikit.dev"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://lapikit.dev",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/lapikit/lapikit-repl.git"
|
|
16
|
+
},
|
|
17
|
+
"funding": "https://buymeacoffee.com/nycolaide",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "vite dev",
|
|
20
|
+
"build": "vite build && npm run prepack",
|
|
21
|
+
"preview": "vite preview",
|
|
22
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
23
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
24
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
25
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
26
|
+
"format": "prettier --write .",
|
|
27
|
+
"lint": "prettier --check . && eslint .",
|
|
28
|
+
"test:unit": "vitest",
|
|
29
|
+
"test": "npm run test:unit -- --run"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"!dist/**/*.test.*",
|
|
34
|
+
"!dist/**/*.spec.*"
|
|
35
|
+
],
|
|
36
|
+
"sideEffects": [
|
|
37
|
+
"**/*.css"
|
|
38
|
+
],
|
|
39
|
+
"svelte": "./dist/index.js",
|
|
40
|
+
"types": "./dist/index.d.ts",
|
|
41
|
+
"type": "module",
|
|
42
|
+
"exports": {
|
|
43
|
+
".": {
|
|
44
|
+
"types": "./dist/index.d.ts",
|
|
45
|
+
"svelte": "./dist/index.js"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@sveltejs/kit": "^2.0.0",
|
|
50
|
+
"svelte": "^5.0.0",
|
|
51
|
+
"lapikit": "^0.6.7"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@eslint/compat": "^1.4.0",
|
|
55
|
+
"@eslint/js": "^9.39.1",
|
|
56
|
+
"@sveltejs/adapter-auto": "^7.0.0",
|
|
57
|
+
"@sveltejs/kit": "^2.49.1",
|
|
58
|
+
"@sveltejs/package": "^2.5.7",
|
|
59
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
60
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
61
|
+
"@testing-library/svelte": "^5.2.4",
|
|
62
|
+
"eslint": "^9.39.1",
|
|
63
|
+
"eslint-config-prettier": "^10.1.8",
|
|
64
|
+
"eslint-plugin-svelte": "^3.13.1",
|
|
65
|
+
"globals": "^16.5.0",
|
|
66
|
+
"jsdom": "^26.0.0",
|
|
67
|
+
"prettier": "^3.7.4",
|
|
68
|
+
"prettier-plugin-svelte": "^3.4.0",
|
|
69
|
+
"publint": "^0.3.15",
|
|
70
|
+
"svelte": "^5.45.6",
|
|
71
|
+
"svelte-check": "^4.3.4",
|
|
72
|
+
"typescript": "^5.9.3",
|
|
73
|
+
"typescript-eslint": "^8.48.1",
|
|
74
|
+
"vite": "^7.2.6",
|
|
75
|
+
"vitest": "^4.0.15"
|
|
76
|
+
},
|
|
77
|
+
"keywords": [
|
|
78
|
+
"svelte"
|
|
79
|
+
],
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"@lucide/svelte": "^0.562.0",
|
|
82
|
+
"shiki": "^3.20.0"
|
|
83
|
+
}
|
|
84
|
+
}
|