bloko-ui 0.0.1

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 (74) hide show
  1. package/README.md +58 -0
  2. package/dist/components/Accordion.svelte +107 -0
  3. package/dist/components/Accordion.svelte.d.ts +14 -0
  4. package/dist/components/Alert.svelte +136 -0
  5. package/dist/components/Alert.svelte.d.ts +11 -0
  6. package/dist/components/Avatar.svelte +82 -0
  7. package/dist/components/Avatar.svelte.d.ts +9 -0
  8. package/dist/components/Badge.svelte +61 -0
  9. package/dist/components/Badge.svelte.d.ts +8 -0
  10. package/dist/components/Breadcrumb.svelte +74 -0
  11. package/dist/components/Breadcrumb.svelte.d.ts +10 -0
  12. package/dist/components/Button.svelte +114 -0
  13. package/dist/components/Button.svelte.d.ts +12 -0
  14. package/dist/components/Card.svelte +49 -0
  15. package/dist/components/Card.svelte.d.ts +9 -0
  16. package/dist/components/Checkbox.svelte +108 -0
  17. package/dist/components/Checkbox.svelte.d.ts +10 -0
  18. package/dist/components/ContextMenu.svelte +132 -0
  19. package/dist/components/ContextMenu.svelte.d.ts +17 -0
  20. package/dist/components/Divider.svelte +55 -0
  21. package/dist/components/Divider.svelte.d.ts +7 -0
  22. package/dist/components/Dropdown.svelte +156 -0
  23. package/dist/components/Dropdown.svelte.d.ts +17 -0
  24. package/dist/components/EmptyState.svelte +79 -0
  25. package/dist/components/EmptyState.svelte.d.ts +10 -0
  26. package/dist/components/IconButton.svelte +88 -0
  27. package/dist/components/IconButton.svelte.d.ts +12 -0
  28. package/dist/components/Input.svelte +87 -0
  29. package/dist/components/Input.svelte.d.ts +15 -0
  30. package/dist/components/LangValue.svelte +124 -0
  31. package/dist/components/LangValue.svelte.d.ts +8 -0
  32. package/dist/components/Modal.svelte +136 -0
  33. package/dist/components/Modal.svelte.d.ts +10 -0
  34. package/dist/components/NumberInput.svelte +143 -0
  35. package/dist/components/NumberInput.svelte.d.ts +12 -0
  36. package/dist/components/Pagination.svelte +83 -0
  37. package/dist/components/Pagination.svelte.d.ts +9 -0
  38. package/dist/components/Popover.svelte +95 -0
  39. package/dist/components/Popover.svelte.d.ts +9 -0
  40. package/dist/components/Progress.svelte +55 -0
  41. package/dist/components/Progress.svelte.d.ts +9 -0
  42. package/dist/components/RadioGroup.svelte +111 -0
  43. package/dist/components/RadioGroup.svelte.d.ts +15 -0
  44. package/dist/components/SearchInput.svelte +121 -0
  45. package/dist/components/SearchInput.svelte.d.ts +10 -0
  46. package/dist/components/Select.svelte +82 -0
  47. package/dist/components/Select.svelte.d.ts +15 -0
  48. package/dist/components/Sidebar.svelte +97 -0
  49. package/dist/components/Sidebar.svelte.d.ts +13 -0
  50. package/dist/components/Skeleton.svelte +47 -0
  51. package/dist/components/Skeleton.svelte.d.ts +9 -0
  52. package/dist/components/Spinner.svelte +58 -0
  53. package/dist/components/Spinner.svelte.d.ts +7 -0
  54. package/dist/components/Switch.svelte +102 -0
  55. package/dist/components/Switch.svelte.d.ts +9 -0
  56. package/dist/components/Table.svelte +78 -0
  57. package/dist/components/Table.svelte.d.ts +6 -0
  58. package/dist/components/Tabs.svelte +74 -0
  59. package/dist/components/Tabs.svelte.d.ts +12 -0
  60. package/dist/components/Tag.svelte +75 -0
  61. package/dist/components/Tag.svelte.d.ts +9 -0
  62. package/dist/components/Textarea.svelte +63 -0
  63. package/dist/components/Textarea.svelte.d.ts +11 -0
  64. package/dist/components/Toast.svelte +103 -0
  65. package/dist/components/Toast.svelte.d.ts +10 -0
  66. package/dist/components/Tooltip.svelte +75 -0
  67. package/dist/components/Tooltip.svelte.d.ts +9 -0
  68. package/dist/components/TopNav.svelte +72 -0
  69. package/dist/components/TopNav.svelte.d.ts +12 -0
  70. package/dist/components/TruncatedText.svelte +46 -0
  71. package/dist/components/TruncatedText.svelte.d.ts +9 -0
  72. package/dist/index.d.ts +35 -0
  73. package/dist/index.js +36 -0
  74. package/package.json +63 -0
