bref-ui 0.1.0 → 0.1.3

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.
@@ -163,13 +163,13 @@
163
163
 
164
164
  .foreground {
165
165
  --internal-current-color: var(--color-foreground);
166
- --internal-current-color-soft: var(--color-foreground-soft);
166
+ --internal-current-color-soft: var(--color-background-saturated);
167
167
  --internal-current-contrast: var(--color-background);
168
168
  }
169
169
 
170
170
  .background {
171
171
  --internal-current-color: var(--color-background);
172
- --internal-current-color-soft: var(--color-background-soft);
172
+ --internal-current-color-soft: var(--color-foreground-saturated);
173
173
  --internal-current-contrast: var(--color-foreground);
174
174
  }
175
175
 
@@ -230,4 +230,21 @@
230
230
  var(--color-background)
231
231
  );
232
232
  }
233
+
234
+ /* Background color ghost variant needs inverted hover colors */
235
+ .background.ghost:not(:disabled):hover {
236
+ background-color: color-mix(
237
+ in srgb,
238
+ var(--color-foreground) var(--internal-btn-ghost-hover-opacity),
239
+ var(--color-background)
240
+ );
241
+ }
242
+
243
+ .background.ghost:not(:disabled):active {
244
+ background-color: color-mix(
245
+ in srgb,
246
+ var(--color-foreground) var(--internal-btn-ghost-active-opacity),
247
+ var(--color-background)
248
+ );
249
+ }
233
250
  </style>
@@ -130,13 +130,13 @@
130
130
 
131
131
  .foreground {
132
132
  --internal-current-color: var(--color-foreground);
133
- --internal-current-color-soft: var(--color-foreground-soft);
133
+ --internal-current-color-soft: var(--color-background-saturated);
134
134
  --internal-current-contrast: var(--color-background);
135
135
  }
136
136
 
137
137
  .background {
138
138
  --internal-current-color: var(--color-background);
139
- --internal-current-color-soft: var(--color-background-soft);
139
+ --internal-current-color-soft: var(--color-foreground-saturated);
140
140
  --internal-current-contrast: var(--color-foreground);
141
141
  }
142
142
 
@@ -205,4 +205,21 @@
205
205
  var(--color-background)
206
206
  );
207
207
  }
208
+
209
+ /* Background color ghost variant needs inverted hover colors */
210
+ .background.ghost:not(:disabled):hover {
211
+ background-color: color-mix(
212
+ in srgb,
213
+ var(--color-foreground) var(--internal-btn-ghost-hover-opacity),
214
+ var(--color-background)
215
+ );
216
+ }
217
+
218
+ .background.ghost:not(:disabled):active {
219
+ background-color: color-mix(
220
+ in srgb,
221
+ var(--color-foreground) var(--internal-btn-ghost-active-opacity),
222
+ var(--color-background)
223
+ );
224
+ }
208
225
  </style>
@@ -1,16 +1,28 @@
1
1
  <script lang="ts">
2
- import type { LoadingProps } from './types.js';
3
-
4
- const { size = 'medium', color = 'primary' }: LoadingProps = $props();
2
+ import type { MorphingShapesLoadingProps } from './types.js';
3
+
4
+ const {
5
+ size = 'medium',
6
+ color = 'primary',
7
+ speed = 'normal',
8
+ isGradient = false,
9
+ pulseShadow = false
10
+ }: MorphingShapesLoadingProps = $props();
5
11
  </script>
6
12
 
7
- <div class={`${size} ${color}`} role="status" aria-label="Loading">
13
+ <div
14
+ class={`holder ${size} ${speed} ${isGradient ? 'gradient' : color} ${pulseShadow ? 'pulse-shadow' : ''}`}
15
+ role="status"
16
+ aria-label="Loading"
17
+ >
8
18
  <div class="shape"></div>
9
19
  </div>
10
20
 
11
21
  <style>
