@aiaiai-pt/design-system 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/components/Alert.svelte +100 -0
  2. package/components/Badge.svelte +108 -0
  3. package/components/BottomNav.svelte +37 -0
  4. package/components/BottomNavItem.svelte +121 -0
  5. package/components/Button.svelte +269 -0
  6. package/components/Card.svelte +108 -0
  7. package/components/Checkbox.svelte +138 -0
  8. package/components/CodeBlock.svelte +187 -0
  9. package/components/CodeEditor.svelte +221 -0
  10. package/components/CollapsibleSection.svelte +160 -0
  11. package/components/Combobox.svelte +396 -0
  12. package/components/EmptyState.svelte +148 -0
  13. package/components/FileUpload.svelte +280 -0
  14. package/components/FileUploadItem.svelte +222 -0
  15. package/components/Input.svelte +222 -0
  16. package/components/KeyValue.svelte +79 -0
  17. package/components/Label.svelte +49 -0
  18. package/components/List.svelte +70 -0
  19. package/components/ListItem.svelte +125 -0
  20. package/components/Menu.svelte +161 -0
  21. package/components/MenuItem.svelte +120 -0
  22. package/components/MenuSeparator.svelte +34 -0
  23. package/components/Modal.svelte +260 -0
  24. package/components/OptionGrid.svelte +195 -0
  25. package/components/Panel.svelte +256 -0
  26. package/components/Popover.svelte +194 -0
  27. package/components/Progress.svelte +78 -0
  28. package/components/Select.svelte +182 -0
  29. package/components/Separator.svelte +47 -0
  30. package/components/Sidebar.svelte +106 -0
  31. package/components/SidebarItem.svelte +154 -0
  32. package/components/SidebarSection.svelte +43 -0
  33. package/components/Skeleton.svelte +79 -0
  34. package/components/Status.svelte +104 -0
  35. package/components/Stepper.svelte +142 -0
  36. package/components/Tab.svelte +94 -0
  37. package/components/TabList.svelte +36 -0
  38. package/components/TabPanel.svelte +45 -0
  39. package/components/Tabs.svelte +46 -0
  40. package/components/Tag.svelte +96 -0
  41. package/components/Textarea.svelte +143 -0
  42. package/components/Toast.svelte +114 -0
  43. package/components/Toggle.svelte +132 -0
  44. package/components/index.js +70 -0
  45. package/package.json +45 -0
  46. package/tokens/base.css +175 -0
  47. package/tokens/components.css +530 -0
  48. package/tokens/semantic.css +211 -0
  49. package/tokens/themes/aiaiai.css +53 -0
  50. package/tokens/themes/bespoke-example.css +148 -0
  51. package/tokens/themes/branded-example.css +55 -0
  52. package/tokens/utilities.css +1865 -0
