svelte-comp 1.0.7 → 1.1.2

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.
@@ -1,4 +1,4 @@
1
- <!-- src/lib/Select.svelte -->
1
+ <!-- src/lib/Select.svelte -->
2
2
  <script lang="ts">
3
3
  /**
4
4
  * @component Select
@@ -167,6 +167,8 @@
167
167
  `position:fixed;top:${menuTop}px;left:${menuLeft}px;min-width:${menuWidth}px;max-height:${menuMaxHeight}px;`
168
168
  );
169
169
 
170
+ const selectedOption = $derived(options.find((o) => o.value === value));
171
+
170
172
  $effect(() => {
171
173
  const currentTriggerEl = triggerEl;
172
174
  const currentListEl = listEl;
@@ -409,14 +411,25 @@
409
411
  onkeydown={onTriggerKeydown}
410
412
  >
411
413
  <span class="min-w-0 grow truncate">
412
- {#if value}
413
- {options.find((o) => o.value === value)?.label}
414
+ {#if selectedOption}
415
+ <span class="inline-flex items-center gap-2 min-w-0">
416
+ {#if selectedOption.swatch}
417
+ <span
418
+ aria-hidden="true"
419
+ class="block w-3 h-3 rounded-[var(--radius-xs)] border border-[var(--border-color-default)] shadow-sm shrink-0"
420
+ style={`background:${selectedOption.swatch}`}
421
+ ></span>
422
+ {/if}
423
+ <span class="truncate">{selectedOption.label}</span>
424
+ </span>
414
425
  {:else}
415
426
  <span class="[color:var(--color-text-muted)]">{placeholder}</span>
416
427
  {/if}
417
428
  </span>
418
429
  <span
419
- class={cx("pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 [color:var(--color-text-default)]")}
430
+ class={cx(
431
+ "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 [color:var(--color-text-default)]"
432
+ )}
420
433
  >
421
434
  <svg
422
435
  class={iconsSizes[sz]}
@@ -470,13 +483,22 @@
470
483
  <button
471
484
  type="button"
472
485
  tabindex="0"
473
- class={cx("w-full text-left focus:outline-[3px] focus:outline-offset-3 focus:outline-[var(--border-color-focus)] rounded")}
486
+ class={cx(
487
+ "w-full text-left focus:outline-[3px] focus:outline-offset-3 focus:outline-[var(--border-color-focus)] rounded flex items-center gap-2"
488
+ )}
474
489
  disabled={opt.disabled}
475
490
  onclick={() => choose(i)}
476
491
  onfocus={() => (highlighted = i)}
477
492
  onmouseenter={() => (highlighted = i)}
478
493
  >
479
- {opt.label}
494
+ {#if opt.swatch}
495
+ <span
496
+ aria-hidden="true"
497
+ class="block w-3 h-3 rounded-[var(--radius-xs)] border border-[var(--border-color-default)] shadow-sm shrink-0"
498
+ style={`background:${opt.swatch}`}
499
+ ></span>
500
+ {/if}
501
+ <span class="truncate">{opt.label}</span>
480
502
  </button>
481
503
  </li>
482
504
  {/each}
@@ -1,4 +1,4 @@
1
- <!-- src/lib/Splitter.svelte -->
1
+ <!-- src/lib/Splitter.svelte -->
2
2
  <script lang="ts">
3
3
  /**
4
4
  * @component Splitter
@@ -203,7 +203,7 @@
203
203
  String(col.key ?? idx);
204
204
  </script>
205
205
 
206
- <div class={wrapperClass}>
206
+ <div class={wrapperClass} tabindex="-1">
207
207
  <table class={tableClass}>
208
208
  <thead class={variantStyles.header}>
209
209
  {#if currentVariant !== "noTitle" && currentVariant !== "list"}
@@ -67,6 +67,14 @@
67
67
  activeTab = tabs[0].id;
68
68
  }
69
69
  });
70
+
71
+ function focusActiveButton() {
72
+ if (!activeTab) return;
73
+ const btn = document.getElementById(
74
+ `tab-${activeTab}`
75
+ ) as HTMLButtonElement | null;
76
+ btn?.focus();
77
+ }
70
78
 
71
79
  function handleTabClick(tab: TabItem) {
72
80
  if (tab.disabled) return;
@@ -95,12 +103,7 @@
95
103
  const nextId = enabled[next].id;
96
104
  activeTab = nextId;
97
105
  onChange?.(nextId);
98
- queueMicrotask(() => {
99
- const btn = document.getElementById(
100
- `tab-${nextId}`
101
- ) as HTMLButtonElement | null;
102
- btn?.focus();
103
- });
106
+ queueMicrotask(focusActiveButton);
104
107
  }
105
108
 
106
109
  const sizes: Record<SizeKey, string> = {
@@ -112,7 +115,7 @@
112
115
  };
113
116
 
114
117
  const base =
115
- "inline-flex items-center justify-center font-medium transition-colors duration-150 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--border-color-focus)] focus-visible:outline-offset-2 disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed";
118
+ "inline-flex items-center justify-center font-medium transition-colors duration-150 focus-visible:ring-inset focus-visible:ring-2 focus-visible:ring-[var(--border-color-focus)] focus-visible:ring-offset-0 focus:outline-none disabled:opacity-[var(--opacity-disabled)] disabled:cursor-not-allowed";
116
119
 
117
120
  const variants = $derived({
118
121
  default: {
@@ -160,6 +163,7 @@
160
163
  aria-orientation="horizontal"
161
164
  class={tablistClass}
162
165
  onkeydown={handleKeyDown}
166
+ onfocus={focusActiveButton}
163
167
  >
164
168
  {#each tabs as tab (tab.id)}
165
169
  <button
@@ -200,7 +204,7 @@
200
204
  <div
201
205
  id={`panel-${activeTab}`}
202
206
  role="tabpanel"
203
- tabindex="0"
207
+ tabindex="-1"
204
208
  aria-labelledby={`tab-${activeTab}`}
205
209
  class="w-full min-w-0 relative z-0 border-t border-[var(--border-color-default)] bg-[var(--color-bg-surface)] p-[var(--spacing-md)] rounded-b-[var(--radius-sm)] shadow-[0_1px_2px_0_var(--shadow-color)]"
206
210
  >
@@ -14,7 +14,9 @@ export { default as Hamburger } from "./Hamburger.svelte";
14
14
  export { default as Menu } from "./Menu.svelte";
15
15
  export { default as PaginatedCard } from "./PaginatedCard.svelte";
16
16
  export { default as Pagination } from "./Pagination.svelte";
17
+ export { default as PrimaryColorSelect } from "./PrimaryColorSelect.svelte";
17
18
  export { default as ProgressBar } from "./ProgressBar.svelte";
19
+ export { default as ProgressCircle } from "./ProgressCircle.svelte";
18
20
  export { default as Radio } from "./Radio.svelte";
19
21
  export { default as Select } from "./Select.svelte";
20
22
  export { default as Slider } from "./Slider.svelte";
package/dist/lib/index.js CHANGED
@@ -15,7 +15,9 @@ export { default as Hamburger } from "./Hamburger.svelte";
15
15
  export { default as Menu } from "./Menu.svelte";
16
16
  export { default as PaginatedCard } from "./PaginatedCard.svelte";
17
17
  export { default as Pagination } from "./Pagination.svelte";
18
+ export { default as PrimaryColorSelect } from "./PrimaryColorSelect.svelte";
18
19
  export { default as ProgressBar } from "./ProgressBar.svelte";
20
+ export { default as ProgressCircle } from "./ProgressCircle.svelte";
19
21
  export { default as Radio } from "./Radio.svelte";
20
22
  export { default as Select } from "./Select.svelte";
21
23
  export { default as Slider } from "./Slider.svelte";
@@ -32,6 +32,9 @@ export declare const TEXTS: {
32
32
  readonly menu: {
33
33
  readonly subtitle: "Menu with size options";
34
34
  };
35
+ readonly primaryColorSelect: {
36
+ readonly text: "Primary color";
37
+ };
35
38
  readonly timePicker: {
36
39
  readonly text: "Choose time";
37
40
  readonly placeholder: "No time selected";
@@ -78,6 +81,9 @@ export declare const TEXTS: {
78
81
  readonly menu: {
79
82
  readonly subtitle: "Меню с опциями размеров";
80
83
  };
84
+ readonly primaryColorSelect: {
85
+ readonly text: "Основной цвет";
86
+ };
81
87
  readonly timePicker: {
82
88
  readonly text: "Выбрать время";
83
89
  readonly placeholder: "Время не выбрано";
@@ -124,6 +130,9 @@ export declare const TEXTS: {
124
130
  readonly menu: {
125
131
  readonly subtitle: "Menú con opciones de tamaño";
126
132
  };
133
+ readonly primaryColorSelect: {
134
+ readonly text: "Color primario";
135
+ };
127
136
  readonly timePicker: {
128
137
  readonly text: "Elegir hora";
129
138
  readonly placeholder: "Ninguna hora seleccionada";
package/dist/lib/lang.js CHANGED
@@ -30,6 +30,7 @@ var enTexts = {
30
30
  totalSize: "Total size",
31
31
  },
32
32
  menu: { subtitle: "Menu with size options" },
33
+ primaryColorSelect: { text: "Primary color" },
33
34
  timePicker: {
34
35
  text: "Choose time",
35
36
  placeholder: "No time selected",
@@ -74,6 +75,7 @@ var ruTexts = {
74
75
  totalSize: "Общий размер",
75
76
  },
76
77
  menu: { subtitle: "Меню с опциями размеров" },
78
+ primaryColorSelect: { text: "Основной цвет" },
77
79
  timePicker: {
78
80
  text: "Выбрать время",
79
81
  placeholder: "Время не выбрано",
@@ -118,6 +120,7 @@ var esTexts = {
118
120
  totalSize: "Tamaño total",
119
121
  },
120
122
  menu: { subtitle: "Menú con opciones de tamaño" },
123
+ primaryColorSelect: { text: "Color primario" },
121
124
  timePicker: {
122
125
  text: "Elegir hora",
123
126
  placeholder: "Ninguna hora seleccionada",
@@ -83,6 +83,7 @@ export type SelectOption = {
83
83
  label: string;
84
84
  value: string;
85
85
  disabled?: boolean;
86
+ swatch?: string;
86
87
  };
87
88
  export type Position = "top" | "bottom" | "left" | "right";
88
89
  export type ToastVariant = "success" | "danger" | "warning" | "info";
@@ -102,3 +103,9 @@ export type FieldType = {
102
103
  invalid?: boolean;
103
104
  describedBy?: string;
104
105
  };
106
+ export type PrimaryKey = "default" | "cyan" | "red" | "green" | "yellow" | "pink" | "orange" | "purple";
107
+ export type PaletteOption = {
108
+ value: PrimaryKey;
109
+ label: string;
110
+ swatch: string;
111
+ };
package/dist/main.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import "./app.css";
2
+ import "./styles.css";
3
+ declare const app: {};
4
+ export default app;
package/dist/main.js ADDED
@@ -0,0 +1,8 @@
1
+ import { mount } from "svelte";
2
+ import "./app.css";
3
+ import "./styles.css";
4
+ import App from "./App.svelte";
5
+ var app = mount(App, {
6
+ target: document.getElementById("app"),
7
+ });
8
+ export default app;
package/dist/styles.css CHANGED
@@ -1,5 +1,6 @@
1
- /* src/app.css */
1
+ /* src/styles.css */
2
2
  @source "../node_modules/svelte-comp/**/*";
