seblify 0.1.7 → 0.2.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.
@@ -1,56 +1,56 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- type BannerTone = 'info' | 'success' | 'warning' | 'error';
5
-
6
- interface Props {
7
- children?: Snippet;
8
- tone?: BannerTone;
9
- }
10
-
11
- let { children, tone = 'info' }: Props = $props();
12
- </script>
13
-
14
- <section
15
- class="banner"
16
- class:success={tone === 'success'}
17
- class:warning={tone === 'warning'}
18
- class:error={tone === 'error'}
19
- >
20
- <div class="content">
21
- {@render children?.()}
22
- </div>
23
- </section>
24
-
25
- <style>
26
- .banner {
27
- width: 100%;
28
- border-bottom: 1px solid var(--seblify-color-info-border, #bfd1ea);
29
- background: var(--seblify-color-info-surface, #eaf3ff);
30
- color: var(--seblify-color-info-text, #102f55);
31
- }
32
-
33
- .content {
34
- padding: 10px 16px;
35
- font-size: 14px;
36
- line-height: 1.4;
37
- }
38
-
39
- .success {
40
- border-bottom-color: var(--seblify-color-success-border, #b8ddc7);
41
- background: var(--seblify-color-success-surface, #e8f8ee);
42
- color: var(--seblify-color-success-text, #143d25);
43
- }
44
-
45
- .warning {
46
- border-bottom-color: var(--seblify-color-warning-border, #e8d28f);
47
- background: var(--seblify-color-warning-surface, #fff6d8);
48
- color: var(--seblify-color-warning-text, #4d3900);
49
- }
50
-
51
- .error {
52
- border-bottom-color: var(--seblify-color-error-border, #efb6b6);
53
- background: var(--seblify-color-error-surface, #fff0f0);
54
- color: var(--seblify-color-error-text, #5a1717);
55
- }
56
- </style>
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ type BannerTone = 'info' | 'success' | 'warning' | 'error';
5
+
6
+ interface Props {
7
+ children?: Snippet;
8
+ tone?: BannerTone;
9
+ }
10
+
11
+ let { children, tone = 'info' }: Props = $props();
12
+ </script>
13
+
14
+ <section
15
+ class="banner"
16
+ class:success={tone === 'success'}
17
+ class:warning={tone === 'warning'}
18
+ class:error={tone === 'error'}
19
+ >
20
+ <div class="content">
21
+ {@render children?.()}
22
+ </div>
23
+ </section>
24
+
25
+ <style>
26
+ .banner {
27
+ width: 100%;
28
+ border-bottom: 1px solid var(--seblify-color-info-border, #bfd1ea);
29
+ background: var(--seblify-color-info-surface, #eaf3ff);
30
+ color: var(--seblify-color-info-text, #102f55);
31
+ }
32
+
33
+ .content {
34
+ padding: 10px 16px;
35
+ font-size: 14px;
36
+ line-height: 1.4;
37
+ }
38
+
39
+ .success {
40
+ border-bottom-color: var(--seblify-color-success-border, #b8ddc7);
41
+ background: var(--seblify-color-success-surface, #e8f8ee);
42
+ color: var(--seblify-color-success-text, #143d25);
43
+ }
44
+
45
+ .warning {
46
+ border-bottom-color: var(--seblify-color-warning-border, #e8d28f);
47
+ background: var(--seblify-color-warning-surface, #fff6d8);
48
+ color: var(--seblify-color-warning-text, #4d3900);
49
+ }
50
+
51
+ .error {
52
+ border-bottom-color: var(--seblify-color-error-border, #efb6b6);
53
+ background: var(--seblify-color-error-surface, #fff0f0);
54
+ color: var(--seblify-color-error-text, #5a1717);
55
+ }
56
+ </style>
@@ -1,64 +1,64 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- type ButtonVariant = 'primary' | 'secondary';
5
- type ButtonType = 'button' | 'submit' | 'reset';
6
-
7
- interface Props {
8
- children?: Snippet;
9
- disabled?: boolean;
10
- onclick?: (event: MouseEvent) => void;
11
- type?: ButtonType;
12
- variant?: ButtonVariant;
13
- }
14
-
15
- let {
16
- children,
17
- disabled = false,
18
- onclick,
19
- type = 'button',
20
- variant = 'primary',
21
- }: Props = $props();
22
- </script>
23
-
24
- <button {disabled} {onclick} {type} class:secondary={variant === 'secondary'}>
25
- {@render children?.()}
26
- </button>
27
-
28
- <style>
29
- button {
30
- min-height: 36px;
31
- border: 1px solid var(--seblify-color-fill-accent, #146a6f);
32
- border-radius: 6px;
33
- padding: 0 14px;
34
- background: var(--seblify-color-fill-accent, #146a6f);
35
- color: var(--seblify-color-fill-accent-text, #ffffff);
36
- font: inherit;
37
- font-weight: 600;
38
- cursor: pointer;
39
- }
40
-
41
- button:hover:not(:disabled) {
42
- background: var(--seblify-color-fill-accent-hover, #0d4d52);
43
- }
44
-
45
- button:focus-visible {
46
- outline: 3px solid var(--seblify-color-focus-ring, #9bd4d8);
47
- outline-offset: 2px;
48
- }
49
-
50
- button:disabled {
51
- cursor: not-allowed;
52
- opacity: var(--seblify-opacity-disabled, 0.56);
53
- }
54
-
55
- .secondary {
56
- border-color: var(--seblify-color-border, #c8d2df);
57
- background: var(--seblify-color-surface, #ffffff);
58
- color: var(--seblify-color-text, #172033);
59
- }
60
-
61
- .secondary:hover:not(:disabled) {
62
- background: var(--seblify-color-surface-hover, #f1f4f9);
63
- }
64
- </style>
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ type ButtonVariant = 'primary' | 'secondary';
5
+ type ButtonType = 'button' | 'submit' | 'reset';
6
+
7
+ interface Props {
8
+ children?: Snippet;
9
+ disabled?: boolean;
10
+ onclick?: (event: MouseEvent) => void;
11
+ type?: ButtonType;
12
+ variant?: ButtonVariant;
13
+ }
14
+
15
+ let {
16
+ children,
17
+ disabled = false,
18
+ onclick,
19
+ type = 'button',
20
+ variant = 'primary',
21
+ }: Props = $props();
22
+ </script>
23
+
24
+ <button {disabled} {onclick} {type} class:secondary={variant === 'secondary'}>
25
+ {@render children?.()}
26
+ </button>
27
+
28
+ <style>
29
+ button {
30
+ min-height: 36px;
31
+ border: 1px solid var(--seblify-color-fill-accent, #146a6f);
32
+ border-radius: 6px;
33
+ padding: 0 14px;
34
+ background: var(--seblify-color-fill-accent, #146a6f);
35
+ color: var(--seblify-color-fill-accent-text, #ffffff);
36
+ font: inherit;
37
+ font-weight: 600;
38
+ cursor: pointer;
39
+ }
40
+
41
+ button:hover:not(:disabled) {
42
+ background: var(--seblify-color-fill-accent-hover, #0d4d52);
43
+ }
44
+
45
+ button:focus-visible {
46
+ outline: 3px solid var(--seblify-color-focus-ring, #9bd4d8);
47
+ outline-offset: 2px;
48
+ }
49
+
50
+ button:disabled {
51
+ cursor: not-allowed;
52
+ opacity: var(--seblify-opacity-disabled, 0.56);
53
+ }
54
+
55
+ .secondary {
56
+ border-color: var(--seblify-color-border, #c8d2df);
57
+ background: var(--seblify-color-surface, #ffffff);
58
+ color: var(--seblify-color-text, #172033);
59
+ }
60
+
61
+ .secondary:hover:not(:disabled) {
62
+ background: var(--seblify-color-surface-hover, #f1f4f9);
63
+ }
64
+ </style>
@@ -1,67 +1,67 @@
1
- <script lang="ts">
2
- const iconModules = import.meta.glob("../icons/**/*.svg", {
3
- eager: true,
4
- import: "default"
5
- });
6
-
7
- interface Props {
8
- alt?: string;
9
- name?: string;
10
- size?: number;
11
- }
12
-
13
- let { alt = "", name = "", size = 24 }: Props = $props();
14
-
15
- function normalizeNameToPath(value: unknown): string | null {
16
- const safe = typeof value === "string" ? value.trim() : "";
17
-
18
- if (safe.length === 0) {
19
- return null;
20
- }
21
-
22
- const parts = safe.split("-").filter((part) => part.length > 0);
23
-
24
- if (parts.length < 2) {
25
- return null;
26
- }
27
-
28
- const folder = parts[0];
29
- const file = parts.slice(1).join("-");
30
-
31
- return `../icons/${folder}/${file}.svg`;
32
- }
33
-
34
- let groupedPath = $derived(normalizeNameToPath(name));
35
- let iconPath = $derived(
36
- (groupedPath != null ? iconModules[groupedPath] : undefined) ??
37
- iconModules[`../icons/${name}.svg`] ??
38
- ""
39
- );
40
- </script>
41
-
42
- {#if iconPath}
43
- <span
44
- role={alt ? "img" : undefined}
45
- aria-label={alt || undefined}
46
- aria-hidden={alt ? undefined : "true"}
47
- style:--icon-url={`url('${iconPath}')`}
48
- style:width={`${size / 16}rem`}
49
- style:height={`${size / 16}rem`}
50
- ></span>
51
- {/if}
52
-
53
- <style>
54
- span {
55
- display: inline-block;
56
- flex: 0 0 auto;
57
- background-color: currentColor;
58
- mask-image: var(--icon-url);
59
- mask-position: center;
60
- mask-repeat: no-repeat;
61
- mask-size: contain;
62
- -webkit-mask-image: var(--icon-url);
63
- -webkit-mask-position: center;
64
- -webkit-mask-repeat: no-repeat;
65
- -webkit-mask-size: contain;
66
- }
67
- </style>
1
+ <script lang="ts">
2
+ const iconModules = import.meta.glob("../icons/**/*.svg", {
3
+ eager: true,
4
+ import: "default"
5
+ });
6
+
7
+ interface Props {
8
+ alt?: string;
9
+ name?: string;
10
+ size?: number;
11
+ }
12
+
13
+ let { alt = "", name = "", size = 24 }: Props = $props();
14
+
15
+ function normalizeNameToPath(value: unknown): string | null {
16
+ const safe = typeof value === "string" ? value.trim() : "";
17
+
18
+ if (safe.length === 0) {
19
+ return null;
20
+ }
21
+
22
+ const parts = safe.split("-").filter((part) => part.length > 0);
23
+
24
+ if (parts.length < 2) {
25
+ return null;
26
+ }
27
+
28
+ const folder = parts[0];
29
+ const file = parts.slice(1).join("-");
30
+
31
+ return `../icons/${folder}/${file}.svg`;
32
+ }
33
+
34
+ let groupedPath = $derived(normalizeNameToPath(name));
35
+ let iconPath = $derived(
36
+ (groupedPath != null ? iconModules[groupedPath] : undefined) ??
37
+ iconModules[`../icons/${name}.svg`] ??
38
+ ""
39
+ );
40
+ </script>
41
+
42
+ {#if iconPath}
43
+ <span
44
+ role={alt ? "img" : undefined}
45
+ aria-label={alt || undefined}
46
+ aria-hidden={alt ? undefined : "true"}
47
+ style:--icon-url={`url('${iconPath}')`}
48
+ style:width={`${size / 16}rem`}
49
+ style:height={`${size / 16}rem`}
50
+ ></span>
51
+ {/if}
52
+
53
+ <style>
54
+ span {
55
+ display: inline-block;
56
+ flex: 0 0 auto;
57
+ background-color: currentColor;
58
+ mask-image: var(--icon-url);
59
+ mask-position: center;
60
+ mask-repeat: no-repeat;
61
+ mask-size: contain;
62
+ -webkit-mask-image: var(--icon-url);
63
+ -webkit-mask-position: center;
64
+ -webkit-mask-repeat: no-repeat;
65
+ -webkit-mask-size: contain;
66
+ }
67
+ </style>
@@ -1,106 +1,106 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- interface SidebarNavItem {
5
- active?: boolean;
6
- href?: string;
7
- label: string;
8
- }
9
-
10
- interface Props {
11
- bottomItems?: SidebarNavItem[];
12
- logo?: Snippet;
13
- topItems?: SidebarNavItem[];
14
- }
15
-
16
- let { bottomItems = [], logo, topItems = [] }: Props = $props();
17
- </script>
18
-
19
- <aside class="sidebar">
20
- {#if logo}
21
- <div class="brand">
22
- {@render logo()}
23
- </div>
24
- {/if}
25
-
26
- <nav class="nav-section top" aria-label="Primary navigation">
27
- {#each topItems as item}
28
- <a
29
- class="nav-item"
30
- class:active={item.active}
31
- href={item.href ?? '#'}
32
- aria-current={item.active ? 'page' : undefined}
33
- >
34
- {item.label}
35
- </a>
36
- {/each}
37
- </nav>
38
-
39
- {#if bottomItems.length > 0}
40
- <nav class="nav-section bottom" aria-label="Secondary navigation">
41
- {#each bottomItems as item}
42
- <a
43
- class="nav-item"
44
- class:active={item.active}
45
- href={item.href ?? '#'}
46
- aria-current={item.active ? 'page' : undefined}
47
- >
48
- {item.label}
49
- </a>
50
- {/each}
51
- </nav>
52
- {/if}
53
- </aside>
54
-
55
- <style>
56
- .sidebar {
57
- display: flex;
58
- flex-direction: column;
59
- width: 16.5rem;
60
- max-width: 100%;
61
- min-height: 100%;
62
- background: var(--seblify-color-surface-inverse, #172033);
63
- }
64
-
65
- .brand {
66
- padding: 1.5rem 1rem;
67
- color: var(--seblify-color-text-inverse, #ffffff);
68
- }
69
-
70
- .nav-section {
71
- display: grid;
72
- gap: 0.25rem;
73
- margin: 0 1rem;
74
- }
75
-
76
- .top {
77
- align-content: start;
78
- }
79
-
80
- .bottom {
81
- margin-top: auto;
82
- padding-bottom: 1rem;
83
- }
84
-
85
- .nav-item {
86
- display: block;
87
- width: 100%;
88
- border-radius: 0.375rem;
89
- padding: 0.75rem 1rem;
90
- color: var(--seblify-color-text-inverse, #ffffff);
91
- font-size: 0.875rem;
92
- line-height: 1.25rem;
93
- text-decoration: none;
94
- box-sizing: border-box;
95
- }
96
-
97
- .nav-item:hover {
98
- background: var(--seblify-color-surface-inverse-hover, #263043);
99
- color: var(--seblify-color-text-inverse, #ffffff);
100
- }
101
-
102
- .active {
103
- background: var(--seblify-color-surface-inverse-hover, #263043);
104
- color: var(--seblify-color-text-inverse, #ffffff);
105
- }
106
- </style>
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface SidebarNavItem {
5
+ active?: boolean;
6
+ href?: string;
7
+ label: string;
8
+ }
9
+
10
+ interface Props {
11
+ bottomItems?: SidebarNavItem[];
12
+ logo?: Snippet;
13
+ topItems?: SidebarNavItem[];
14
+ }
15
+
16
+ let { bottomItems = [], logo, topItems = [] }: Props = $props();
17
+ </script>
18
+
19
+ <aside class="sidebar">
20
+ {#if logo}
21
+ <div class="brand">
22
+ {@render logo()}
23
+ </div>
24
+ {/if}
25
+
26
+ <nav class="nav-section top" aria-label="Primary navigation">
27
+ {#each topItems as item}
28
+ <a
29
+ class="nav-item"
30
+ class:active={item.active}
31
+ href={item.href ?? '#'}
32
+ aria-current={item.active ? 'page' : undefined}
33
+ >
34
+ {item.label}
35
+ </a>
36
+ {/each}
37
+ </nav>
38
+
39
+ {#if bottomItems.length > 0}
40
+ <nav class="nav-section bottom" aria-label="Secondary navigation">
41
+ {#each bottomItems as item}
42
+ <a
43
+ class="nav-item"
44
+ class:active={item.active}
45
+ href={item.href ?? '#'}
46
+ aria-current={item.active ? 'page' : undefined}
47
+ >
48
+ {item.label}
49
+ </a>
50
+ {/each}
51
+ </nav>
52
+ {/if}
53
+ </aside>
54
+
55
+ <style>
56
+ .sidebar {
57
+ display: flex;
58
+ flex-direction: column;
59
+ width: 16.5rem;
60
+ max-width: 100%;
61
+ min-height: 100%;
62
+ background: var(--seblify-color-surface-inverse, #172033);
63
+ }
64
+
65
+ .brand {
66
+ padding: 1.5rem 1rem;
67
+ color: var(--seblify-color-text-inverse, #ffffff);
68
+ }
69
+
70
+ .nav-section {
71
+ display: grid;
72
+ gap: 0.25rem;
73
+ margin: 0 1rem;
74
+ }
75
+
76
+ .top {
77
+ align-content: start;
78
+ }
79
+
80
+ .bottom {
81
+ margin-top: auto;
82
+ padding-bottom: 1rem;
83
+ }
84
+
85
+ .nav-item {
86
+ display: block;
87
+ width: 100%;
88
+ border-radius: 0.375rem;
89
+ padding: 0.75rem 1rem;
90
+ color: var(--seblify-color-text-inverse, #ffffff);
91
+ font-size: 0.875rem;
92
+ line-height: 1.25rem;
93
+ text-decoration: none;
94
+ box-sizing: border-box;
95
+ }
96
+
97
+ .nav-item:hover {
98
+ background: var(--seblify-color-surface-inverse-hover, #263043);
99
+ color: var(--seblify-color-text-inverse, #ffffff);
100
+ }
101
+
102
+ .active {
103
+ background: var(--seblify-color-surface-inverse-hover, #263043);
104
+ color: var(--seblify-color-text-inverse, #ffffff);
105
+ }
106
+ </style>
@@ -1,26 +1,26 @@
1
- <script lang="ts">
2
- import type { Snippet } from 'svelte';
3
-
4
- interface Props {
5
- children?: Snippet;
6
- }
7
-
8
- let { children }: Props = $props();
9
- </script>
10
-
11
- <section class="snackbar" role="status">
12
- {@render children?.()}
13
- </section>
14
-
15
- <style>
16
- .snackbar {
17
- border: 1px solid var(--seblify-color-border-inverse, #263043);
18
- border-radius: 6px;
19
- padding: 12px 14px;
20
- background: var(--seblify-color-surface-inverse, #172033);
21
- color: var(--seblify-color-text-inverse, #ffffff);
22
- box-shadow: var(--seblify-shadow-raised, 0 12px 28px rgb(23 32 51 / 22%));
23
- font-size: 14px;
24
- line-height: 1.4;
25
- }
26
- </style>
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ interface Props {
5
+ children?: Snippet;
6
+ }
7
+
8
+ let { children }: Props = $props();
9
+ </script>
10
+
11
+ <section class="snackbar" role="status">
12
+ {@render children?.()}
13
+ </section>
14
+
15
+ <style>
16
+ .snackbar {
17
+ border: 1px solid var(--seblify-color-border-inverse, #263043);
18
+ border-radius: 6px;
19
+ padding: 12px 14px;
20
+ background: var(--seblify-color-surface-inverse, #172033);
21
+ color: var(--seblify-color-text-inverse, #ffffff);
22
+ box-shadow: var(--seblify-shadow-raised, 0 12px 28px rgb(23 32 51 / 22%));
23
+ font-size: 14px;
24
+ line-height: 1.4;
25
+ }
26
+ </style>