@@ -0,0 +1,108 @@
1
+ <!--
2
+ @component Card
3
+
4
+ Surface container. Three variants: flat, bordered (default), elevated.
5
+ Content-agnostic. Consumes --card-* tokens from components.css.
6
+
7
+ @example Bordered (default)
8
+ <Card>Content here</Card>
9
+
10
+ @example Elevated
11
+ <Card variant="elevated">Floating content</Card>
12
+
13
+ @example Interactive + selectable
14
+ <Card interactive selected={isSelected} onclick={() => select(id)}>
15
+ Clickable card
16
+ </Card>
17
+ -->
18
+ <script>
19
+ /**
20
+ * @typedef {'flat' | 'bordered' | 'elevated'} Variant
21
+ */
22
+
23
+ let {
24
+ /** @type {Variant} */
25
+ variant = 'bordered',
26
+ /** @type {boolean} */
27
+ interactive = false,
28
+ /** @type {boolean} */
29
+ selected = false,
30
+ /** @type {string} */
31
+ class: className = '',
32
+ /** @type {import('svelte').Snippet | undefined} */
33
+ children = undefined,
34
+ ...rest
35
+ } = $props();
36
+
37
+ // tag variable unused — rendering uses {#if interactive} branching
38
+ </script>
39
+
40
+ {#if interactive}
41
+ <button
42
+ class="card card-{variant} card-interactive {className}"
43
+ class:card-selected={selected}
44
+ {...rest}
45
+ >
46
+ {#if children}{@render children()}{/if}
47
+ </button>
48
+ {:else}
49
+ <div
50
+ class="card card-{variant} {className}"
51
+ class:card-selected={selected}
52
+ {...rest}
53
+ >
54
+ {#if children}{@render children()}{/if}
55
+ </div>
56
+ {/if}
57
+
58
+ <style>
59
+ .card {
60
+ border-radius: var(--card-radius);
61
+ padding: var(--card-padding);
62
+ background: var(--card-bg);
63
+ transition: all var(--card-transition);
64
+ text-align: left;
65
+ display: flex;
66
+ flex-direction: column;
67
+ }
68
+
69
+ .card-flat {
70
+ border: var(--card-flat-border);
71
+ box-shadow: var(--card-flat-shadow);
72
+ background: var(--color-surface-secondary);
73
+ }
74
+
75
+ .card-bordered {
76
+ border: var(--card-bordered-border);
77
+ box-shadow: var(--card-bordered-shadow);
78
+ }
79
+
80
+ .card-elevated {
81
+ border: var(--card-elevated-border);
82
+ box-shadow: var(--card-elevated-shadow);
83
+ }
84
+
85
+ .card-interactive {
86
+ cursor: pointer;
87
+ font-family: inherit;
88
+ font-size: inherit;
89
+ width: 100%;
90
+ }
91
+
92
+ .card-interactive:hover {
93
+ border: var(--card-interactive-hover-border);
94
+ }
95
+
96
+ .card-interactive:active {
97
+ background: var(--card-interactive-active-bg);
98
+ }
99
+
100
+ .card-interactive:focus-visible {
101
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
102
+ outline-offset: var(--focus-ring-offset);
103
+ }
104
+
105
+ .card-selected {
106
+ border-color: var(--card-selected-border-color);
107
+ }
108
+ </style>
@@ -0,0 +1,138 @@
1
+ <!--
2
+ @component Checkbox
3
+
4
+ Checkbox with label. Supports checked, indeterminate, and disabled states.
5
+ Consumes --checkbox-* tokens from components.css.
6
+
7
+ @example
8
+ <Checkbox label="Accept terms" bind:checked />
9
+
10
+ @example Indeterminate
11
+ <Checkbox label="Select all" indeterminate />
12
+ -->
13
+ <script module>
14
+ let _checkboxUid = 0;
15
+ </script>
16
+
17
+ <script>
18
+ let {
19
+ /** @type {boolean} */
20
+ checked = $bindable(false),
21
+ /** @type {boolean} */
22
+ indeterminate = false,
23
+ /** @type {boolean} */
24
+ disabled = false,
25
+ /** @type {string | undefined} */
26
+ label = undefined,
27
+ /** @type {string | undefined} */
28
+ id = undefined,
29
+ /** @type {string} */
30
+ class: className = '',
31
+ ...rest
32
+ } = $props();
33
+
34
+ const fallbackId = `checkbox-${_checkboxUid++}`;
35
+ const checkboxId = $derived(id ?? fallbackId);
36
+
37
+ /** @type {HTMLInputElement | undefined} */
38
+ let inputEl;
39
+
40
+ $effect(() => {
41
+ if (inputEl) {
42
+ inputEl.indeterminate = indeterminate;
43
+ }
44
+ });
45
+ </script>
46
+
47
+ <label
48
+ class="checkbox-group {className}"
49
+ class:checkbox-group-disabled={disabled}
50
+ for={checkboxId}
51
+ >
52
+ <span
53
+ class="checkbox"
54
+ class:checkbox-checked={checked || indeterminate}
55
+ >
56
+ {#if checked}
57
+ <svg class="checkbox-icon" viewBox="0 0 12 12" fill="none" aria-hidden="true">
58
+ <path d="M2.5 6l2.5 2.5 4.5-5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
59
+ </svg>
60
+ {:else if indeterminate}
61
+ <svg class="checkbox-icon" viewBox="0 0 12 12" fill="none" aria-hidden="true">
62
+ <path d="M3 6h6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
63
+ </svg>
64
+ {/if}
65
+ </span>
66
+ <input
67
+ bind:this={inputEl}
68
+ id={checkboxId}
69
+ type="checkbox"
70
+ class="checkbox-input"
71
+ {disabled}
72
+ bind:checked
73
+ {...rest}
74
+ />
75
+ {#if label}
76
+ <span class="checkbox-label">{label}</span>
77
+ {/if}
78
+ </label>
79
+
80
+ <style>
81
+ .checkbox-group {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: var(--space-sm);
85
+ cursor: pointer;
86
+ }
87
+
88
+ .checkbox-group-disabled {
89
+ opacity: 0.5;
90
+ cursor: not-allowed;
91
+ }
92
+
93
+ .checkbox-input {
94
+ position: absolute;
95
+ opacity: 0;
96
+ width: 0;
97
+ height: 0;
98
+ }
99
+
100
+ .checkbox {
101
+ width: var(--checkbox-size);
102
+ height: var(--checkbox-size);
103
+ border-radius: var(--checkbox-radius);
104
+ border: var(--checkbox-border);
105
+ background: var(--color-surface);
106
+ display: flex;
107
+ align-items: center;
108
+ justify-content: center;
109
+ flex-shrink: 0;
110
+ transition: all var(--duration-fast) var(--easing-default);
111
+ }
112
+
113
+ .checkbox-group:has(.checkbox-input:focus-visible) .checkbox {
114
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
115
+ outline-offset: var(--focus-ring-offset);
116
+ }
117
+
118
+ .checkbox-checked {
119
+ background: var(--checkbox-bg-checked);
120
+ border-color: var(--checkbox-bg-checked);
121
+ }
122
+
123
+ .checkbox-icon {
124
+ width: 12px;
125
+ height: 12px;
126
+ color: var(--checkbox-check-color);
127
+ }
128
+
129
+ .checkbox-label {
130
+ font-family: var(--type-body-sm-font);
131
+ font-size: var(--type-body-sm-size);
132
+ color: var(--color-text);
133
+ }
134
+
135
+ .checkbox-group-disabled .checkbox-label {
136
+ color: var(--color-text-muted);
137
+ }
138
+ </style>
@@ -0,0 +1,187 @@
1
+ <!--
2
+ @component CodeBlock
3
+
4
+ Formatted code display with optional line numbers.
5
+ Consumes --code-* tokens from components.css.
6
+
7
+ Syntax highlighting is the consumer's responsibility (Prism, Shiki, etc).
8
+ This component handles layout, line numbers, and copy.
9
+
10
+ @example
11
+ <CodeBlock code="SELECT * FROM users WHERE active = true;" language="sql" />
12
+
13
+ @example Without line numbers
14
+ <CodeBlock code="pip install pandas" lineNumbers={false} />
15
+
16
+ @example With highlighted HTML (pre-highlighted by consumer)
17
+ <CodeBlock language="python" lineNumbers>
18
+ {#snippet content()}
19
+ <span class="token keyword">def</span> <span class="token function">main</span>():
20
+ {/snippet}
21
+ </CodeBlock>
22
+ -->
23
+ <script>
24
+ let {
25
+ /** @type {string | undefined} */
26
+ code = undefined,
27
+ /** @type {string | undefined} */
28
+ language = undefined,
29
+ /** @type {boolean} */
30
+ lineNumbers = true,
31
+ /** @type {boolean} */
32
+ copyable = true,
33
+ /** @type {string} */
34
+ class: className = '',
35
+ /** @type {import('svelte').Snippet | undefined} */
36
+ content = undefined,
37
+ ...rest
38
+ } = $props();
39
+
40
+ let copied = $state(false);
41
+
42
+ const lines = $derived(code?.split('\n') ?? []);
43
+
44
+ async function handleCopy() {
45
+ if (!code) return;
46
+ try {
47
+ await navigator.clipboard.writeText(code);
48
+ copied = true;
49
+ setTimeout(() => { copied = false; }, 2000);
50
+ } catch {
51
+ // Clipboard API not available
52
+ }
53
+ }
54
+ </script>
55
+
56
+ <div
57
+ class="code-block {className}"
58
+ data-language={language}
59
+ {...rest}
60
+ >
61
+ {#if copyable && code}
62
+ <button
63
+ class="code-copy"
64
+ onclick={handleCopy}
65
+ aria-label={copied ? 'Copied' : 'Copy code'}
66
+ >
67
+ <span class="code-copy-label">
68
+ {copied ? 'COPIED' : 'COPY'}
69
+ </span>
70
+ </button>
71
+ {/if}
72
+
73
+ <div class="code-scroll">
74
+ {#if content}
75
+ <!-- Pre-highlighted content via snippet -->
76
+ <pre class="code-pre"><code>{@render content()}</code></pre>
77
+ {:else if code}
78
+ <!-- Plain text with optional line numbers -->
79
+ <table class="code-table" role="presentation">
80
+ <tbody>
81
+ {#each lines as line, i}
82
+ <tr class="code-line">
83
+ {#if lineNumbers}
84
+ <td class="code-line-number" aria-hidden="true">{i + 1}</td>
85
+ {/if}
86
+ <td class="code-line-content">{line || '\u00A0'}</td>
87
+ </tr>
88
+ {/each}
89
+ </tbody>
90
+ </table>
91
+ {/if}
92
+ </div>
93
+ </div>
94
+
95
+ <style>
96
+ .code-block {
97
+ position: relative;
98
+ background: var(--code-bg);
99
+ border: var(--code-border);
100
+ border-radius: var(--code-radius);
101
+ overflow: hidden;
102
+ }
103
+
104
+ .code-scroll {
105
+ overflow-x: auto;
106
+ }
107
+
108
+ .code-pre {
109
+ margin: 0;
110
+ padding: var(--code-padding);
111
+ font-family: var(--code-font);
112
+ font-size: var(--code-font-size);
113
+ line-height: var(--code-line-height);
114
+ color: var(--code-text);
115
+ }
116
+
117
+ .code-table {
118
+ border-collapse: collapse;
119
+ width: 100%;
120
+ font-family: var(--code-font);
121
+ font-size: var(--code-font-size);
122
+ line-height: var(--code-line-height);
123
+ color: var(--code-text);
124
+ }
125
+
126
+ .code-line {
127
+ display: block;
128
+ }
129
+
130
+ .code-line-number {
131
+ width: var(--code-line-number-width);
132
+ padding: 0 var(--space-sm);
133
+ text-align: right;
134
+ color: var(--code-line-number-color);
135
+ background: var(--code-gutter-bg);
136
+ border-right: var(--code-gutter-border);
137
+ user-select: none;
138
+ vertical-align: top;
139
+ }
140
+
141
+ .code-line-content {
142
+ padding: 0 var(--code-padding);
143
+ white-space: pre;
144
+ }
145
+
146
+ /* First and last rows get vertical padding */
147
+ .code-table tbody tr:first-child .code-line-number,
148
+ .code-table tbody tr:first-child .code-line-content {
149
+ padding-top: var(--code-padding);
150
+ }
151
+
152
+ .code-table tbody tr:last-child .code-line-number,
153
+ .code-table tbody tr:last-child .code-line-content {
154
+ padding-bottom: var(--code-padding);
155
+ }
156
+
157
+ /* ─── Copy button ─── */
158
+ .code-copy {
159
+ all: unset;
160
+ position: absolute;
161
+ top: var(--space-sm);
162
+ right: var(--space-sm);
163
+ cursor: pointer;
164
+ z-index: 1;
165
+ padding: var(--space-2xs) var(--space-sm);
166
+ border-radius: var(--radius-sm);
167
+ background: var(--code-bg);
168
+ border: var(--code-border);
169
+ transition: all var(--duration-instant) var(--easing-default);
170
+ }
171
+
172
+ .code-copy:hover {
173
+ background: var(--color-surface-tertiary);
174
+ }
175
+
176
+ .code-copy:focus-visible {
177
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
178
+ outline-offset: var(--focus-ring-offset);
179
+ }
180
+
181
+ .code-copy-label {
182
+ font-family: var(--type-label-font);
183
+ font-size: var(--type-caption-size);
184
+ letter-spacing: var(--type-label-tracking);
185
+ color: var(--color-text-secondary);
186
+ }
187
+ </style>
@@ -0,0 +1,221 @@
1
+ <!--
2
+ @component CodeEditor
3
+
4
+ Editable code editor wrapping CodeMirror 6.
5
+ Styled from --code-* tokens to match CodeBlock appearance.
6
+ Requires @codemirror/* peer dependencies installed by the consumer.
7
+
8
+ @example SQL editor
9
+ <CodeEditor bind:value={sql} language="sql" />
10
+
11
+ @example Readonly Python
12
+ <CodeEditor value={code} readonly language="python" minLines={10} />
13
+
14
+ @example Empty with placeholder
15
+ <CodeEditor language="sql" placeholder="Enter your query..." />
16
+ -->
17
+ <script>
18
+ import { onMount } from 'svelte';
19
+ import { EditorView, keymap, placeholder as phExtension, lineNumbers as lnExtension } from '@codemirror/view';
20
+ import { EditorState } from '@codemirror/state';
21
+ import { defaultKeymap, history, historyKeymap } from '@codemirror/commands';
22
+ import { syntaxHighlighting, defaultHighlightStyle } from '@codemirror/language';
23
+ import { sql as sqlLang } from '@codemirror/lang-sql';
24
+ import { python as pythonLang } from '@codemirror/lang-python';
25
+ import { json as jsonLang } from '@codemirror/lang-json';
26
+
27
+ /** @type {{ value?: string, language?: string, readonly?: boolean, placeholder?: string, lineNumbers?: boolean, minLines?: number, maxLines?: number, class?: string }} */
28
+ let {
29
+ /** @type {string} */
30
+ value = $bindable(''),
31
+ /** @type {string} */
32
+ language = 'sql',
33
+ /** @type {boolean} */
34
+ readonly = false,
35
+ /** @type {string} */
36
+ placeholder = '',
37
+ /** @type {boolean} */
38
+ lineNumbers = true,
39
+ /** @type {number} */
40
+ minLines = 5,
41
+ /** @type {number} */
42
+ maxLines = 20,
43
+ /** @type {string} */
44
+ class: className = '',
45
+ } = $props();
46
+
47
+ /** @type {HTMLDivElement} */
48
+ let container;
49
+ /** @type {EditorView | null} */
50
+ let view = null;
51
+ let internalUpdate = false;
52
+
53
+ /**
54
+ * Get the language extension for the given language name.
55
+ * @param {string} lang
56
+ */
57
+ function getLanguageExtension(lang) {
58
+ switch (lang) {
59
+ case 'sql': return sqlLang();
60
+ case 'python': return pythonLang();
61
+ case 'json': return jsonLang();
62
+ default: return [];
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Build a CM6 theme from CSS custom properties on the container element.
68
+ * @param {HTMLElement} el
69
+ * @param {number} minH
70
+ * @param {number} maxH
71
+ */
72
+ function buildThemeFromTokens(el, minH, maxH) {
73
+ const s = getComputedStyle(el);
74
+ const get = (/** @type {string} */ prop) => s.getPropertyValue(prop).trim();
75
+
76
+ const bg = get('--code-bg') || 'inherit';
77
+ const text = get('--code-text') || 'inherit';
78
+ const font = get('--code-font') || 'monospace';
79
+ const fontSize = get('--code-font-size') || '14px';
80
+ const lineHeight = get('--code-line-height') || '1.6';
81
+ const gutterBg = get('--code-gutter-bg') || 'inherit';
82
+ const gutterBorder = get('--code-gutter-border') || 'var(--elevation-border)';
83
+ const lineNumColor = get('--code-line-number-color') || 'inherit';
84
+ const selectionBg = get('--code-selection-bg') || 'rgba(0,0,0,0.1)';
85
+ const cursorColor = get('--code-cursor-color') || 'currentColor';
86
+
87
+ return EditorView.theme({
88
+ '&': {
89
+ backgroundColor: bg,
90
+ color: text,
91
+ fontFamily: font,
92
+ fontSize,
93
+ lineHeight,
94
+ minHeight: `calc(${lineHeight} * ${fontSize} * ${minH})`,
95
+ maxHeight: `calc(${lineHeight} * ${fontSize} * ${maxH})`,
96
+ },
97
+ '&.cm-focused': {
98
+ outline: 'none',
99
+ },
100
+ '.cm-scroller': {
101
+ overflow: 'auto',
102
+ fontFamily: font,
103
+ },
104
+ '.cm-content': {
105
+ caretColor: cursorColor,
106
+ fontFamily: font,
107
+ padding: '0',
108
+ },
109
+ '.cm-cursor, .cm-dropCursor': {
110
+ borderLeftColor: cursorColor,
111
+ borderLeftWidth: '2px',
112
+ },
113
+ '&.cm-focused .cm-selectionBackground, .cm-selectionBackground': {
114
+ backgroundColor: selectionBg,
115
+ },
116
+ '.cm-gutters': {
117
+ backgroundColor: gutterBg,
118
+ borderRight: gutterBorder || '1px solid #ddd',
119
+ color: lineNumColor,
120
+ },
121
+ '.cm-lineNumbers .cm-gutterElement': {
122
+ padding: '0 8px 0 4px',
123
+ minWidth: '32px',
124
+ },
125
+ '.cm-activeLine': {
126
+ backgroundColor: 'transparent',
127
+ },
128
+ '.cm-activeLineGutter': {
129
+ backgroundColor: 'transparent',
130
+ },
131
+ '.cm-placeholder': {
132
+ color: lineNumColor,
133
+ fontStyle: 'italic',
134
+ },
135
+ });
136
+ }
137
+
138
+ onMount(() => {
139
+ const extensions = [
140
+ history(),
141
+ keymap.of([...defaultKeymap, ...historyKeymap]),
142
+ syntaxHighlighting(defaultHighlightStyle),
143
+ buildThemeFromTokens(container, minLines, maxLines),
144
+ EditorView.updateListener.of((/** @type {import('@codemirror/view').ViewUpdate} */ update) => {
145
+ if (update.docChanged) {
146
+ internalUpdate = true;
147
+ value = update.state.doc.toString();
148
+ internalUpdate = false;
149
+ }
150
+ }),
151
+ ];
152
+
153
+ if (lineNumbers) {
154
+ extensions.push(lnExtension());
155
+ }
156
+
157
+ if (placeholder) {
158
+ extensions.push(phExtension(placeholder));
159
+ }
160
+
161
+ if (readonly) {
162
+ extensions.push(EditorState.readOnly.of(true));
163
+ extensions.push(EditorView.editable.of(false));
164
+ }
165
+
166
+ const langExt = getLanguageExtension(language);
167
+ if (langExt) {
168
+ extensions.push(langExt);
169
+ }
170
+
171
+ view = new EditorView({
172
+ state: EditorState.create({ doc: /** @type {string} */ (value), extensions }),
173
+ parent: container,
174
+ });
175
+
176
+ return () => {
177
+ view?.destroy();
178
+ view = null;
179
+ };
180
+ });
181
+
182
+ // Sync external value changes into the editor
183
+ $effect(() => {
184
+ if (view && !internalUpdate) {
185
+ const current = view.state.doc.toString();
186
+ if (value !== current) {
187
+ view.dispatch({
188
+ changes: { from: 0, to: current.length, insert: /** @type {string} */ (value) },
189
+ });
190
+ }
191
+ }
192
+ });
193
+ </script>
194
+
195
+ <div
196
+ class="code-editor {className}"
197
+ class:code-editor--readonly={readonly}
198
+ bind:this={container}
199
+ data-language={language}
200
+ ></div>
201
+
202
+ <style>
203
+ .code-editor {
204
+ border: var(--code-border);
205
+ border-radius: var(--code-radius);
206
+ overflow: hidden;
207
+ background: var(--code-bg);
208
+ transition: box-shadow var(--duration-instant) var(--easing-default);
209
+ }
210
+
211
+ .code-editor:focus-within:not(.code-editor--readonly) {
212
+ box-shadow:
213
+ 0 0 0 var(--focus-ring-offset) var(--color-surface),
214
+ 0 0 0 calc(var(--focus-ring-offset) + var(--focus-ring-width)) var(--focus-ring-color);
215
+ }
216
+
217
+ /* CM6 places its own wrapper — let it fill the container */
218
+ .code-editor :global(.cm-editor) {
219
+ border-radius: var(--code-radius);
220
+ }
221
+ </style>