3
+
3
4
  @custom-variant dark (&:where(.dark, .dark *));
4
5
 
5
6
  @theme {
@@ -16,6 +17,7 @@
16
17
  --color-bg-page: oklch(98% 0 0deg);
17
18
  --color-bg-surface: oklch(100% 0 0deg);
18
19
  --color-bg-primary: oklch(62.3% 0.214 259.8deg);
20
+ --color-primary: var(--color-bg-primary);
19
21
  --color-bg-secondary: oklch(80% 0 0deg);
20
22
  --color-bg-danger: oklch(60% 0.25 30deg);
21
23
  --color-bg-success: oklch(55% 0.2 150deg);
@@ -108,6 +110,7 @@
108
110
  --color-bg-page: oklch(15% 0 0deg);
109
111
  --color-bg-surface: oklch(26% 0 0deg);
110
112
  --color-bg-primary: oklch(42% 0.19 259.8deg);
113
+ --color-primary: var(--color-bg-primary);
111
114
  --color-bg-secondary: oklch(45% 0 0deg);
112
115
  --color-bg-danger: oklch(50% 0.25 30deg);
113
116
  --color-bg-success: oklch(45% 0.2 150deg);
@@ -167,3 +170,63 @@
167
170
  .dark ::-webkit-scrollbar-thumb {
168
171
  background: oklch(from var(--color-bg-secondary) l c h / 0.7);
169
172
  }
173
+
174
+ /* ----------------------------- */
175
+ /* 🎨 Primary color palettes */
176
+ /* ----------------------------- */
177
+
178
+ [data-primary="default"] {
179
+ --color-primary: oklch(62.3% 0.214 259.8deg);
180
+ --color-bg-primary: var(--color-primary);
181
+ --border-color-primary: var(--color-primary);
182
+ --border-color-focus: var(--color-primary);
183
+ }
184
+
185
+ [data-primary="cyan"] {
186
+ --color-primary: oklch(86.5% 0.127 207.078);
187
+ --color-bg-primary: var(--color-primary);
188
+ --border-color-primary: var(--color-primary);
189
+ --border-color-focus: var(--color-primary);
190
+ }
191
+
192
+ [data-primary="red"] {
193
+ --color-primary: oklch(58% 0.24 30deg);
194
+ --color-bg-primary: var(--color-primary);
195
+ --border-color-primary: var(--color-primary);
196
+ --border-color-focus: var(--color-primary);
197
+ }
198
+
199
+ [data-primary="green"] {
200
+ --color-primary: oklch(65% 0.22 140deg);
201
+ --color-bg-primary: var(--color-primary);
202
+ --border-color-primary: var(--color-primary);
203
+ --border-color-focus: var(--color-primary);
204
+ }
205
+
206
+ [data-primary="yellow"] {
207
+ --color-primary: oklch(75% 0.18 90deg);
208
+ --color-bg-primary: var(--color-primary);
209
+ --border-color-primary: var(--color-primary);
210
+ --border-color-focus: var(--color-primary);
211
+ }
212
+
213
+ [data-primary="pink"] {
214
+ --color-primary: oklch(70% 0.25 350deg);
215
+ --color-bg-primary: var(--color-primary);
216
+ --border-color-primary: var(--color-primary);
217
+ --border-color-focus: var(--color-primary);
218
+ }
219
+
220
+ [data-primary="orange"] {
221
+ --color-primary: oklch(72% 0.22 60deg);
222
+ --color-bg-primary: var(--color-primary);
223
+ --border-color-primary: var(--color-primary);
224
+ --border-color-focus: var(--color-primary);
225
+ }
226
+
227
+ [data-primary="purple"] {
228
+ --color-primary: oklch(55% 0.22 290deg);
229
+ --color-bg-primary: var(--color-primary);
230
+ --border-color-primary: var(--color-primary);
231
+ --border-color-focus: var(--color-primary);
232
+ }
package/package.json CHANGED
@@ -1,14 +1,18 @@
1
1
  {
2
- "dependencies": {
3
- "prismjs": "^1.30.0"
4
- },
5
2
  "description": "A comprehensive component library built on Svelte 5 (runes) with design tokens (tailwind), accessibility focus, and TypeScript support",
6
3
  "devDependencies": {
7
4
  "@sveltejs/package": "^2.5.7",
8
5
  "@sveltejs/vite-plugin-svelte": "^6.2.1",
6
+ "@tailwindcss/vite": "^4.1.17",
9
7
  "@tsconfig/svelte": "^5.0.4",
10
8
  "@types/node": "^24.5.2",
9
+ "@types/prismjs": "^1.26.5",
10
+ "prettier": "^3.7.4",
11
+ "prettier-plugin-svelte": "^3.4.0",
12
+ "prismjs": "^1.30.0",
11
13
  "svelte": "^5.39.6",
14
+ "svelte-check": "^4.3.4",
15
+ "tailwindcss": "^4.1.17",
12
16
  "typescript": "^5.9.3",
13
17
  "vite": "^7.2.1"
14
18
  },
@@ -38,10 +42,10 @@
38
42
  "scripts": {
39
43
  "build": "svelte-package --input src",
40
44
  "dev": "vite",
41
- "prepare": "npm run build"
45
+ "check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
42
46
  },
43
47
  "svelte": "./dist/lib/index.js",
44
48
  "type": "module",
45
49
  "types": "./dist/lib/index.d.ts",
46
- "version": "1.0.7"
50
+ "version": "1.1.2"
47
51
  }