svelte-comp 1.1.7 → 1.2.5

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.
@@ -30,6 +30,9 @@
30
30
  * @options xs|sm|md|lg|xl
31
31
  * @default md
32
32
  *
33
+ * @prop class {string} - Extra classes applied to the root container
34
+ * @default ""
35
+ *
33
36
  * @note Uses Prism for syntax highlighting; HTML/CSS/TXT grammars are bundled by default.
34
37
  * @note Editable mode renders a transparent textarea above a highlighted code layer, mirroring real editors.
35
38
  * @note Cursor-line highlight is overlaid using CSS variables and scroll-position tracking.
@@ -59,6 +62,7 @@
59
62
  editable?: boolean;
60
63
  activeLine?: boolean;
61
64
  sz?: SizeKey;
65
+ class?: string;
62
66
  };
63
67
 
64
68
  let {
@@ -70,6 +74,7 @@
70
74
  editable = false,
71
75
  activeLine = false,
72
76
  sz = "md",
77
+ class: externalClass = "",
73
78
  }: Props = $props();
74
79
 
75
80
  let textareaEl = $state<HTMLTextAreaElement | null>(null);
@@ -142,8 +147,9 @@
142
147
 
143
148
  <div
144
149
  class={cx(
145
- "w-full border border-[var(--border-color-default)] bg-[var(--color-bg-surface)]",
146
- "text-[var(--color-text-default)]"
150
+ "cv-root w-full h-full min-h-0 flex flex-col border border-[var(--border-color-default)] bg-[var(--color-bg-surface)]",
151
+ "text-[var(--color-text-default)]",
152
+ externalClass
147
153
  )}
148
154
  >
