@fastwork/xosmoz-svelte 0.0.31 → 0.0.32
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.
- package/dist/components/badge/Badge.svelte +183 -0
- package/dist/components/badge/Badge.svelte.d.ts +26 -0
- package/dist/components/badge/BadgeAllVariants.svelte +94 -0
- package/dist/components/badge/BadgeAllVariants.svelte.d.ts +18 -0
- package/dist/components/badge/BadgeShowcase.svelte +24 -0
- package/dist/components/badge/BadgeShowcase.svelte.d.ts +11 -0
- package/dist/components/badge/index.d.ts +2 -0
- package/dist/components/badge/index.js +1 -0
- package/dist/components/button/Button.svelte +376 -0
- package/dist/components/button/index.d.ts +2 -0
- package/dist/components/button/index.js +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/styles/_helpers.scss +9 -0
- package/package.json +8 -1
- package/dist/components/Button.svelte +0 -117
- /package/dist/components/{Button.svelte.d.ts → button/Button.svelte.d.ts} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type BadgeVariant =
|
|
3
|
+
| 'primary'
|
|
4
|
+
| 'primary-solid'
|
|
5
|
+
| 'success'
|
|
6
|
+
| 'success-solid'
|
|
7
|
+
| 'danger'
|
|
8
|
+
| 'danger-solid'
|
|
9
|
+
| 'warning'
|
|
10
|
+
| 'warning-solid'
|
|
11
|
+
| 'info'
|
|
12
|
+
| 'info-solid'
|
|
13
|
+
| 'neutral'
|
|
14
|
+
| 'neutral-solid'
|
|
15
|
+
|
|
16
|
+
export type BadgeSize = 'small' | 'medium' | 'large'
|
|
17
|
+
|
|
18
|
+
export interface BadgeProps {
|
|
19
|
+
/** Badge variant style */
|
|
20
|
+
variant?: BadgeVariant
|
|
21
|
+
/** Badge size */
|
|
22
|
+
size?: BadgeSize
|
|
23
|
+
/** Whether the badge has pill-shaped border radius */
|
|
24
|
+
isPill?: boolean
|
|
25
|
+
/** Whether the badge should take full width */
|
|
26
|
+
isFluid?: boolean
|
|
27
|
+
/** Icon class name (e.g. for icon fonts) */
|
|
28
|
+
iconClass?: string
|
|
29
|
+
/** Additional CSS classes */
|
|
30
|
+
class?: string
|
|
31
|
+
}
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<script lang="ts">
|
|
35
|
+
import type { Snippet } from 'svelte'
|
|
36
|
+
|
|
37
|
+
interface Props extends BadgeProps {
|
|
38
|
+
/** Main badge content */
|
|
39
|
+
children: Snippet
|
|
40
|
+
/** Icon snippet */
|
|
41
|
+
icon?: Snippet
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let {
|
|
45
|
+
children,
|
|
46
|
+
variant = 'neutral',
|
|
47
|
+
size = 'medium',
|
|
48
|
+
isPill = false,
|
|
49
|
+
isFluid = false,
|
|
50
|
+
icon,
|
|
51
|
+
iconClass,
|
|
52
|
+
class: className = '',
|
|
53
|
+
}: Props = $props()
|
|
54
|
+
|
|
55
|
+
const badgeClasses = $derived.by(() => {
|
|
56
|
+
const classes = ['xz-badge']
|
|
57
|
+
|
|
58
|
+
// Variant (only add class if not neutral, which is the default)
|
|
59
|
+
if (variant !== 'neutral') {
|
|
60
|
+
classes.push(`is-variant-${variant}`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Size (only add class if not medium, which is the default)
|
|
64
|
+
if (size !== 'medium') {
|
|
65
|
+
classes.push(`is-size-${size}`)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Modifiers
|
|
69
|
+
if (isPill) classes.push('is-pill')
|
|
70
|
+
if (isFluid) classes.push('is-fluid')
|
|
71
|
+
|
|
72
|
+
// Custom classes
|
|
73
|
+
if (className) classes.push(className)
|
|
74
|
+
|
|
75
|
+
return classes.join(' ')
|
|
76
|
+
})
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<div class={badgeClasses}>
|
|
80
|
+
{#if iconClass}
|
|
81
|
+
<span class="icon">
|
|
82
|
+
<i class={iconClass}></i>
|
|
83
|
+
</span>
|
|
84
|
+
{/if}
|
|
85
|
+
|
|
86
|
+
{#if icon}
|
|
87
|
+
<span class="icon">
|
|
88
|
+
{@render icon()}
|
|
89
|
+
</span>
|
|
90
|
+
{/if}
|
|
91
|
+
|
|
92
|
+
{@render children()}
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<style>.xz-badge {
|
|
96
|
+
display: inline-flex;
|
|
97
|
+
gap: 0.25rem;
|
|
98
|
+
justify-content: center;
|
|
99
|
+
align-items: center;
|
|
100
|
+
padding: 0.25rem 0.625rem;
|
|
101
|
+
border-radius: 0.375rem;
|
|
102
|
+
background: var(--xz-color-neutral-soft-100);
|
|
103
|
+
color: var(--xz-color-neutral-fg-100);
|
|
104
|
+
font-weight: 500;
|
|
105
|
+
font-size: var(--xz-font-size-300, 0.75rem);
|
|
106
|
+
font-family: var(--xz-font-family-primary, system-ui, sans-serif);
|
|
107
|
+
line-height: 1.4;
|
|
108
|
+
}
|
|
109
|
+
.xz-badge .icon {
|
|
110
|
+
display: flex;
|
|
111
|
+
justify-content: flex-start;
|
|
112
|
+
align-items: center;
|
|
113
|
+
width: 1rem;
|
|
114
|
+
height: 1rem;
|
|
115
|
+
}
|
|
116
|
+
.xz-badge.is-size-small {
|
|
117
|
+
padding: 0.1875rem 0.5rem;
|
|
118
|
+
border-radius: 0.25rem;
|
|
119
|
+
font-size: 0.75rem;
|
|
120
|
+
}
|
|
121
|
+
.xz-badge.is-size-large {
|
|
122
|
+
padding: 0.5rem 1rem;
|
|
123
|
+
font-size: 0.875rem;
|
|
124
|
+
}
|
|
125
|
+
.xz-badge.is-variant-primary {
|
|
126
|
+
background: var(--xz-color-primary-soft-100);
|
|
127
|
+
color: var(--xz-color-primary-fg-100);
|
|
128
|
+
}
|
|
129
|
+
.xz-badge.is-variant-success {
|
|
130
|
+
background: var(--xz-color-success-soft-100);
|
|
131
|
+
color: var(--xz-color-success-fg-100);
|
|
132
|
+
}
|
|
133
|
+
.xz-badge.is-variant-danger {
|
|
134
|
+
background: var(--xz-color-danger-soft-100);
|
|
135
|
+
color: var(--xz-color-danger-fg-100);
|
|
136
|
+
}
|
|
137
|
+
.xz-badge.is-variant-warning {
|
|
138
|
+
background: var(--xz-color-warning-soft-100);
|
|
139
|
+
color: var(--xz-color-warning-fg-100);
|
|
140
|
+
}
|
|
141
|
+
.xz-badge.is-variant-info {
|
|
142
|
+
background: var(--xz-color-info-soft-100);
|
|
143
|
+
color: var(--xz-color-info-fg-100);
|
|
144
|
+
}
|
|
145
|
+
.xz-badge.is-variant-primary-solid {
|
|
146
|
+
background: var(--xz-color-primary-bg-100);
|
|
147
|
+
color: var(--xz-color-primary-fg-50);
|
|
148
|
+
}
|
|
149
|
+
.xz-badge.is-variant-success-solid {
|
|
150
|
+
background: var(--xz-color-success-bg-100);
|
|
151
|
+
color: var(--xz-color-success-fg-50, #fff);
|
|
152
|
+
}
|
|
153
|
+
.xz-badge.is-variant-danger-solid {
|
|
154
|
+
background: var(--xz-color-danger-bg-100);
|
|
155
|
+
color: var(--xz-color-danger-fg-50, #fff);
|
|
156
|
+
}
|
|
157
|
+
.xz-badge.is-variant-warning-solid {
|
|
158
|
+
background: var(--xz-color-warning-bg-100);
|
|
159
|
+
color: var(--xz-color-warning-fg-50, #fff);
|
|
160
|
+
}
|
|
161
|
+
.xz-badge.is-variant-info-solid {
|
|
162
|
+
background: var(--xz-color-info-bg-100);
|
|
163
|
+
color: var(--xz-color-info-fg-50, #fff);
|
|
164
|
+
}
|
|
165
|
+
.xz-badge.is-variant-neutral-solid {
|
|
166
|
+
background: var(--xz-color-neutral-bg-100);
|
|
167
|
+
color: var(--xz-color-neutral-fg-50, #fff);
|
|
168
|
+
}
|
|
169
|
+
.xz-badge.is-fluid {
|
|
170
|
+
width: 100%;
|
|
171
|
+
}
|
|
172
|
+
.xz-badge.is-pill {
|
|
173
|
+
border-radius: 999px;
|
|
174
|
+
}
|
|
175
|
+
.xz-badge.is-pill.is-size-small {
|
|
176
|
+
padding: 0.1875rem 0.5625rem;
|
|
177
|
+
}
|
|
178
|
+
.xz-badge.is-pill.is-size-medium {
|
|
179
|
+
padding: 0.375rem 0.875rem;
|
|
180
|
+
}
|
|
181
|
+
.xz-badge.is-pill.is-size-large {
|
|
182
|
+
padding: 0.5rem 1rem;
|
|
183
|
+
}</style>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type BadgeVariant = 'primary' | 'primary-solid' | 'success' | 'success-solid' | 'danger' | 'danger-solid' | 'warning' | 'warning-solid' | 'info' | 'info-solid' | 'neutral' | 'neutral-solid';
|
|
2
|
+
export type BadgeSize = 'small' | 'medium' | 'large';
|
|
3
|
+
export interface BadgeProps {
|
|
4
|
+
/** Badge variant style */
|
|
5
|
+
variant?: BadgeVariant;
|
|
6
|
+
/** Badge size */
|
|
7
|
+
size?: BadgeSize;
|
|
8
|
+
/** Whether the badge has pill-shaped border radius */
|
|
9
|
+
isPill?: boolean;
|
|
10
|
+
/** Whether the badge should take full width */
|
|
11
|
+
isFluid?: boolean;
|
|
12
|
+
/** Icon class name (e.g. for icon fonts) */
|
|
13
|
+
iconClass?: string;
|
|
14
|
+
/** Additional CSS classes */
|
|
15
|
+
class?: string;
|
|
16
|
+
}
|
|
17
|
+
import type { Snippet } from 'svelte';
|
|
18
|
+
interface Props extends BadgeProps {
|
|
19
|
+
/** Main badge content */
|
|
20
|
+
children: Snippet;
|
|
21
|
+
/** Icon snippet */
|
|
22
|
+
icon?: Snippet;
|
|
23
|
+
}
|
|
24
|
+
declare const Badge: import("svelte").Component<Props, {}, "">;
|
|
25
|
+
type Badge = ReturnType<typeof Badge>;
|
|
26
|
+
export default Badge;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Badge from './Badge.svelte'
|
|
3
|
+
</script>
|
|
4
|
+
|
|
5
|
+
<div class="badge-showcase">
|
|
6
|
+
<section>
|
|
7
|
+
<h3>Soft Variants</h3>
|
|
8
|
+
<div class="badge-row">
|
|
9
|
+
<Badge variant="primary">Primary</Badge>
|
|
10
|
+
<Badge variant="success">Success</Badge>
|
|
11
|
+
<Badge variant="danger">Danger</Badge>
|
|
12
|
+
<Badge variant="warning">Warning</Badge>
|
|
13
|
+
<Badge variant="info">Info</Badge>
|
|
14
|
+
<Badge variant="neutral">Neutral</Badge>
|
|
15
|
+
</div>
|
|
16
|
+
</section>
|
|
17
|
+
|
|
18
|
+
<section>
|
|
19
|
+
<h3>Solid Variants</h3>
|
|
20
|
+
<div class="badge-row">
|
|
21
|
+
<Badge variant="primary-solid">Primary Solid</Badge>
|
|
22
|
+
<Badge variant="success-solid">Success Solid</Badge>
|
|
23
|
+
<Badge variant="danger-solid">Danger Solid</Badge>
|
|
24
|
+
<Badge variant="warning-solid">Warning Solid</Badge>
|
|
25
|
+
<Badge variant="info-solid">Info Solid</Badge>
|
|
26
|
+
<Badge variant="neutral-solid">Neutral Solid</Badge>
|
|
27
|
+
</div>
|
|
28
|
+
</section>
|
|
29
|
+
|
|
30
|
+
<section>
|
|
31
|
+
<h3>Sizes</h3>
|
|
32
|
+
<div class="badge-row">
|
|
33
|
+
<Badge size="small">Small</Badge>
|
|
34
|
+
<Badge size="medium">Medium</Badge>
|
|
35
|
+
<Badge size="large">Large</Badge>
|
|
36
|
+
</div>
|
|
37
|
+
</section>
|
|
38
|
+
|
|
39
|
+
<section>
|
|
40
|
+
<h3>Modifiers</h3>
|
|
41
|
+
<div class="badge-row">
|
|
42
|
+
<Badge isPill>Pill</Badge>
|
|
43
|
+
<Badge variant="primary" isPill>Primary Pill</Badge>
|
|
44
|
+
<Badge variant="success" isPill>Success Pill</Badge>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="badge-row" style="width: 100%; max-width: 400px;">
|
|
47
|
+
<Badge isFluid>Fluid</Badge>
|
|
48
|
+
</div>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<section>
|
|
52
|
+
<h3>Variant + Sizes</h3>
|
|
53
|
+
<div class="badge-row">
|
|
54
|
+
<Badge variant="primary" size="small">Primary Small</Badge>
|
|
55
|
+
<Badge variant="primary" size="medium">Primary Medium</Badge>
|
|
56
|
+
<Badge variant="primary" size="large">Primary Large</Badge>
|
|
57
|
+
</div>
|
|
58
|
+
<div class="badge-row">
|
|
59
|
+
<Badge variant="danger" size="small">Danger Small</Badge>
|
|
60
|
+
<Badge variant="danger" size="medium">Danger Medium</Badge>
|
|
61
|
+
<Badge variant="danger" size="large">Danger Large</Badge>
|
|
62
|
+
</div>
|
|
63
|
+
</section>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<style>
|
|
67
|
+
.badge-showcase {
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
gap: 2rem;
|
|
71
|
+
padding: 2rem;
|
|
72
|
+
font-family: var(--xz-font-family-primary, system-ui);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
section {
|
|
76
|
+
display: flex;
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
gap: 1rem;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
h3 {
|
|
82
|
+
margin: 0;
|
|
83
|
+
color: var(--xz-color-fg-100);
|
|
84
|
+
font-weight: 600;
|
|
85
|
+
font-size: 1rem;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.badge-row {
|
|
89
|
+
display: flex;
|
|
90
|
+
flex-wrap: wrap;
|
|
91
|
+
gap: 0.75rem;
|
|
92
|
+
align-items: center;
|
|
93
|
+
}
|
|
94
|
+
</style>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const BadgeAllVariants: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type BadgeAllVariants = InstanceType<typeof BadgeAllVariants>;
|
|
18
|
+
export default BadgeAllVariants;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import Badge from './Badge.svelte'
|
|
3
|
+
import type { BadgeVariant, BadgeSize } from './Badge.svelte'
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
variant?: BadgeVariant
|
|
7
|
+
size?: BadgeSize
|
|
8
|
+
isPill?: boolean
|
|
9
|
+
isFluid?: boolean
|
|
10
|
+
label?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
variant = 'neutral',
|
|
15
|
+
size = 'medium',
|
|
16
|
+
isPill = false,
|
|
17
|
+
isFluid = false,
|
|
18
|
+
label = 'Badge',
|
|
19
|
+
}: Props = $props()
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<Badge {variant} {size} {isPill} {isFluid}>
|
|
23
|
+
{label}
|
|
24
|
+
</Badge>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BadgeVariant, BadgeSize } from './Badge.svelte';
|
|
2
|
+
interface Props {
|
|
3
|
+
variant?: BadgeVariant;
|
|
4
|
+
size?: BadgeSize;
|
|
5
|
+
isPill?: boolean;
|
|
6
|
+
isFluid?: boolean;
|
|
7
|
+
label?: string;
|
|
8
|
+
}
|
|
9
|
+
declare const BadgeShowcase: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type BadgeShowcase = ReturnType<typeof BadgeShowcase>;
|
|
11
|
+
export default BadgeShowcase;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Badge } from './Badge.svelte';
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type ButtonVariant =
|
|
3
|
+
| 'primary'
|
|
4
|
+
| 'secondary'
|
|
5
|
+
| 'outline'
|
|
6
|
+
| 'tertiary'
|
|
7
|
+
| 'ghost'
|
|
8
|
+
| 'danger'
|
|
9
|
+
| 'success'
|
|
10
|
+
| 'white'
|
|
11
|
+
| 'white-secondary'
|
|
12
|
+
|
|
13
|
+
export type ButtonSize = 'small' | 'medium' | 'large'
|
|
14
|
+
|
|
15
|
+
export interface ButtonProps {
|
|
16
|
+
/** Button variant style */
|
|
17
|
+
variant?: ButtonVariant
|
|
18
|
+
/** Button size */
|
|
19
|
+
size?: ButtonSize
|
|
20
|
+
/** Whether the button is disabled */
|
|
21
|
+
disabled?: boolean
|
|
22
|
+
/** Whether the button is in loading state */
|
|
23
|
+
loading?: boolean
|
|
24
|
+
/** Whether the button should take full width */
|
|
25
|
+
fluid?: boolean
|
|
26
|
+
/** Whether the button has pill-shaped border radius */
|
|
27
|
+
pill?: boolean
|
|
28
|
+
/** Whether the button should be square (1:1 aspect ratio) */
|
|
29
|
+
square?: boolean
|
|
30
|
+
/** Button type attribute */
|
|
31
|
+
type?: 'button' | 'submit' | 'reset'
|
|
32
|
+
/** Additional CSS classes */
|
|
33
|
+
class?: string
|
|
34
|
+
/** Click handler */
|
|
35
|
+
onclick?: (event: MouseEvent) => void
|
|
36
|
+
}
|
|
37
|
+
</script>
|
|
38
|
+
|
|
39
|
+
<script lang="ts">
|
|
40
|
+
import type { Snippet } from 'svelte'
|
|
41
|
+
|
|
42
|
+
interface Props extends ButtonProps {
|
|
43
|
+
/** Content before the main text */
|
|
44
|
+
startIcon?: Snippet
|
|
45
|
+
/** Main button content */
|
|
46
|
+
children: Snippet
|
|
47
|
+
/** Content after the main text */
|
|
48
|
+
endIcon?: Snippet
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let {
|
|
52
|
+
variant = 'primary',
|
|
53
|
+
size = 'medium',
|
|
54
|
+
disabled = false,
|
|
55
|
+
loading = false,
|
|
56
|
+
fluid = false,
|
|
57
|
+
pill = false,
|
|
58
|
+
square = false,
|
|
59
|
+
type = 'button',
|
|
60
|
+
class: className = '',
|
|
61
|
+
onclick,
|
|
62
|
+
startIcon,
|
|
63
|
+
children,
|
|
64
|
+
endIcon,
|
|
65
|
+
}: Props = $props()
|
|
66
|
+
|
|
67
|
+
const buttonClasses = $derived.by(() => {
|
|
68
|
+
const classes = ['xz-button']
|
|
69
|
+
|
|
70
|
+
// Variant (only add class if not primary, which is the default)
|
|
71
|
+
if (variant !== 'primary') {
|
|
72
|
+
classes.push(`is-variant-${variant}`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Size (only add class if not medium, which is the default)
|
|
76
|
+
if (size !== 'medium') {
|
|
77
|
+
classes.push(`is-size-${size}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// States
|
|
81
|
+
if (loading) classes.push('is-loading')
|
|
82
|
+
if (disabled) classes.push('is-disabled')
|
|
83
|
+
|
|
84
|
+
// Modifiers
|
|
85
|
+
if (fluid) classes.push('is-fluid')
|
|
86
|
+
if (pill) classes.push('is-pill')
|
|
87
|
+
if (square) classes.push('is-square')
|
|
88
|
+
|
|
89
|
+
// Custom classes
|
|
90
|
+
if (className) classes.push(className)
|
|
91
|
+
|
|
92
|
+
return classes.join(' ')
|
|
93
|
+
})
|
|
94
|
+
</script>
|
|
95
|
+
|
|
96
|
+
<button
|
|
97
|
+
class={buttonClasses}
|
|
98
|
+
{type}
|
|
99
|
+
disabled={disabled || loading}
|
|
100
|
+
aria-disabled={disabled || loading}
|
|
101
|
+
aria-busy={loading}
|
|
102
|
+
{onclick}
|
|
103
|
+
>
|
|
104
|
+
{#if startIcon}
|
|
105
|
+
<span class="start-icon">
|
|
106
|
+
{@render startIcon()}
|
|
107
|
+
</span>
|
|
108
|
+
{/if}
|
|
109
|
+
<span>
|
|
110
|
+
{@render children()}
|
|
111
|
+
</span>
|
|
112
|
+
{#if endIcon}
|
|
113
|
+
<span class="end-icon">
|
|
114
|
+
{@render endIcon()}
|
|
115
|
+
</span>
|
|
116
|
+
{/if}
|
|
117
|
+
</button>
|
|
118
|
+
|
|
119
|
+
<style>.xz-button {
|
|
120
|
+
--button-font-family: var(
|
|
121
|
+
--xz-font-family-primary,
|
|
122
|
+
system-ui,
|
|
123
|
+
sans-serif
|
|
124
|
+
);
|
|
125
|
+
--button-font-weight: 600;
|
|
126
|
+
--button-border-radius: 0.5rem;
|
|
127
|
+
--button-small-height: 2rem;
|
|
128
|
+
--button-small-font-size: 0.8125rem;
|
|
129
|
+
--button-medium-height: 2.5rem;
|
|
130
|
+
--button-medium-font-size: 0.875rem;
|
|
131
|
+
--button-large-height: 3rem;
|
|
132
|
+
--button-large-font-size: 1rem;
|
|
133
|
+
position: relative;
|
|
134
|
+
display: inline-flex;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
align-items: center;
|
|
137
|
+
overflow: hidden;
|
|
138
|
+
min-height: var(--button-medium-height);
|
|
139
|
+
padding: 0 1.125rem;
|
|
140
|
+
border: none;
|
|
141
|
+
border-radius: var(--button-border-radius);
|
|
142
|
+
background: var(--xz-color-primary-bg-100);
|
|
143
|
+
color: var(--xz-color-primary-fg-50);
|
|
144
|
+
outline: none;
|
|
145
|
+
font-weight: var(--button-font-weight);
|
|
146
|
+
font-size: var(--button-medium-font-size);
|
|
147
|
+
font-family: var(--button-font-family);
|
|
148
|
+
line-height: 100%;
|
|
149
|
+
cursor: pointer;
|
|
150
|
+
user-select: none;
|
|
151
|
+
transition: all 0.16s ease-in-out;
|
|
152
|
+
}
|
|
153
|
+
@media (hover: hover) {
|
|
154
|
+
.xz-button:hover::before {
|
|
155
|
+
background: var(--xz-color-black-alpha-100);
|
|
156
|
+
}
|
|
157
|
+
.xz-button:focus {
|
|
158
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
.xz-button > span {
|
|
162
|
+
z-index: 1;
|
|
163
|
+
}
|
|
164
|
+
.xz-button .start-icon,
|
|
165
|
+
.xz-button .end-icon {
|
|
166
|
+
display: flex;
|
|
167
|
+
align-items: center;
|
|
168
|
+
min-width: 1.375rem;
|
|
169
|
+
}
|
|
170
|
+
.xz-button .end-icon {
|
|
171
|
+
justify-content: flex-end;
|
|
172
|
+
}
|
|
173
|
+
.xz-button::before {
|
|
174
|
+
content: "";
|
|
175
|
+
position: absolute;
|
|
176
|
+
inset: 0;
|
|
177
|
+
z-index: 0;
|
|
178
|
+
pointer-events: none;
|
|
179
|
+
transition: all 0.16s ease-in-out;
|
|
180
|
+
}
|
|
181
|
+
.xz-button.is-size-small {
|
|
182
|
+
min-height: var(--button-small-height);
|
|
183
|
+
padding: 0 1rem;
|
|
184
|
+
font-size: var(--button-small-font-size);
|
|
185
|
+
}
|
|
186
|
+
.xz-button.is-size-small .start-icon,
|
|
187
|
+
.xz-button.is-size-small .end-icon {
|
|
188
|
+
min-width: 1.125rem;
|
|
189
|
+
}
|
|
190
|
+
.xz-button.is-size-medium {
|
|
191
|
+
min-height: var(--button-medium-height);
|
|
192
|
+
padding: 0 1.125rem;
|
|
193
|
+
font-size: var(--button-medium-font-size);
|
|
194
|
+
}
|
|
195
|
+
.xz-button.is-size-medium .start-icon,
|
|
196
|
+
.xz-button.is-size-medium .end-icon {
|
|
197
|
+
min-width: 1.375rem;
|
|
198
|
+
}
|
|
199
|
+
.xz-button.is-size-large {
|
|
200
|
+
min-height: var(--button-large-height);
|
|
201
|
+
padding: 0 1.25rem;
|
|
202
|
+
font-size: var(--button-large-font-size);
|
|
203
|
+
}
|
|
204
|
+
.xz-button.is-size-large .start-icon,
|
|
205
|
+
.xz-button.is-size-large .end-icon {
|
|
206
|
+
min-width: 1.625rem;
|
|
207
|
+
}
|
|
208
|
+
.xz-button.is-variant-danger {
|
|
209
|
+
background: var(--xz-color-danger-bg-100);
|
|
210
|
+
}
|
|
211
|
+
@media (hover: hover) {
|
|
212
|
+
.xz-button.is-variant-danger:focus {
|
|
213
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-danger-line-200);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
.xz-button.is-variant-danger.is-loading::after {
|
|
217
|
+
border-top-color: var(--xz-color-danger-fg-50);
|
|
218
|
+
border-right-color: var(--xz-color-danger-fg-50);
|
|
219
|
+
}
|
|
220
|
+
.xz-button.is-variant-success {
|
|
221
|
+
background: var(--xz-color-success-bg-100);
|
|
222
|
+
}
|
|
223
|
+
@media (hover: hover) {
|
|
224
|
+
.xz-button.is-variant-success:focus {
|
|
225
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-success-line-200);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
.xz-button.is-variant-success.is-loading::after {
|
|
229
|
+
border-top-color: var(--xz-color-success-fg-50);
|
|
230
|
+
border-right-color: var(--xz-color-success-fg-50);
|
|
231
|
+
}
|
|
232
|
+
.xz-button.is-variant-secondary {
|
|
233
|
+
border: 1px solid var(--xz-color-line-100);
|
|
234
|
+
background: transparent;
|
|
235
|
+
color: var(--xz-color-primary-fg-100);
|
|
236
|
+
}
|
|
237
|
+
@media (hover: hover) {
|
|
238
|
+
.xz-button.is-variant-secondary:focus {
|
|
239
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
240
|
+
}
|
|
241
|
+
.xz-button.is-variant-secondary:hover {
|
|
242
|
+
border: 1px solid var(--xz-color-line-200);
|
|
243
|
+
color: var(--xz-color-primary-fg-100);
|
|
244
|
+
}
|
|
245
|
+
.xz-button.is-variant-secondary:hover::before {
|
|
246
|
+
background: var(--xz-color-black-alpha-100);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
.xz-button.is-variant-secondary.is-loading::after {
|
|
250
|
+
border-top-color: var(--xz-color-primary-fg-100);
|
|
251
|
+
border-right-color: var(--xz-color-primary-fg-100);
|
|
252
|
+
}
|
|
253
|
+
.xz-button.is-variant-outline {
|
|
254
|
+
border: 1px solid var(--xz-color-line-100);
|
|
255
|
+
background: transparent;
|
|
256
|
+
color: var(--xz-color-fg-200);
|
|
257
|
+
}
|
|
258
|
+
@media (hover: hover) {
|
|
259
|
+
.xz-button.is-variant-outline:focus {
|
|
260
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
261
|
+
}
|
|
262
|
+
.xz-button.is-variant-outline:hover {
|
|
263
|
+
border: 1px solid var(--xz-color-line-200);
|
|
264
|
+
color: var(--xz-color-fg-100);
|
|
265
|
+
}
|
|
266
|
+
.xz-button.is-variant-outline:hover::before {
|
|
267
|
+
background: var(--xz-color-black-alpha-100);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
.xz-button.is-variant-outline.is-loading::after {
|
|
271
|
+
border-top-color: var(--xz-color-fg-200);
|
|
272
|
+
border-right-color: var(--xz-color-fg-200);
|
|
273
|
+
}
|
|
274
|
+
.xz-button.is-variant-tertiary {
|
|
275
|
+
border: unset;
|
|
276
|
+
background: var(--xz-color-neutral-soft-100);
|
|
277
|
+
color: var(--xz-color-fg-100);
|
|
278
|
+
}
|
|
279
|
+
@media (hover: hover) {
|
|
280
|
+
.xz-button.is-variant-tertiary:focus {
|
|
281
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
.xz-button.is-variant-tertiary.is-loading::after {
|
|
285
|
+
border-top-color: var(--xz-color-fg-200);
|
|
286
|
+
border-right-color: var(--xz-color-fg-200);
|
|
287
|
+
}
|
|
288
|
+
.xz-button.is-variant-ghost {
|
|
289
|
+
border: unset;
|
|
290
|
+
background: transparent;
|
|
291
|
+
color: var(--xz-color-fg-200);
|
|
292
|
+
}
|
|
293
|
+
@media (hover: hover) {
|
|
294
|
+
.xz-button.is-variant-ghost:focus {
|
|
295
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
.xz-button.is-variant-ghost.is-loading::after {
|
|
299
|
+
border-top-color: var(--xz-color-fg-200);
|
|
300
|
+
border-right-color: var(--xz-color-fg-200);
|
|
301
|
+
}
|
|
302
|
+
.xz-button.is-variant-white {
|
|
303
|
+
border: 1px solid var(--xz-color-line-100);
|
|
304
|
+
background: var(--xz-color-bg-100);
|
|
305
|
+
color: var(--xz-color-primary-fg-100);
|
|
306
|
+
}
|
|
307
|
+
@media (hover: hover) {
|
|
308
|
+
.xz-button.is-variant-white:focus {
|
|
309
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
.xz-button.is-variant-white.is-loading::after {
|
|
313
|
+
border-top-color: var(--xz-color-primary-fg-100);
|
|
314
|
+
border-right-color: var(--xz-color-primary-fg-100);
|
|
315
|
+
}
|
|
316
|
+
.xz-button.is-variant-white-secondary {
|
|
317
|
+
border: 1px solid var(--xz-color-white-alpha-1000);
|
|
318
|
+
background: transparent;
|
|
319
|
+
color: var(--xz-color-white-alpha-1000);
|
|
320
|
+
}
|
|
321
|
+
@media (hover: hover) {
|
|
322
|
+
.xz-button.is-variant-white-secondary:focus {
|
|
323
|
+
box-shadow: 0 0 0 0.175rem var(--xz-color-primary-line-200);
|
|
324
|
+
}
|
|
325
|
+
.xz-button.is-variant-white-secondary:hover {
|
|
326
|
+
border: 1px solid var(--xz-color-line-200);
|
|
327
|
+
color: var(--xz-color-white-alpha-1000);
|
|
328
|
+
}
|
|
329
|
+
.xz-button.is-variant-white-secondary:hover::before {
|
|
330
|
+
background: var(--xz-color-black-alpha-100);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
.xz-button.is-variant-white-secondary.is-loading::after {
|
|
334
|
+
border-top-color: var(--xz-color-white-alpha-1000);
|
|
335
|
+
border-right-color: var(--xz-color-white-alpha-1000);
|
|
336
|
+
}
|
|
337
|
+
.xz-button.is-loading {
|
|
338
|
+
color: transparent;
|
|
339
|
+
pointer-events: none;
|
|
340
|
+
}
|
|
341
|
+
.xz-button.is-loading::after {
|
|
342
|
+
content: "";
|
|
343
|
+
position: absolute;
|
|
344
|
+
right: 0;
|
|
345
|
+
left: 0;
|
|
346
|
+
width: 1em;
|
|
347
|
+
height: 1em;
|
|
348
|
+
margin: auto;
|
|
349
|
+
border: 2px solid;
|
|
350
|
+
border-top-color: var(--xz-color-primary-fg-50);
|
|
351
|
+
border-right-color: var(--xz-color-primary-fg-50);
|
|
352
|
+
border-radius: 999px;
|
|
353
|
+
animation: button-loading-spin 0.48s infinite linear;
|
|
354
|
+
}
|
|
355
|
+
.xz-button[disabled], .xz-button.is-disabled {
|
|
356
|
+
opacity: 0.6;
|
|
357
|
+
cursor: not-allowed;
|
|
358
|
+
}
|
|
359
|
+
.xz-button.is-fluid {
|
|
360
|
+
width: 100%;
|
|
361
|
+
}
|
|
362
|
+
.xz-button.is-pill {
|
|
363
|
+
border-radius: 999px;
|
|
364
|
+
}
|
|
365
|
+
.xz-button.is-square {
|
|
366
|
+
aspect-ratio: 1/1;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
@keyframes button-loading-spin {
|
|
370
|
+
from {
|
|
371
|
+
transform: rotate(0deg);
|
|
372
|
+
}
|
|
373
|
+
to {
|
|
374
|
+
transform: rotate(359deg);
|
|
375
|
+
}
|
|
376
|
+
}</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as Button } from './Button.svelte';
|
package/dist/index.d.ts
CHANGED
|
@@ -17,5 +17,7 @@
|
|
|
17
17
|
* import '@fastwork/xosmoz-svelte/styles.css';
|
|
18
18
|
* ```
|
|
19
19
|
*/
|
|
20
|
-
export { default as Button } from './components/Button.svelte';
|
|
21
|
-
export
|
|
20
|
+
export { default as Button } from './components/button/Button.svelte';
|
|
21
|
+
export { default as Badge } from './components/badge/Badge.svelte';
|
|
22
|
+
export type { ButtonProps, ButtonVariant, ButtonSize } from './components/button/Button.svelte';
|
|
23
|
+
export type { BadgeProps, BadgeVariant, BadgeSize } from './components/badge/Badge.svelte';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fastwork/xosmoz-svelte",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "Svelte 5 components for Xosmoz design system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"svelte": "./dist/index.js",
|
|
@@ -59,8 +59,15 @@
|
|
|
59
59
|
"eslint-config-prettier": "^10.1.8",
|
|
60
60
|
"eslint-plugin-svelte": "^3.12.4",
|
|
61
61
|
"globals": "^16.4.0",
|
|
62
|
+
"postcss-html": "^1.8.1",
|
|
63
|
+
"postcss-scss": "^4.0.9",
|
|
62
64
|
"prettier": "^3.6.2",
|
|
63
65
|
"prettier-plugin-svelte": "^3.4.0",
|
|
66
|
+
"sass": "^1.97.3",
|
|
67
|
+
"stylelint": "^16.26.1",
|
|
68
|
+
"stylelint-config-standard-scss": "^17.0.0",
|
|
69
|
+
"stylelint-order": "^7.0.1",
|
|
70
|
+
"stylelint-prettier": "^5.0.3",
|
|
64
71
|
"svelte": "^5.41.0",
|
|
65
72
|
"svelte-check": "^4.3.3",
|
|
66
73
|
"typescript": "^5.9.3",
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
<script lang="ts" module>
|
|
2
|
-
export type ButtonVariant =
|
|
3
|
-
| 'primary'
|
|
4
|
-
| 'secondary'
|
|
5
|
-
| 'outline'
|
|
6
|
-
| 'tertiary'
|
|
7
|
-
| 'ghost'
|
|
8
|
-
| 'danger'
|
|
9
|
-
| 'success'
|
|
10
|
-
| 'white'
|
|
11
|
-
| 'white-secondary'
|
|
12
|
-
|
|
13
|
-
export type ButtonSize = 'small' | 'medium' | 'large'
|
|
14
|
-
|
|
15
|
-
export interface ButtonProps {
|
|
16
|
-
/** Button variant style */
|
|
17
|
-
variant?: ButtonVariant
|
|
18
|
-
/** Button size */
|
|
19
|
-
size?: ButtonSize
|
|
20
|
-
/** Whether the button is disabled */
|
|
21
|
-
disabled?: boolean
|
|
22
|
-
/** Whether the button is in loading state */
|
|
23
|
-
loading?: boolean
|
|
24
|
-
/** Whether the button should take full width */
|
|
25
|
-
fluid?: boolean
|
|
26
|
-
/** Whether the button has pill-shaped border radius */
|
|
27
|
-
pill?: boolean
|
|
28
|
-
/** Whether the button should be square (1:1 aspect ratio) */
|
|
29
|
-
square?: boolean
|
|
30
|
-
/** Button type attribute */
|
|
31
|
-
type?: 'button' | 'submit' | 'reset'
|
|
32
|
-
/** Additional CSS classes */
|
|
33
|
-
class?: string
|
|
34
|
-
/** Click handler */
|
|
35
|
-
onclick?: (event: MouseEvent) => void
|
|
36
|
-
}
|
|
37
|
-
</script>
|
|
38
|
-
|
|
39
|
-
<script lang="ts">
|
|
40
|
-
import type { Snippet } from 'svelte'
|
|
41
|
-
|
|
42
|
-
interface Props extends ButtonProps {
|
|
43
|
-
/** Content before the main text */
|
|
44
|
-
startIcon?: Snippet
|
|
45
|
-
/** Main button content */
|
|
46
|
-
children: Snippet
|
|
47
|
-
/** Content after the main text */
|
|
48
|
-
endIcon?: Snippet
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
let {
|
|
52
|
-
variant = 'primary',
|
|
53
|
-
size = 'medium',
|
|
54
|
-
disabled = false,
|
|
55
|
-
loading = false,
|
|
56
|
-
fluid = false,
|
|
57
|
-
pill = false,
|
|
58
|
-
square = false,
|
|
59
|
-
type = 'button',
|
|
60
|
-
class: className = '',
|
|
61
|
-
onclick,
|
|
62
|
-
startIcon,
|
|
63
|
-
children,
|
|
64
|
-
endIcon,
|
|
65
|
-
}: Props = $props()
|
|
66
|
-
|
|
67
|
-
const buttonClasses = $derived.by(() => {
|
|
68
|
-
const classes = ['xz-button']
|
|
69
|
-
|
|
70
|
-
// Variant (only add class if not primary, which is the default)
|
|
71
|
-
if (variant !== 'primary') {
|
|
72
|
-
classes.push(`is-variant-${variant}`)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Size (only add class if not medium, which is the default)
|
|
76
|
-
if (size !== 'medium') {
|
|
77
|
-
classes.push(`is-size-${size}`)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// States
|
|
81
|
-
if (loading) classes.push('is-loading')
|
|
82
|
-
if (disabled) classes.push('is-disabled')
|
|
83
|
-
|
|
84
|
-
// Modifiers
|
|
85
|
-
if (fluid) classes.push('is-fluid')
|
|
86
|
-
if (pill) classes.push('is-pill')
|
|
87
|
-
if (square) classes.push('is-square')
|
|
88
|
-
|
|
89
|
-
// Custom classes
|
|
90
|
-
if (className) classes.push(className)
|
|
91
|
-
|
|
92
|
-
return classes.join(' ')
|
|
93
|
-
})
|
|
94
|
-
</script>
|
|
95
|
-
|
|
96
|
-
<button
|
|
97
|
-
class={buttonClasses}
|
|
98
|
-
{type}
|
|
99
|
-
disabled={disabled || loading}
|
|
100
|
-
aria-disabled={disabled || loading}
|
|
101
|
-
aria-busy={loading}
|
|
102
|
-
{onclick}
|
|
103
|
-
>
|
|
104
|
-
{#if startIcon}
|
|
105
|
-
<span class="start-icon">
|
|
106
|
-
{@render startIcon()}
|
|
107
|
-
</span>
|
|
108
|
-
{/if}
|
|
109
|
-
<span>
|
|
110
|
-
{@render children()}
|
|
111
|
-
</span>
|
|
112
|
-
{#if endIcon}
|
|
113
|
-
<span class="end-icon">
|
|
114
|
-
{@render endIcon()}
|
|
115
|
-
</span>
|
|
116
|
-
{/if}
|
|
117
|
-
</button>
|
|
File without changes
|