12
- div {
22
+ .holder {
13
23
  --internal-shape-size: 2rem;
24
+ --internal-morph-duration: 4s;
25
+ --internal-rotate-duration: 5s;
14
26
  width: var(--internal-shape-size);
15
27
  height: var(--internal-shape-size);
16
28
  }
@@ -18,61 +30,112 @@
18
30
  .shape {
19
31
  width: 100%;
20
32
  height: 100%;
21
- background-color: var(--internal-current-color);
33
+ background: var(--internal-current-color);
34
+ animation:
35
+ morph var(--internal-morph-duration) cubic-bezier(0.4, 0, 0.2, 1) infinite,
36
+ rotate var(--internal-rotate-duration) cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
37
+ }
38
+
39
+ .gradient .shape {
40
+ background: linear-gradient(
41
+ 135deg,
42
+ var(--color-primary),
43
+ var(--color-secondary),
44
+ var(--color-success),
45
+ var(--color-info),
46
+ var(--color-warning),
47
+ var(--color-danger),
48
+ var(--color-primary)
49
+ );
50
+ background-size: 600% 600%;
22
51
  animation:
23
- morph 4s ease-in-out infinite,
24
- rotate 8s linear infinite;
52
+ morph var(--internal-morph-duration) cubic-bezier(0.4, 0, 0.2, 1) infinite,
53
+ rotate var(--internal-rotate-duration) cubic-bezier(0.22, 0.61, 0.36, 1) infinite,
54
+ gradient-flow 12s ease-in-out infinite;
25
55
  }
26
56
 
27
- @keyframes morph {
57
+ @keyframes gradient-flow {
28
58
  0% {
29
- /* Circle */
59
+ background-position: 0% 50%;
60
+ }
61
+ 50% {
62
+ background-position: 100% 50%;
63
+ }
64
+ 100% {
65
+ background-position: 0% 50%;
66
+ }
67
+ }
68
+
69
+ @keyframes morph {
70
+ 0%,
71
+ 100% {
30
72
  border-radius: 50%;
31
73
  corner-shape: round;
74
+ transform: scale(1);
32
75
  }
33
- 14% {
34
- /* Squircle */
35
- border-radius: 35%;
76
+ 8% {
77
+ border-radius: 42% 58% 70% 30% / 45% 45% 55% 55%;
36
78
  corner-shape: squircle;
79
+ transform: scale(1.02);
80
+ }
81
+ 18% {
82
+ border-radius: 30%;
83
+ corner-shape: notch;
84
+ transform: scale(0.96);
37
85
  }
38
86
  28% {
39
- /* Blob with bevel corners */
40
87
  border-radius: 60% 40% 30% 70% / 60% 30% 70% 40%;
41
- corner-shape: bevel;
42
- }
43
- 42% {
44
- /* Scoop corners */
45
- border-radius: 40%;
46
- corner-shape: scoop;
47
- }
48
- 57% {
49
- /* Organic blob */
50
- border-radius: 40% 60% 70% 30% / 40% 50% 60% 50%;
51
88
  corner-shape: round;
89
+ transform: scale(1.04);
52
90
  }
53
- 71% {
54
- /* Notched */
55
- border-radius: 30%;
56
- corner-shape: notch;
91
+ 40% {
92
+ border-radius: 35%;
93
+ corner-shape: scoop;
94
+ transform: scale(0.98);
57
95
  }
58
- 85% {
59
- /* Another blob with squircle */
60
- border-radius: 70% 30% 50% 50% / 30% 60% 40% 70%;
96
+ 52% {
97
+ border-radius: 70% 30% 70% 30% / 30% 52% 48% 70%;
61
98
  corner-shape: squircle;
99
+ transform: scale(1.03);
62
100
  }
63
- 100% {
64
- /* Back to circle */
65
- border-radius: 50%;
101
+ 64% {
102
+ border-radius: 25% 75% 25% 75% / 75% 25% 75% 25%;
103
+ corner-shape: bevel;
104
+ transform: scale(0.95);
105
+ }
106
+ 76% {
107
+ border-radius: 50% 50% 30% 70% / 60% 40% 60% 40%;
66
108
  corner-shape: round;
109
+ transform: scale(1.05);
110
+ }
111
+ 88% {
112
+ border-radius: 40% 60% 50% 50% / 50% 60% 40% 50%;
113
+ corner-shape: squircle;
114
+ transform: scale(0.97);
67
115
  }
68
116
  }
69
117
 
70
118
  @keyframes rotate {
71
- from {
72
- transform: rotate(0deg);
119
+ 0% {
120
+ rotate: 0deg;
121
+ }
122
+ 15% {
123
+ rotate: 75deg;
124
+ }
125
+ 30% {
126
+ rotate: 110deg;
127
+ }
128
+ 50% {
129
+ rotate: 200deg;
130
+ }
131
+ 65% {
132
+ rotate: 280deg;
73
133
  }
74
- to {
75
- transform: rotate(360deg);
134
+ 80% {
135
+ rotate: 320deg;
136
+ }
137
+ 100% {
138
+ rotate: 360deg;
76
139
  }
77
140
  }
78
141
 
@@ -129,4 +192,47 @@
129
192
  .background {
130
193
  --internal-current-color: var(--color-background);
131
194
  }
195
+
196
+ /* Speed mappings */
197
+ .slow {
198
+ --internal-morph-duration: 6s;
199
+ --internal-rotate-duration: 7.5s;
200
+ }
201
+
202
+ .normal {
203
+ --internal-morph-duration: 4s;
204
+ --internal-rotate-duration: 5s;
205
+ }
206
+
207
+ .fast {
208
+ --internal-morph-duration: 2.4s;
209
+ --internal-rotate-duration: 3s;
210
+ }
211
+
212
+ /* Pulse shadow */
213
+ .pulse-shadow .shape {
214
+ --internal-shadow-size: calc(var(--internal-shape-size) * 0.5);
215
+ animation:
216
+ morph var(--internal-morph-duration) cubic-bezier(0.4, 0, 0.2, 1) infinite,
217
+ rotate var(--internal-rotate-duration) cubic-bezier(0.22, 0.61, 0.36, 1) infinite,
218
+ pulse-shadow 2s ease-in-out infinite;
219
+ }
220
+
221
+ .pulse-shadow.gradient .shape {
222
+ animation:
223
+ morph var(--internal-morph-duration) cubic-bezier(0.4, 0, 0.2, 1) infinite,
224
+ rotate var(--internal-rotate-duration) cubic-bezier(0.22, 0.61, 0.36, 1) infinite,
225
+ gradient-flow 12s ease-in-out infinite,
226
+ pulse-shadow 2s ease-in-out infinite;
227
+ }
228
+
229
+ @keyframes pulse-shadow {
230
+ 0%,
231
+ 100% {
232
+ box-shadow: 0 0 var(--internal-shadow-size) color-mix(in srgb, var(--color-foreground) 15%, transparent);
233
+ }
234
+ 50% {
235
+ box-shadow: 0 0 var(--internal-shadow-size) color-mix(in srgb, var(--color-foreground) 35%, transparent);
236
+ }
237
+ }
132
238
  </style>
@@ -1,4 +1,4 @@
1
- import type { LoadingProps } from './types.ts';
2
- declare const MorphingShapesLoading: import("svelte").Component<LoadingProps, {}, "">;
1
+ import type { MorphingShapesLoadingProps } from './types.ts';
2
+ declare const MorphingShapesLoading: import("svelte").Component<MorphingShapesLoadingProps, {}, "">;
3
3
  type MorphingShapesLoading = ReturnType<typeof MorphingShapesLoading>;
4
4
  export default MorphingShapesLoading;
@@ -9,3 +9,8 @@ export interface TextualLoadingProps extends LoadingProps {
9
9
  typeSpeed?: Speed;
10
10
  pauseSpeed?: Speed;
11
11
  }
12
+ export interface MorphingShapesLoadingProps extends LoadingProps {
13
+ speed?: Speed;
14
+ isGradient?: boolean;
15
+ pulseShadow?: boolean;
16
+ }
@@ -25,9 +25,9 @@
25
25
  <IconButton
26
26
  {onClick}
27
27
  size="x-small"
28
- color={hasCopied ? 'success' : 'primary'}
29
- variant={hasCopied ? 'filled' : 'soft'}
30
- filled
28
+ color={hasCopied ? 'success' : 'foreground'}
29
+ variant={hasCopied ? 'filled' : 'ghost'}
30
+ rounded
31
31
  name={hasCopied ? 'check' : 'copy_all'}
32
32
  disabled={hasCopied}
33
33
  />
@@ -59,7 +59,8 @@
59
59
  code,
60
60
  pre {
61
61
  width: 100%;
62
- flex: 1; align-self: center;
62
+ flex: 1;
63
+ align-self: center;
63
64
  height: fit-content;
64
65
  }
65
66
  pre {
@@ -1,9 +1,13 @@
1
+ <script lang="ts">
2
+ import { asset } from '$app/paths';
3
+ </script>
4
+
1
5
  <div class="logo">
2
6
  <div class="icon">
3
- <img src={'favicon.svg'} alt="Logo" />
7
+ <img src={asset('/favicon.svg')} alt="Logo" />
4
8
  <span>Bref</span>
5
9
  </div>
6
-
10
+
7
11
  <p>A truly Svelte-esque UI Component Library.</p>
8
12
  </div>
9
13
 
@@ -1,18 +1,5 @@
1
- export default Logo;
2
- type Logo = SvelteComponent<{
3
- [x: string]: never;
4
- }, {
5
- [evt: string]: CustomEvent<any>;
6
- }, {}> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const Logo: $$__sveltets_2_IsomorphicComponent<{
10
- [x: string]: never;
11
- }, {
12
- [evt: string]: CustomEvent<any>;
13
- }, {}, {}, string>;
14
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> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
16
3
  $$bindings?: Bindings;
17
4
  } & Exports;
18
5
  (internal: unknown, props: {
@@ -24,3 +11,8 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
24
11
  };
25
12
  z_$$bindings?: Bindings;
26
13
  }
14
+ declare const Logo: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type Logo = InstanceType<typeof Logo>;
18
+ export default Logo;
@@ -5,7 +5,7 @@
5
5
  import { page } from '$app/state';
6
6
  import TreeView from '../../../base/tree-view/tree-view.svelte';
7
7
  import type { NodeDataProps } from '../../../index.js';
8
- import { goto } from '$app/navigation';
8
+ import navigateTo from '../../../internal/navigate.js';
9
9
 
10
10
  const pageToNode = (page: PageProps): NodeDataProps => ({
11
11
  id: page.href,
@@ -18,7 +18,7 @@
18
18
  return allPages.find((p) => page.url.pathname.endsWith(p.href)) ?? PAGES[0];
19
19
  });
20
20
  const selectedIds = $derived(new Set([selectedPage.href]));
21
- const onSelect = (href: string) => goto(href);
21
+ const onSelect = (href: string) => navigateTo(href);
22
22
  </script>
23
23
 
24
24
  <div class="container">
@@ -7,77 +7,77 @@ export const PAGES = [
7
7
  },
8
8
  {
9
9
  title: 'Theming',
10
- description: 'Customize colors and modes',
10
+ description: "Bref's theming system uses CSS custom properties for complete flexibility",
11
11
  href: '/theming',
12
12
  icon: 'palette'
13
13
  },
14
14
  {
15
15
  title: 'Generic Types',
16
- description: 'Shared types for components',
16
+ description: 'Shared TypeScript types used across components for consistent styling and behavior',
17
17
  href: '/types',
18
18
  icon: 'data_object'
19
19
  },
20
20
  {
21
21
  title: 'Icon',
22
- description: 'Material Symbols icons with various sizes, colors, and fill options',
22
+ description: 'Icons with customizable size, color, and fill. Based on Google Material Symbols',
23
23
  href: '/icon',
24
24
  icon: 'emoji_symbols'
25
25
  },
26
26
  {
27
27
  title: 'Buttons',
28
- description: '2 types of buttons: Icon Button and a `Normal` Button',
28
+ description: 'Full-featured buttons with labels and icons, or compact icon-only buttons',
29
29
  href: '/buttons',
30
30
  icon: 'touch_app',
31
31
  children: [
32
32
  {
33
- title: 'Icon Button',
34
- description: 'Icon Button for buttons with only an icon',
35
- href: '/icon-button',
36
- icon: 'adjust'
33
+ title: 'Button',
34
+ description: 'Buttons with customizable size, color, variant, and optional icons',
35
+ href: '/buttons/button',
36
+ icon: 'buttons_alt'
37
37
  },
38
38
  {
39
- title: '(Normal) Button',
40
- description: 'A button with label and optional icon',
41
- href: '/button',
42
- icon: 'buttons_alt'
39
+ title: 'Icon Button',
40
+ description: 'Icon buttons with customizable size, color, variant, and shape',
41
+ href: '/buttons/icon-button',
42
+ icon: 'adjust'
43
43
  }
44
44
  ]
45
45
  },
46
46
  {
47
47
  title: 'Loading',
48
- description: 'Loading indicators to a state that content is being loaded',
48
+ description: 'Multiple loading indicator styles for different visual contexts',
49
49
  href: '/loadings',
50
50
  icon: 'hourglass_empty',
51
51
  children: [
52
52
  {
53
53
  title: 'Circular',
54
- description: 'A spinning circular indicator for general loading states with customizable size and color',
55
- href: '/circular-loading',
54
+ description: 'A classic spinning circle indicator for loading states',
55
+ href: '/loadings/circular',
56
56
  icon: 'autorenew'
57
57
  },
58
58
  {
59
59
  title: 'Pulsing Dots',
60
- description: 'Animated dots that pulse in sequence, ideal for chat or messaging interfaces',
61
- href: '/pulsing-dots-loading',
60
+ description: 'Three dots that pulse in sequence to indicate loading',
61
+ href: '/loadings/pulsing-dots',
62
62
  icon: 'more_horiz'
63
63
  },
64
64
  {
65
65
  title: 'Morphing Shapes',
66
- description: 'Smooth shape transitions creating a fluid animation effect for creative loading states',
67
- href: '/morphing-shapes-loading',
66
+ description: 'A shape that transforms through organic forms while rotating',
67
+ href: '/loadings/morphing-shapes',
68
68
  icon: 'animation'
69
69
  },
70
70
  {
71
71
  title: 'Textual',
72
- description: 'Text-based loading indicator with customizable messages and animated ellipsis',
73
- href: '/textual-loading',
72
+ description: 'Animated text with a typewriter effect that cycles through words',
73
+ href: '/loadings/textual',
74
74
  icon: 'text_fields'
75
75
  }
76
76
  ]
77
77
  },
78
78
  {
79
- title: 'TreeView',
80
- description: 'Hierarchical tree component for displaying nested data structures with expandable nodes',
79
+ title: 'Tree View',
80
+ description: 'A hierarchical tree component for displaying nested data structures',
81
81
  href: '/tree-view',
82
82
  icon: 'account_tree'
83
83
  }
@@ -0,0 +1,2 @@
1
+ declare const navigateTo: (href: string) => any;
2
+ export default navigateTo;
@@ -0,0 +1,4 @@
1
+ import { goto } from "$app/navigation";
2
+ import { resolve } from "$app/paths";
3
+ const navigateTo = (href) => goto(resolve(href));
4
+ export default navigateTo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bref-ui",
3
- "version": "0.1.0",
3
+ "version": "0.1.3",
4
4
  "description": "A truly Svelte-esque UI component library - minimal, flexible, pure CSS, no Tailwind",
5
5
  "license": "MIT",
6
6
  "author": "feuerstein",