149
155
  {#if title}
@@ -170,14 +176,20 @@
170
176
  </div>
171
177
  {/if}
172
178
 
173
- <div class={cx("flex font-mono", TEXT[sz], LINE_HEIGHT[sz])}>
179
+ <div
180
+ class={cx(
181
+ "cv-body flex flex-1 min-h-0 font-mono",
182
+ TEXT[sz],
183
+ LINE_HEIGHT[sz]
184
+ )}
185
+ >
174
186
  {#if showLineNumbers}
175
187
  <div
176
188
  bind:this={gutterEl}
177
189
  class={cx(
178
190
  "select-none px-3 py-[12px] border-r border-[var(--border-color-default)]",
179
191
  "text-[var(--color-text-muted)] text-right overflow-hidden",
180
- "bg-[var(--color-bg-surface)] tabular-nums min-h-[180px] max-h-[480px]"
192
+ "cv-gutter bg-[var(--color-bg-surface)] tabular-nums h-full min-h-0"
181
193
  )}
182
194
  >
183
195
  {#each lines as _, i (i)}
@@ -186,7 +198,7 @@
186
198
  </div>
187
199
  {/if}
188
200
 
189
- <div class="relative flex-1 min-h-[180px] max-h-[480px]">
201
+ <div class="cv-editor relative flex-1 min-h-0">
190
202
  <div
191
203
  bind:this={highlightEl}
192
204
  class={cx("cv-highlight cv-layer", TEXT[sz], LINE_HEIGHT[sz])}
@@ -28,6 +28,9 @@
28
28
  * @options xs|sm|md|lg|xl
29
29
  * @default md
30
30
  *
31
+ * @prop class {string} - Extra classes applied to the root container
32
+ * @default ""
33
+ *
31
34
  * @note Uses Prism for syntax highlighting; HTML/CSS/TXT grammars are bundled by default.
32
35
  * @note Editable mode renders a transparent textarea above a highlighted code layer, mirroring real editors.
33
36
  * @note Cursor-line highlight is overlaid using CSS variables and scroll-position tracking.
@@ -54,6 +57,7 @@ type Props = {
54
57
  editable?: boolean;
55
58
  activeLine?: boolean;
56
59
  sz?: SizeKey;
60
+ class?: string;
57
61
  };
58
62
  declare const CodeView: import("svelte").Component<Props, {}, "code">;
59
63
  type CodeView = ReturnType<typeof CodeView>;
@@ -100,7 +100,7 @@
100
100
  }
101
101
 
102
102
  const panelBase =
103
- "bg-[var(--color-bg-surface)] rounded-[var(--radius-lg)] shadow-lg min-w-80 max-w-md w-full border border-[var(--border-color-default)]";
103
+ "fusion-dialog bg-[var(--color-bg-surface)] rounded-[var(--radius-lg)] shadow-lg min-w-80 max-w-md w-full border border-[var(--border-color-default)]";
104
104
 
105
105
  const paddingBySize: Record<SizeKey, string> = {
106
106
  xs: "p-[var(--spacing-sm)]",
@@ -224,3 +224,12 @@
224
224
  </div>
225
225
  {/if}
226
226
  {/if}
227
+ <style>
228
+ :global(.fusion-dialog h3) {
229
+ color: var(--color-text-default);
230
+ }
231
+
232
+ :global(.fusion-dialog p) {
233
+ color: var(--color-text-muted);
234
+ }
235
+ </style>
@@ -65,13 +65,14 @@
65
65
  </script>
66
66
 
67
67
  <div class={wrapperClass}>
68
- <span>Page {currentPage} of {totalPages}</span>
68
+ <span class="pagination-count">Page {currentPage} of {totalPages}</span>
69
69
 
70
70
  <Button
71
71
  onClick={prevPage}
72
72
  disabled={currentPage === 1}
73
73
  sz="xs"
74
74
  variant="secondary"
75
+ class="pagination-btn"
75
76
  >
76
77
  &lt;
77
78
  </Button>
@@ -82,6 +83,7 @@
82
83
  sz="xs"
83
84
  variant={currentPage === page ? "primary" : "secondary"}
84
85
  aria-current={currentPage === page ? "page" : undefined}
86
+ class="pagination-btn"
85
87
  >
86
88
  {page}
87
89
  </Button>
@@ -92,7 +94,26 @@
92
94
  disabled={currentPage === totalPages}
93
95
  sz="xs"
94
96
  variant="secondary"
97
+ class="pagination-btn"
95
98
  >
96
99
  &gt;
97
100
  </Button>
98
101
  </div>
102
+
103
+ <style>
104
+ @media (max-width: 640px) {
105
+ :global(.pagination-btn) {
106
+ font-size: 10px;
107
+ line-height: 1;
108
+ height: 20px;
109
+ padding: 0 6px;
110
+ }
111
+ }
112
+
113
+ @media (max-width: 480px) {
114
+ :global(.pagination-count) {
115
+ display: none;
116
+ }
117
+ }
118
+ </style>
119
+
@@ -0,0 +1,106 @@
1
+ <script lang="ts">
2
+ /**
3
+ * @component SearchInput
4
+ * @description Search input field with a leading search icon.
5
+ *
6
+ * @prop label {string} - Label text rendered above the field
7
+ *
8
+ * @prop placeholder {string} - Placeholder text (localized by default)
9
+ *
10
+ * @prop value {string} - Controlled field value (bindable)
11
+ * @default ""
12
+ *
13
+ * @prop sz {SizeKey} - Size preset for spacing and typography
14
+ * @options xs|sm|md|lg|xl
15
+ * @default sm
16
+ *
17
+ * @prop variant {FieldVariant} - Visual style variant
18
+ * @options default|filled|neutral
19
+ * @default filled
20
+ *
21
+ * @prop class {string} - Additional classes applied to the Field root
22
+ * @default ""
23
+ *
24
+ * @note Renders a leading search icon and uses `Field` with `type="search"` and `clearable`.
25
+ */
26
+ import { getContext } from "svelte";
27
+ import Field from "./Field.svelte";
28
+ import type { FieldVariant, SizeKey } from "./types";
29
+ import { TEXTS } from "./lang";
30
+
31
+ type Props = {
32
+ label?: string;
33
+ placeholder?: string;
34
+ value?: string;
35
+ sz?: SizeKey;
36
+ variant?: FieldVariant;
37
+ class?: string;
38
+ [key: string]: unknown;
39
+ };
40
+
41
+ let {
42
+ label,
43
+ placeholder,
44
+ value = $bindable(''),
45
+ sz = 'sm',
46
+ variant = 'filled',
47
+ class: externalClass = '',
48
+ ...rest
49
+ }: Props = $props();
50
+
51
+ const langCtx =
52
+ getContext<{ value: keyof typeof TEXTS } | undefined>("lang") ?? null;
53
+ const langKey = $derived(langCtx?.value ?? "en");
54
+ const L = $derived(TEXTS[langKey].components.searchInput);
55
+
56
+ const placeholderFinal = $derived(placeholder ?? L.placeholder);
57
+ </script>
58
+
59
+ {#snippet leading()}
60
+ <span class="ml-1 inline-flex h-6 w-6 items-center justify-center text-[var(--color-text-muted)]">
61
+ <svg
62
+ xmlns="http://www.w3.org/2000/svg"
63
+ width="20"
64
+ height="20"
65
+ viewBox="0 0 24 24"
66
+ fill="none"
67
+ stroke="currentColor"
68
+ stroke-width="2"
69
+ stroke-linecap="round"
70
+ stroke-linejoin="round"
71
+ class="lucide lucide-search-icon lucide-search"
72
+ >
73
+ <path d="m21 21-4.34-4.34" />
74
+ <circle cx="11" cy="11" r="8" />
75
+ </svg>
76
+ </span>
77
+ {/snippet}
78
+
79
+ <Field
80
+ {label}
81
+ bind:value
82
+ {sz}
83
+ {variant}
84
+ type="search"
85
+ clearable={true}
86
+ {leading}
87
+ placeholder={placeholderFinal}
88
+ class={`search-input w-full max-w-[520px] [&_input]:pl-10 ${externalClass}`}
89
+ {...rest}
90
+ />
91
+
92
+ <style>
93
+ :global(.search-input input[type="search"]) {
94
+ -webkit-appearance: none;
95
+ appearance: none;
96
+ }
97
+
98
+ :global(.search-input input[type="search"]::-webkit-search-cancel-button),
99
+ :global(.search-input input[type="search"]::-webkit-search-decoration),
100
+ :global(.search-input input[type="search"]::-webkit-search-results-button),
101
+ :global(.search-input input[type="search"]::-webkit-search-results-decoration) {
102
+ -webkit-appearance: none;
103
+ appearance: none;
104
+ display: none;
105
+ }
106
+ </style>
@@ -0,0 +1,13 @@
1
+ import type { FieldVariant, SizeKey } from "./types";
2
+ type Props = {
3
+ label?: string;
4
+ placeholder?: string;
5
+ value?: string;
6
+ sz?: SizeKey;
7
+ variant?: FieldVariant;
8
+ class?: string;
9
+ [key: string]: unknown;
10
+ };
11
+ declare const SearchInput: import("svelte").Component<Props, {}, "value">;
12
+ type SearchInput = ReturnType<typeof SearchInput>;
13
+ export default SearchInput;
@@ -171,6 +171,13 @@
171
171
  const alignTd = (a?: CellAlign) =>
172
172
  a === "end" ? "text-right" : a === "start" ? "text-left" : "text-center";
173
173
 
174
+ const alignTh = (a?: CellAlign) =>
175
+ a === "end"
176
+ ? "justify-end"
177
+ : a === "center"
178
+ ? "justify-center"
179
+ : "justify-start";
180
+
174
181
  const wrapperClass = $derived(cx("overflow-x-auto", externalClass));
175
182
  const tableTextSize = $derived(TEXT[sz]);
176
183
  const currentVariant = $derived(variant);
@@ -225,7 +232,10 @@
225
232
  >
226
233
  <button
227
234
  type="button"
228
- class="flex items-center gap-2 select-none hover:bg-[var(--color-bg-hover)] rounded-none px-1 py-0.5 border border-transparent focus-visible:border-[var(--border-color-focus)] focus-visible:ring-2 focus-visible:ring-[var(--border-color-focus)] focus-visible:outline-none"
235
+ class={cx(
236
+ "flex w-full items-center gap-2 select-none hover:bg-[var(--color-bg-hover)] rounded-none px-1 py-0.5 border border-transparent focus-visible:border-[var(--border-color-focus)] focus-visible:ring-2 focus-visible:ring-[var(--border-color-focus)] focus-visible:outline-none",
237
+ alignTh(col.align)
238
+ )}
229
239
  onclick={() => toggleSort(col)}
230
240
  onkeydown={(e) => {
231
241
  if (e.key === "Enter" || e.key === " ") {
@@ -235,7 +245,9 @@
235
245
  }}
236
246
  aria-label={`Sort by ${col.label}`}
237
247
  >
238
- <span class="truncate min-w-0 text-left">{col.label}</span>
248
+ <span class={cx("truncate min-w-0", alignTd(col.align))}>
249
+ {col.label}
250
+ </span>
239
251
  <svg
240
252
  class={cx(
241
253
  "h-4 w-4 opacity-60 transition-transform",
@@ -63,7 +63,7 @@
63
63
  xl: "px-6 py-3 h-10",
64
64
  };
65
65
 
66
- const position = "fixed top-4 right-4";
66
+ const position = "fixed top-4 right-4 z-50";
67
67
 
68
68
  const mergedClass = $derived(
69
69
  cx(
@@ -18,6 +18,7 @@ export { default as PrimaryColorSelect } from "./PrimaryColorSelect.svelte";
18
18
  export { default as ProgressBar } from "./ProgressBar.svelte";
19
19
  export { default as ProgressCircle } from "./ProgressCircle.svelte";
20
20
  export { default as Radio } from "./Radio.svelte";
21
+ export { default as SearchInput } from "./SearchInput.svelte";
21
22
  export { default as Select } from "./Select.svelte";
22
23
  export { default as Slider } from "./Slider.svelte";
23
24
  export { default as Splitter } from "./Splitter.svelte";
package/dist/lib/index.js CHANGED
@@ -19,6 +19,7 @@ export { default as PrimaryColorSelect } from "./PrimaryColorSelect.svelte";
19
19
  export { default as ProgressBar } from "./ProgressBar.svelte";
20
20
  export { default as ProgressCircle } from "./ProgressCircle.svelte";
21
21
  export { default as Radio } from "./Radio.svelte";
22
+ export { default as SearchInput } from "./SearchInput.svelte";
22
23
  export { default as Select } from "./Select.svelte";
23
24
  export { default as Slider } from "./Slider.svelte";
24
25
  export { default as Splitter } from "./Splitter.svelte";
@@ -29,6 +29,9 @@ export declare const TEXTS: {
29
29
  readonly fileCount: "{n} file(s) selected";
30
30
  readonly totalSize: "Total size";
31
31
  };
32
+ readonly searchInput: {
33
+ readonly placeholder: "Search";
34
+ };
32
35
  readonly menu: {
33
36
  readonly subtitle: "Menu with size options";
34
37
  };
@@ -78,6 +81,9 @@ export declare const TEXTS: {
78
81
  readonly fileCount: "{n} файл(ов) выбрано";
79
82
  readonly totalSize: "Общий размер";
80
83
  };
84
+ readonly searchInput: {
85
+ readonly placeholder: "?????";
86
+ };
81
87
  readonly menu: {
82
88
  readonly subtitle: "Меню с вариантами размеров";
83
89
  };
@@ -127,6 +133,9 @@ export declare const TEXTS: {
127
133
  readonly fileCount: "{n} archivo(s) seleccionado(s)";
128
134
  readonly totalSize: "Tamaño total";
129
135
  };
136
+ readonly searchInput: {
137
+ readonly placeholder: "Buscar";
138
+ };
130
139
  readonly menu: {
131
140
  readonly subtitle: "Menú con opciones de tamaño";
132
141
  };
package/dist/lib/lang.js CHANGED
@@ -29,6 +29,9 @@ var enTexts = {
29
29
  fileCount: "{n} file(s) selected",
30
30
  totalSize: "Total size",
31
31
  },
32
+ searchInput: {
33
+ placeholder: "Search",
34
+ },
32
35
  menu: { subtitle: "Menu with size options" },
33
36
  primaryColorSelect: { text: "Primary color" },
34
37
  timePicker: {
@@ -74,6 +77,9 @@ var ruTexts = {
74
77
  fileCount: "{n} файл(ов) выбрано",
75
78
  totalSize: "Общий размер",
76
79
  },
80
+ searchInput: {
81
+ placeholder: "?????",
82
+ },
77
83
  menu: { subtitle: "Меню с вариантами размеров" },
78
84
  primaryColorSelect: { text: "Основной цвет" },
79
85
  timePicker: {
@@ -119,6 +125,9 @@ var esTexts = {
119
125
  fileCount: "{n} archivo(s) seleccionado(s)",
120
126
  totalSize: "Tamaño total",
121
127
  },
128
+ searchInput: {
129
+ placeholder: "Buscar",
130
+ },
122
131
  menu: { subtitle: "Menú con opciones de tamaño" },
123
132
  primaryColorSelect: { text: "Color primario" },
124
133
  timePicker: {
package/package.json CHANGED
@@ -1,4 +1,7 @@
1
1
  {
2
+ "name": "svelte-comp",
3
+ "version": "1.2.5",
4
+ "license": "MIT",
2
5
  "description": "A comprehensive component library built on Svelte 5 (runes) with design tokens (tailwind), accessibility focus, and TypeScript support",
3
6
  "devDependencies": {
4
7
  "@sveltejs/package": "^2.5.7",
@@ -34,8 +37,6 @@
34
37
  "tailwind",
35
38
  "ui-library"
36
39
  ],
37
- "license": "MIT",
38
- "name": "svelte-comp",
39
40
  "peerDependencies": {
40
41
  "svelte": "^5.0.0"
41
42
  },
@@ -46,6 +47,5 @@
46
47
  },
47
48
  "svelte": "./dist/lib/index.js",
48
49
  "type": "module",
49
- "types": "./dist/lib/index.d.ts",
50
- "version": "1.1.7"
50
+ "types": "./dist/lib/index.d.ts"
51
51
  }