@@ -0,0 +1,97 @@
1
+ <script lang="ts">
2
+ interface SidebarItem {
3
+ label: string;
4
+ href?: string;
5
+ count?: number;
6
+ active?: boolean;
7
+ }
8
+
9
+ interface Props {
10
+ title?: string;
11
+ items?: SidebarItem[];
12
+ }
13
+
14
+ let {
15
+ title = '',
16
+ items = []
17
+ }: Props = $props();
18
+ </script>
19
+
20
+ <aside class="sidebar">
21
+ {#if title}
22
+ <div class="sidebar-title">{title}</div>
23
+ {/if}
24
+ <ul class="sidebar-list">
25
+ {#each items as item}
26
+ <li>
27
+ <a href={item.href || '#'} class:active={item.active}>
28
+ <span class="label">{item.label}</span>
29
+ {#if item.count !== undefined}
30
+ <span class="count">{item.count}</span>
31
+ {/if}
32
+ </a>
33
+ </li>
34
+ {/each}
35
+ </ul>
36
+ </aside>
37
+
38
+ <style>
39
+ .sidebar {
40
+ width: 180px;
41
+ min-width: 180px;
42
+ background: #fafafa;
43
+ border-right: 1px solid #e2e2e2;
44
+ overflow-y: auto;
45
+ }
46
+
47
+ .sidebar-title {
48
+ padding: 8px 12px;
49
+ font-size: 10px;
50
+ font-weight: 600;
51
+ color: #a1a1aa;
52
+ text-transform: uppercase;
53
+ letter-spacing: 0.05em;
54
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
55
+ }
56
+
57
+ .sidebar-list {
58
+ list-style: none;
59
+ margin: 0;
60
+ padding: 0;
61
+ }
62
+
63
+ .sidebar-list a {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+ height: 28px;
68
+ padding: 0 12px;
69
+ font-size: 12px;
70
+ color: #52525b;
71
+ text-decoration: none;
72
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
73
+ transition: background 0.1s;
74
+ }
75
+
76
+ .sidebar-list a:hover {
77
+ background: #f4f4f5;
78
+ }
79
+
80
+ .sidebar-list a.active {
81
+ background: #e4e4e7;
82
+ color: #18181b;
83
+ font-weight: 500;
84
+ }
85
+
86
+ .label {
87
+ overflow: hidden;
88
+ text-overflow: ellipsis;
89
+ white-space: nowrap;
90
+ }
91
+
92
+ .count {
93
+ font-size: 10px;
94
+ color: #a1a1aa;
95
+ font-family: 'SF Mono', 'Fira Code', monospace;
96
+ }
97
+ </style>
@@ -0,0 +1,13 @@
1
+ interface SidebarItem {
2
+ label: string;
3
+ href?: string;
4
+ count?: number;
5
+ active?: boolean;
6
+ }
7
+ interface Props {
8
+ title?: string;
9
+ items?: SidebarItem[];
10
+ }
11
+ declare const Sidebar: import("svelte").Component<Props, {}, "">;
12
+ type Sidebar = ReturnType<typeof Sidebar>;
13
+ export default Sidebar;
@@ -0,0 +1,47 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ width?: string;
4
+ height?: string;
5
+ rounded?: boolean;
6
+ circle?: boolean;
7
+ }
8
+
9
+ let {
10
+ width = '100%',
11
+ height = '16px',
12
+ rounded = true,
13
+ circle = false
14
+ }: Props = $props();
15
+ </script>
16
+
17
+ <div
18
+ class="skeleton"
19
+ class:rounded
20
+ class:circle
21
+ style="width: {width}; height: {height};"
22
+ ></div>
23
+
24
+ <style>
25
+ .skeleton {
26
+ background: linear-gradient(90deg, #f4f4f5 25%, #e4e4e7 50%, #f4f4f5 75%);
27
+ background-size: 200% 100%;
28
+ animation: shimmer 1.5s infinite;
29
+ }
30
+
31
+ .skeleton.rounded {
32
+ border-radius: 4px;
33
+ }
34
+
35
+ .skeleton.circle {
36
+ border-radius: 50%;
37
+ }
38
+
39
+ @keyframes shimmer {
40
+ 0% {
41
+ background-position: 200% 0;
42
+ }
43
+ 100% {
44
+ background-position: -200% 0;
45
+ }
46
+ }
47
+ </style>
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ width?: string;
3
+ height?: string;
4
+ rounded?: boolean;
5
+ circle?: boolean;
6
+ }
7
+ declare const Skeleton: import("svelte").Component<Props, {}, "">;
8
+ type Skeleton = ReturnType<typeof Skeleton>;
9
+ export default Skeleton;
@@ -0,0 +1,58 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ size?: 'sm' | 'md' | 'lg';
4
+ label?: string;
5
+ }
6
+
7
+ let { size = 'sm', label }: Props = $props();
8
+ </script>
9
+
10
+ <div class="spinner-container">
11
+ <div class="spinner spinner-{size}"></div>
12
+ {#if label}
13
+ <span class="label">{label}</span>
14
+ {/if}
15
+ </div>
16
+
17
+ <style>
18
+ .spinner-container {
19
+ display: inline-flex;
20
+ align-items: center;
21
+ gap: 8px;
22
+ }
23
+
24
+ .spinner {
25
+ border: 2px solid #e2e2e2;
26
+ border-top-color: #18181b;
27
+ border-radius: 50%;
28
+ animation: spin 0.6s linear infinite;
29
+ }
30
+
31
+ .spinner-sm {
32
+ width: 14px;
33
+ height: 14px;
34
+ }
35
+
36
+ .spinner-md {
37
+ width: 20px;
38
+ height: 20px;
39
+ }
40
+
41
+ .spinner-lg {
42
+ width: 28px;
43
+ height: 28px;
44
+ border-width: 3px;
45
+ }
46
+
47
+ .label {
48
+ font-size: 12px;
49
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
50
+ color: #71717a;
51
+ }
52
+
53
+ @keyframes spin {
54
+ to {
55
+ transform: rotate(360deg);
56
+ }
57
+ }
58
+ </style>
@@ -0,0 +1,7 @@
1
+ interface Props {
2
+ size?: 'sm' | 'md' | 'lg';
3
+ label?: string;
4
+ }
5
+ declare const Spinner: import("svelte").Component<Props, {}, "">;
6
+ type Spinner = ReturnType<typeof Spinner>;
7
+ export default Spinner;
@@ -0,0 +1,102 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ checked?: boolean;
4
+ disabled?: boolean;
5
+ size?: 'sm' | 'md';
6
+ onchange?: (checked: boolean) => void;
7
+ }
8
+
9
+ let {
10
+ checked = $bindable(false),
11
+ disabled = false,
12
+ size = 'md',
13
+ onchange
14
+ }: Props = $props();
15
+
16
+ function toggle() {
17
+ if (disabled) return;
18
+ checked = !checked;
19
+ onchange?.(checked);
20
+ }
21
+
22
+ function handleKeydown(event: KeyboardEvent) {
23
+ if (event.key === ' ' || event.key === 'Enter') {
24
+ event.preventDefault();
25
+ toggle();
26
+ }
27
+ }
28
+ </script>
29
+
30
+ <button
31
+ type="button"
32
+ role="switch"
33
+ aria-checked={checked}
34
+ class="switch {size}"
35
+ class:checked
36
+ class:disabled
37
+ onclick={toggle}
38
+ onkeydown={handleKeydown}
39
+ {disabled}
40
+ >
41
+ <span class="thumb"></span>
42
+ </button>
43
+
44
+ <style>
45
+ .switch {
46
+ position: relative;
47
+ display: inline-flex;
48
+ align-items: center;
49
+ border: none;
50
+ border-radius: 999px;
51
+ background: #d4d4d8;
52
+ cursor: pointer;
53
+ transition: background-color 0.15s ease;
54
+ }
55
+
56
+ .switch.md {
57
+ width: 36px;
58
+ height: 20px;
59
+ }
60
+
61
+ .switch.sm {
62
+ width: 28px;
63
+ height: 16px;
64
+ }
65
+
66
+ .switch.checked {
67
+ background: #6366f1;
68
+ }
69
+
70
+ .switch.disabled {
71
+ opacity: 0.5;
72
+ cursor: not-allowed;
73
+ }
74
+
75
+ .thumb {
76
+ position: absolute;
77
+ background: white;
78
+ border-radius: 50%;
79
+ transition: transform 0.15s ease;
80
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
81
+ }
82
+
83
+ .switch.md .thumb {
84
+ width: 16px;
85
+ height: 16px;
86
+ left: 2px;
87
+ }
88
+
89
+ .switch.sm .thumb {
90
+ width: 12px;
91
+ height: 12px;
92
+ left: 2px;
93
+ }
94
+
95
+ .switch.md.checked .thumb {
96
+ transform: translateX(16px);
97
+ }
98
+
99
+ .switch.sm.checked .thumb {
100
+ transform: translateX(12px);
101
+ }
102
+ </style>
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ checked?: boolean;
3
+ disabled?: boolean;
4
+ size?: 'sm' | 'md';
5
+ onchange?: (checked: boolean) => void;
6
+ }
7
+ declare const Switch: import("svelte").Component<Props, {}, "checked">;
8
+ type Switch = ReturnType<typeof Switch>;
9
+ export default Switch;
@@ -0,0 +1,78 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ children?: import('svelte').Snippet;
4
+ }
5
+
6
+ let { children }: Props = $props();
7
+ </script>
8
+
9
+ <div class="table-wrapper">
10
+ <table class="table">
11
+ {#if children}
12
+ {@render children()}
13
+ {/if}
14
+ </table>
15
+ </div>
16
+
17
+ <style>
18
+ .table-wrapper {
19
+ overflow: auto;
20
+ border: 1px solid #e2e2e2;
21
+ border-radius: 4px;
22
+ background: white;
23
+ }
24
+
25
+ .table {
26
+ width: 100%;
27
+ border-collapse: collapse;
28
+ font-size: 12px;
29
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
30
+ }
31
+
32
+ :global(.table th) {
33
+ height: 28px;
34
+ padding: 0 12px;
35
+ text-align: left;
36
+ font-weight: 500;
37
+ color: #71717a;
38
+ background: #fafafa;
39
+ border-bottom: 1px solid #e2e2e2;
40
+ white-space: nowrap;
41
+ }
42
+
43
+ :global(.table td) {
44
+ height: 32px;
45
+ padding: 0 12px;
46
+ color: #333;
47
+ border-bottom: 1px solid #f4f4f5;
48
+ white-space: nowrap;
49
+ }
50
+
51
+ :global(.table tr:last-child td) {
52
+ border-bottom: none;
53
+ }
54
+
55
+ :global(.table tr:hover td) {
56
+ background: #fafafa;
57
+ }
58
+
59
+ :global(.table .mono) {
60
+ font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;
61
+ font-size: 11px;
62
+ color: #71717a;
63
+ }
64
+
65
+ :global(.table .truncate) {
66
+ max-width: 200px;
67
+ overflow: hidden;
68
+ text-overflow: ellipsis;
69
+ }
70
+
71
+ :global(.table .editable) {
72
+ cursor: pointer;
73
+ }
74
+
75
+ :global(.table .editable:hover) {
76
+ background: #f0f4ff;
77
+ }
78
+ </style>
@@ -0,0 +1,6 @@
1
+ interface Props {
2
+ children?: import('svelte').Snippet;
3
+ }
4
+ declare const Table: import("svelte").Component<Props, {}, "">;
5
+ type Table = ReturnType<typeof Table>;
6
+ export default Table;
@@ -0,0 +1,74 @@
1
+ <script lang="ts">
2
+ interface Tab {
3
+ id: string;
4
+ label: string;
5
+ }
6
+
7
+ interface Props {
8
+ tabs: Tab[];
9
+ active?: string;
10
+ onchange?: (id: string) => void;
11
+ }
12
+
13
+ let {
14
+ tabs,
15
+ active = $bindable(tabs[0]?.id ?? ''),
16
+ onchange
17
+ }: Props = $props();
18
+
19
+ function handleClick(id: string) {
20
+ active = id;
21
+ onchange?.(id);
22
+ }
23
+ </script>
24
+
25
+ <div class="tabs">
26
+ {#each tabs as tab}
27
+ <button
28
+ class="tab"
29
+ class:active={active === tab.id}
30
+ onclick={() => handleClick(tab.id)}
31
+ >
32
+ {tab.label}
33
+ </button>
34
+ {/each}
35
+ </div>
36
+
37
+ <style>
38
+ .tabs {
39
+ display: flex;
40
+ gap: 0;
41
+ border-bottom: 1px solid #e2e2e2;
42
+ }
43
+
44
+ .tab {
45
+ padding: 8px 16px;
46
+ border: none;
47
+ background: none;
48
+ font-size: 12px;
49
+ font-weight: 500;
50
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
51
+ color: #71717a;
52
+ cursor: pointer;
53
+ position: relative;
54
+ transition: color 0.1s;
55
+ }
56
+
57
+ .tab:hover {
58
+ color: #18181b;
59
+ }
60
+
61
+ .tab.active {
62
+ color: #18181b;
63
+ }
64
+
65
+ .tab.active::after {
66
+ content: '';
67
+ position: absolute;
68
+ bottom: -1px;
69
+ left: 0;
70
+ right: 0;
71
+ height: 2px;
72
+ background: #18181b;
73
+ }
74
+ </style>
@@ -0,0 +1,12 @@
1
+ interface Tab {
2
+ id: string;
3
+ label: string;
4
+ }
5
+ interface Props {
6
+ tabs: Tab[];
7
+ active?: string;
8
+ onchange?: (id: string) => void;
9
+ }
10
+ declare const Tabs: import("svelte").Component<Props, {}, "active">;
11
+ type Tabs = ReturnType<typeof Tabs>;
12
+ export default Tabs;
@@ -0,0 +1,75 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ label: string;
4
+ removable?: boolean;
5
+ variant?: 'default' | 'primary' | 'success' | 'warning' | 'error';
6
+ onremove?: () => void;
7
+ }
8
+
9
+ let { label, removable = false, variant = 'default', onremove }: Props = $props();
10
+ </script>
11
+
12
+ <span class="tag {variant}">
13
+ {label}
14
+ {#if removable}
15
+ <button class="remove" onclick={onremove} aria-label="Remove {label}">
16
+ <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
17
+ <path d="M18 6L6 18M6 6l12 12" />
18
+ </svg>
19
+ </button>
20
+ {/if}
21
+ </span>
22
+
23
+ <style>
24
+ .tag {
25
+ display: inline-flex;
26
+ align-items: center;
27
+ gap: 4px;
28
+ padding: 3px 8px;
29
+ font-size: 11px;
30
+ font-weight: 500;
31
+ border-radius: 4px;
32
+ }
33
+
34
+ .tag.default {
35
+ background: #f4f4f5;
36
+ color: #3f3f46;
37
+ }
38
+
39
+ .tag.primary {
40
+ background: #eef2ff;
41
+ color: #4f46e5;
42
+ }
43
+
44
+ .tag.success {
45
+ background: #f0fdf4;
46
+ color: #16a34a;
47
+ }
48
+
49
+ .tag.warning {
50
+ background: #fffbeb;
51
+ color: #d97706;
52
+ }
53
+
54
+ .tag.error {
55
+ background: #fef2f2;
56
+ color: #dc2626;
57
+ }
58
+
59
+ .remove {
60
+ display: inline-flex;
61
+ align-items: center;
62
+ justify-content: center;
63
+ padding: 0;
64
+ margin-left: 2px;
65
+ background: none;
66
+ border: none;
67
+ cursor: pointer;
68
+ opacity: 0.6;
69
+ transition: opacity 0.15s;
70
+ }
71
+
72
+ .remove:hover {
73
+ opacity: 1;
74
+ }
75
+ </style>
@@ -0,0 +1,9 @@
1
+ interface Props {
2
+ label: string;
3
+ removable?: boolean;
4
+ variant?: 'default' | 'primary' | 'success' | 'warning' | 'error';
5
+ onremove?: () => void;
6
+ }
7
+ declare const Tag: import("svelte").Component<Props, {}, "">;
8
+ type Tag = ReturnType<typeof Tag>;
9
+ export default Tag;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ interface Props {
3
+ value?: string;
4
+ placeholder?: string;
5
+ rows?: number;
6
+ disabled?: boolean;
7
+ resize?: 'none' | 'vertical' | 'horizontal' | 'both';
8
+ onchange?: (value: string) => void;
9
+ }
10
+
11
+ let {
12
+ value = $bindable(''),
13
+ placeholder = '',
14
+ rows = 3,
15
+ disabled = false,
16
+ resize = 'vertical',
17
+ onchange
18
+ }: Props = $props();
19
+
20
+ function handleInput(event: Event) {
21
+ const target = event.target as HTMLTextAreaElement;
22
+ value = target.value;
23
+ onchange?.(value);
24
+ }
25
+ </script>
26
+
27
+ <textarea
28
+ class="textarea"
29
+ {placeholder}
30
+ {rows}
31
+ {disabled}
32
+ style="resize: {resize}"
33
+ oninput={handleInput}
34
+ >{value}</textarea>
35
+
36
+ <style>
37
+ .textarea {
38
+ width: 100%;
39
+ padding: 8px 10px;
40
+ font-size: 12px;
41
+ font-family: inherit;
42
+ color: #18181b;
43
+ background: white;
44
+ border: 1px solid #e4e4e7;
45
+ border-radius: 4px;
46
+ outline: none;
47
+ transition: border-color 0.15s ease;
48
+ }
49
+
50
+ .textarea::placeholder {
51
+ color: #a1a1aa;
52
+ }
53
+
54
+ .textarea:focus {
55
+ border-color: #6366f1;
56
+ }
57
+
58
+ .textarea:disabled {
59
+ background: #fafafa;
60
+ color: #a1a1aa;
61
+ cursor: not-allowed;
62
+ }
63
+ </style>
@@ -0,0 +1,11 @@
1
+ interface Props {
2
+ value?: string;
3
+ placeholder?: string;
4
+ rows?: number;
5
+ disabled?: boolean;
6
+ resize?: 'none' | 'vertical' | 'horizontal' | 'both';
7
+ onchange?: (value: string) => void;
8
+ }
9
+ declare const Textarea: import("svelte").Component<Props, {}, "value">;
10
+ type Textarea = ReturnType<typeof Textarea>;
11
+ export default Textarea;