@x33025/sveltely 0.1.1 → 0.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.
Files changed (101) hide show
  1. package/dist/components/Library/Button/Button.demo.svelte +5 -3
  2. package/dist/components/Library/Button/Button.demo.svelte.d.ts +1 -0
  3. package/dist/components/Library/Calendar/Calendar.demo.svelte +2 -14
  4. package/dist/components/Library/Calendar/Calendar.svelte +54 -50
  5. package/dist/components/Library/Divider/Divider.svelte +10 -0
  6. package/dist/components/Library/Divider/Divider.svelte.d.ts +26 -0
  7. package/dist/components/Library/Divider/index.d.ts +1 -0
  8. package/dist/components/Library/Divider/index.js +1 -0
  9. package/dist/components/Library/Dropdown/Dropdown.demo.svelte +10 -3
  10. package/dist/components/Library/Dropdown/Dropdown.svelte +39 -5
  11. package/dist/components/Library/Dropdown/index.d.ts +1 -1
  12. package/dist/components/Library/Dropdown/types.d.ts +4 -1
  13. package/dist/components/Library/Floating/Floating.svelte +35 -1
  14. package/dist/components/Library/ForEach/ForEach.svelte +14 -0
  15. package/dist/components/Library/ForEach/ForEach.svelte.d.ts +28 -0
  16. package/dist/components/Library/ForEach/index.d.ts +1 -0
  17. package/dist/components/Library/ForEach/index.js +1 -0
  18. package/dist/components/Library/Grid/Grid.svelte +74 -0
  19. package/dist/components/Library/Grid/Grid.svelte.d.ts +13 -0
  20. package/dist/components/Library/Grid/index.d.ts +1 -0
  21. package/dist/components/Library/Grid/index.js +1 -0
  22. package/dist/components/Library/GridItem/GridItem.svelte +65 -0
  23. package/dist/components/Library/GridItem/GridItem.svelte.d.ts +14 -0
  24. package/dist/components/Library/GridItem/index.d.ts +1 -0
  25. package/dist/components/Library/GridItem/index.js +1 -0
  26. package/dist/components/Library/HStack/HStack.svelte +45 -0
  27. package/dist/components/Library/HStack/HStack.svelte.d.ts +9 -0
  28. package/dist/components/Library/HStack/index.d.ts +1 -0
  29. package/dist/components/Library/HStack/index.js +1 -0
  30. package/dist/components/Library/Image/Image.demo.svelte +18 -0
  31. package/dist/components/Library/Image/Image.demo.svelte.d.ts +23 -0
  32. package/dist/components/Library/Image/Image.svelte +57 -0
  33. package/dist/components/Library/Image/Image.svelte.d.ts +17 -0
  34. package/dist/components/Library/Image/ImagePlaceholder.svelte +202 -0
  35. package/dist/components/Library/Image/ImagePlaceholder.svelte.d.ts +7 -0
  36. package/dist/components/Library/Image/index.d.ts +1 -0
  37. package/dist/components/Library/Image/index.js +1 -0
  38. package/dist/components/Library/ImageMask/BrushPreview.svelte +119 -0
  39. package/dist/components/Library/ImageMask/BrushPreview.svelte.d.ts +11 -0
  40. package/dist/components/Library/ImageMask/ImageMask.demo.svelte +117 -0
  41. package/dist/components/Library/ImageMask/ImageMask.demo.svelte.d.ts +10 -0
  42. package/dist/components/Library/ImageMask/ImageMask.svelte +46 -0
  43. package/dist/components/Library/ImageMask/ImageMask.svelte.d.ts +20 -0
  44. package/dist/components/Library/ImageMask/MaskLayer.svelte +341 -0
  45. package/dist/components/Library/ImageMask/MaskLayer.svelte.d.ts +12 -0
  46. package/dist/components/Library/ImageMask/contour.d.ts +11 -0
  47. package/dist/components/Library/ImageMask/contour.js +152 -0
  48. package/dist/components/Library/ImageMask/index.d.ts +2 -0
  49. package/dist/components/Library/ImageMask/index.js +1 -0
  50. package/dist/components/Library/ImageMask/marchingAnts.d.ts +8 -0
  51. package/dist/components/Library/ImageMask/marchingAnts.js +29 -0
  52. package/dist/components/Library/ImageMask/maskSurface.d.ts +5 -0
  53. package/dist/components/Library/ImageMask/maskSurface.js +94 -0
  54. package/dist/components/Library/ImageMask/types.d.ts +23 -0
  55. package/dist/components/Library/ImageMask/types.js +1 -0
  56. package/dist/components/Library/Label/Label.demo.svelte +28 -0
  57. package/dist/components/Library/Label/Label.demo.svelte.d.ts +9 -0
  58. package/dist/components/Library/Label/Label.svelte +177 -0
  59. package/dist/components/Library/Label/Label.svelte.d.ts +18 -0
  60. package/dist/components/Library/Label/index.d.ts +1 -0
  61. package/dist/components/Library/Label/index.js +1 -0
  62. package/dist/components/Library/NumberField/NumberField.demo.svelte +21 -0
  63. package/dist/components/Library/NumberField/NumberField.demo.svelte.d.ts +8 -0
  64. package/dist/components/Library/NumberField/NumberField.svelte +194 -0
  65. package/dist/components/Library/NumberField/NumberField.svelte.d.ts +21 -0
  66. package/dist/components/Library/NumberField/index.d.ts +1 -0
  67. package/dist/components/Library/NumberField/index.js +1 -0
  68. package/dist/components/Library/ScrollView/ScrollView.svelte +25 -9
  69. package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +4 -4
  70. package/dist/components/Library/Spacer/Spacer.svelte +7 -0
  71. package/dist/components/Library/Spacer/Spacer.svelte.d.ts +26 -0
  72. package/dist/components/Library/Spacer/index.d.ts +1 -0
  73. package/dist/components/Library/Spacer/index.js +1 -0
  74. package/dist/components/Library/TextField/TextField.demo.svelte +14 -0
  75. package/dist/components/Library/TextField/TextField.demo.svelte.d.ts +8 -0
  76. package/dist/components/Library/TextField/TextField.svelte +149 -0
  77. package/dist/components/Library/TextField/TextField.svelte.d.ts +19 -0
  78. package/dist/components/Library/TextField/index.d.ts +1 -0
  79. package/dist/components/Library/TextField/index.js +1 -0
  80. package/dist/components/Library/VStack/VStack.svelte +45 -0
  81. package/dist/components/Library/VStack/VStack.svelte.d.ts +9 -0
  82. package/dist/components/Library/VStack/index.d.ts +1 -0
  83. package/dist/components/Library/VStack/index.js +1 -0
  84. package/dist/components/Local/ComponentGrid.svelte +15 -31
  85. package/dist/components/Local/HeroCard.svelte +26 -36
  86. package/dist/components/Local/HeroCard.svelte.d.ts +0 -2
  87. package/dist/index.d.ts +23 -0
  88. package/dist/index.js +17 -0
  89. package/dist/style/index.css +28 -17
  90. package/dist/style/label.d.ts +6 -0
  91. package/dist/style/label.js +4 -0
  92. package/dist/style/layout.d.ts +57 -0
  93. package/dist/style/layout.js +128 -0
  94. package/dist/style/media.d.ts +12 -0
  95. package/dist/style/media.js +8 -0
  96. package/dist/style/scroll.d.ts +7 -0
  97. package/dist/style/scroll.js +5 -0
  98. package/dist/style/text-editor.d.ts +34 -0
  99. package/dist/style/text-editor.js +29 -0
  100. package/dist/style.css +58 -35
  101. package/package.json +1 -1
@@ -0,0 +1,194 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ import { tooltip } from '../../../actions/tooltip';
4
+ import { surfaceStyle, type StyleProps } from '../../../style/surface';
5
+ import {
6
+ textEditorStyle,
7
+ type TextEditorProps,
8
+ type TextInputMode
9
+ } from '../../../style/text-editor';
10
+
11
+ type Props = {
12
+ value?: number | null;
13
+ help?: string;
14
+ error?: string | null;
15
+ disabled?: boolean;
16
+ placeholder?: string;
17
+ name?: string;
18
+ autocomplete?: HTMLInputAttributes['autocomplete'];
19
+ required?: boolean;
20
+ readonly?: boolean;
21
+ inputmode?: Extract<TextInputMode, 'numeric' | 'decimal'>;
22
+ min?: number;
23
+ max?: number;
24
+ step?: number | 'any';
25
+ } & StyleProps &
26
+ TextEditorProps;
27
+
28
+ let {
29
+ value = $bindable(null),
30
+ help,
31
+ error = null,
32
+ disabled = false,
33
+ placeholder = '',
34
+ name,
35
+ autocomplete,
36
+ required = false,
37
+ readonly = false,
38
+ inputmode = 'decimal',
39
+ min,
40
+ max,
41
+ step,
42
+ textAlign = 'right',
43
+ fontSize,
44
+ paddingX,
45
+ paddingY,
46
+ gap,
47
+ borderRadius,
48
+ inset,
49
+ background,
50
+ borderColor,
51
+ color
52
+ }: Props = $props();
53
+
54
+ const styleProps = $derived({
55
+ fontSize,
56
+ paddingX,
57
+ paddingY,
58
+ gap,
59
+ borderRadius,
60
+ inset,
61
+ background,
62
+ borderColor,
63
+ color
64
+ });
65
+ const textEditorProps = $derived({ textAlign });
66
+ const rootStyle = $derived.by(() =>
67
+ [surfaceStyle(styleProps, 'text-field'), textEditorStyle(textEditorProps)].filter(Boolean).join(' ')
68
+ );
69
+ const describedBy = $derived(help ? 'text-field-message' : undefined);
70
+
71
+ let draftValue = $state(formatValue(value));
72
+ let committedValue = $state(value);
73
+
74
+ $effect(() => {
75
+ if (value !== committedValue) {
76
+ draftValue = formatValue(value);
77
+ committedValue = value;
78
+ }
79
+ });
80
+
81
+ function formatValue(nextValue: number | null | undefined) {
82
+ return nextValue === null || nextValue === undefined ? '' : String(nextValue);
83
+ }
84
+
85
+ function handleInput(event: Event) {
86
+ const input = event.currentTarget as HTMLInputElement;
87
+ const nextValue = input.value;
88
+
89
+ draftValue = nextValue;
90
+
91
+ if (nextValue === '') {
92
+ value = null;
93
+ committedValue = null;
94
+ return;
95
+ }
96
+
97
+ const numericValue = Number(nextValue);
98
+
99
+ if (!input.validity.badInput && Number.isFinite(numericValue)) {
100
+ value = numericValue;
101
+ committedValue = numericValue;
102
+ }
103
+ }
104
+
105
+ function handleBlur() {
106
+ if (draftValue !== formatValue(value)) {
107
+ draftValue = formatValue(value);
108
+ }
109
+ }
110
+ </script>
111
+
112
+ <div
113
+ use:tooltip={{ label: error ?? '', disabled: !error }}
114
+ class="text-field"
115
+ style={rootStyle}
116
+ data-disabled={disabled ? 'true' : 'false'}
117
+ data-error={error ? 'true' : 'false'}
118
+ >
119
+ <input
120
+ value={draftValue}
121
+ type="number"
122
+ {disabled}
123
+ {name}
124
+ {autocomplete}
125
+ {required}
126
+ {readonly}
127
+ {inputmode}
128
+ {placeholder}
129
+ {min}
130
+ {max}
131
+ {step}
132
+ aria-invalid={error ? 'true' : undefined}
133
+ aria-describedby={describedBy}
134
+ class="text-field-input"
135
+ oninput={handleInput}
136
+ onblur={handleBlur}
137
+ />
138
+
139
+ {#if help}
140
+ <span id="text-field-message" class="text-field-message">{help}</span>
141
+ {/if}
142
+ </div>
143
+
144
+ <style>
145
+ .text-field {
146
+ display: inline-flex;
147
+ width: 100%;
148
+ min-width: 0;
149
+ flex-direction: column;
150
+ gap: var(--text-field-gap, calc(var(--sveltely-gap) * 0.75));
151
+ color: var(--text-field-color, var(--color-zinc-900));
152
+ font-size: var(--text-field-font-size, calc(var(--sveltely-font-size) * 0.875));
153
+ }
154
+
155
+ .text-field-input {
156
+ width: 100%;
157
+ min-width: 0;
158
+ border: 1px solid var(--text-field-border-color, var(--sveltely-border-color));
159
+ border-radius: var(--text-field-border-radius, var(--sveltely-border-radius));
160
+ background: var(--text-field-background, white);
161
+ color: inherit;
162
+ font-variant-numeric: tabular-nums;
163
+ line-height: 1.25rem;
164
+ outline: none;
165
+ padding:
166
+ var(--text-field-padding-y, calc(var(--sveltely-padding-y) * 0.67))
167
+ var(--text-field-padding-x, var(--sveltely-padding-x));
168
+ text-align: var(--text-field-text-align, start);
169
+ transition: color 150ms, border-color 150ms, background-color 150ms, box-shadow 150ms;
170
+ }
171
+
172
+ .text-field-input:focus {
173
+ border-color: color-mix(in oklab, var(--sveltely-primary-color) 50%, white);
174
+ }
175
+
176
+ .text-field-input::placeholder {
177
+ color: var(--color-zinc-400);
178
+ }
179
+
180
+ .text-field-message {
181
+ color: var(--color-zinc-500);
182
+ font-size: calc(var(--text-field-font-size, 0.875rem) * 0.857);
183
+ line-height: 1.25;
184
+ }
185
+
186
+ .text-field[data-error='true'] .text-field-input {
187
+ border-color: var(--color-red-500);
188
+ }
189
+
190
+ .text-field[data-disabled='true'] {
191
+ cursor: not-allowed;
192
+ opacity: 0.6;
193
+ }
194
+ </style>
@@ -0,0 +1,21 @@
1
+ import type { HTMLInputAttributes } from 'svelte/elements';
2
+ import { type StyleProps } from '../../../style/surface';
3
+ import { type TextEditorProps, type TextInputMode } from '../../../style/text-editor';
4
+ type Props = {
5
+ value?: number | null;
6
+ help?: string;
7
+ error?: string | null;
8
+ disabled?: boolean;
9
+ placeholder?: string;
10
+ name?: string;
11
+ autocomplete?: HTMLInputAttributes['autocomplete'];
12
+ required?: boolean;
13
+ readonly?: boolean;
14
+ inputmode?: Extract<TextInputMode, 'numeric' | 'decimal'>;
15
+ min?: number;
16
+ max?: number;
17
+ step?: number | 'any';
18
+ } & StyleProps & TextEditorProps;
19
+ declare const NumberField: import("svelte").Component<Props, {}, "value">;
20
+ type NumberField = ReturnType<typeof NumberField>;
21
+ export default NumberField;
@@ -0,0 +1 @@
1
+ export { default } from './NumberField.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './NumberField.svelte';
@@ -1,25 +1,42 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
- import { extractStyleProps, surfaceStyle, type StyleProps } from '../../../style/surface';
3
+ import { surfaceStyle, type StyleProps } from '../../../style/surface';
4
+ import type { ScrollAxis } from '../../../style/scroll';
4
5
 
5
6
  type Props = {
6
7
  children: Snippet;
7
8
  viewport?: HTMLElement | null;
8
- axis?: 'vertical' | 'horizontal' | 'both';
9
+ axis?: ScrollAxis;
9
10
  contentStyles?: StyleProps;
10
- };
11
+ } & StyleProps;
11
12
 
12
13
  let {
13
14
  children,
14
15
  viewport = $bindable<HTMLElement | null>(null),
15
16
  axis = 'vertical',
16
17
  contentStyles = {},
17
- ...restProps
18
- }: Props & StyleProps & Record<string, unknown> = $props();
18
+ fontSize,
19
+ paddingX,
20
+ paddingY,
21
+ gap,
22
+ borderRadius,
23
+ inset,
24
+ background,
25
+ borderColor,
26
+ color
27
+ }: Props = $props();
19
28
 
20
- const extractedStyleProps = $derived.by(() => extractStyleProps(restProps));
21
- const styleProps = $derived(extractedStyleProps.styleProps);
22
- const props = $derived(extractedStyleProps.restProps);
29
+ const styleProps = $derived({
30
+ fontSize,
31
+ paddingX,
32
+ paddingY,
33
+ gap,
34
+ borderRadius,
35
+ inset,
36
+ background,
37
+ borderColor,
38
+ color
39
+ });
23
40
  const viewportStyle = $derived.by(() => surfaceStyle(styleProps, 'scroll-view'));
24
41
  const contentStyle = $derived.by(() => surfaceStyle(contentStyles, 'scroll-view-content'));
25
42
  </script>
@@ -31,7 +48,6 @@
31
48
  class:scroll-view-horizontal={axis === 'horizontal'}
32
49
  class:scroll-view-both={axis === 'both'}
33
50
  style={viewportStyle}
34
- {...props}
35
51
  >
36
52
  <div class="scroll-view-content" style={contentStyle}>
37
53
  {@render children()}
@@ -1,12 +1,12 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import { type StyleProps } from '../../../style/surface';
3
+ import type { ScrollAxis } from '../../../style/scroll';
3
4
  type Props = {
4
5
  children: Snippet;
5
6
  viewport?: HTMLElement | null;
6
- axis?: 'vertical' | 'horizontal' | 'both';
7
+ axis?: ScrollAxis;
7
8
  contentStyles?: StyleProps;
8
- };
9
- type $$ComponentProps = Props & StyleProps & Record<string, unknown>;
10
- declare const ScrollView: import("svelte").Component<$$ComponentProps, {}, "viewport">;
9
+ } & StyleProps;
10
+ declare const ScrollView: import("svelte").Component<Props, {}, "viewport">;
11
11
  type ScrollView = ReturnType<typeof ScrollView>;
12
12
  export default ScrollView;
@@ -0,0 +1,7 @@
1
+ <div class="spacer"></div>
2
+
3
+ <style>
4
+ .spacer {
5
+ flex: 1 1 auto;
6
+ }
7
+ </style>
@@ -0,0 +1,26 @@
1
+ export default Spacer;
2
+ type Spacer = SvelteComponent<{
3
+ [x: string]: never;
4
+ }, {
5
+ [evt: string]: CustomEvent<any>;
6
+ }, {}> & {
7
+ $$bindings?: string | undefined;
8
+ };
9
+ declare const Spacer: $$__sveltets_2_IsomorphicComponent<{
10
+ [x: string]: never;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}, {}, string>;
14
+ 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> & {
16
+ $$bindings?: Bindings;
17
+ } & Exports;
18
+ (internal: unknown, props: {
19
+ $$events?: Events;
20
+ $$slots?: Slots;
21
+ }): Exports & {
22
+ $set?: any;
23
+ $on?: any;
24
+ };
25
+ z_$$bindings?: Bindings;
26
+ }
@@ -0,0 +1 @@
1
+ export { default } from './Spacer.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './Spacer.svelte';
@@ -0,0 +1,14 @@
1
+ <script module lang="ts">
2
+ export const demo = {
3
+ name: 'TextField',
4
+ description: 'Token-aware text input with help and error states.'
5
+ };
6
+ </script>
7
+
8
+ <script lang="ts">
9
+ import TextField from './TextField.svelte';
10
+
11
+ let value = $state('Sveltely');
12
+ </script>
13
+
14
+ <TextField bind:value placeholder="Enter name" help="Value: {value}" />
@@ -0,0 +1,8 @@
1
+ export declare const demo: {
2
+ name: string;
3
+ description: string;
4
+ };
5
+ import TextField from './TextField.svelte';
6
+ declare const TextField: import("svelte").Component<Record<string, never>, {}, "">;
7
+ type TextField = ReturnType<typeof TextField>;
8
+ export default TextField;
@@ -0,0 +1,149 @@
1
+ <script lang="ts">
2
+ import type { HTMLInputAttributes } from 'svelte/elements';
3
+ import { tooltip } from '../../../actions/tooltip';
4
+ import { surfaceStyle, type StyleProps } from '../../../style/surface';
5
+ import {
6
+ textEditorStyle,
7
+ type TextEditorProps,
8
+ type TextFieldType,
9
+ type TextInputMode
10
+ } from '../../../style/text-editor';
11
+
12
+ type Props = {
13
+ value?: string;
14
+ help?: string;
15
+ error?: string | null;
16
+ type?: TextFieldType;
17
+ disabled?: boolean;
18
+ placeholder?: string;
19
+ name?: string;
20
+ autocomplete?: HTMLInputAttributes['autocomplete'];
21
+ required?: boolean;
22
+ readonly?: boolean;
23
+ inputmode?: TextInputMode;
24
+ } & StyleProps &
25
+ TextEditorProps;
26
+
27
+ let {
28
+ value = $bindable(''),
29
+ help,
30
+ error = null,
31
+ type = 'text',
32
+ disabled = false,
33
+ placeholder = '',
34
+ name,
35
+ autocomplete,
36
+ required = false,
37
+ readonly = false,
38
+ inputmode,
39
+ textAlign,
40
+ fontSize,
41
+ paddingX,
42
+ paddingY,
43
+ gap,
44
+ borderRadius,
45
+ inset,
46
+ background,
47
+ borderColor,
48
+ color
49
+ }: Props = $props();
50
+
51
+ const styleProps = $derived({
52
+ fontSize,
53
+ paddingX,
54
+ paddingY,
55
+ gap,
56
+ borderRadius,
57
+ inset,
58
+ background,
59
+ borderColor,
60
+ color
61
+ });
62
+ const textEditorProps = $derived({ textAlign });
63
+ const rootStyle = $derived.by(() =>
64
+ [surfaceStyle(styleProps, 'text-field'), textEditorStyle(textEditorProps)].filter(Boolean).join(' ')
65
+ );
66
+ const describedBy = $derived(help ? 'text-field-message' : undefined);
67
+ </script>
68
+
69
+ <div
70
+ use:tooltip={{ label: error ?? '', disabled: !error }}
71
+ class="text-field"
72
+ style={rootStyle}
73
+ data-disabled={disabled ? 'true' : 'false'}
74
+ data-error={error ? 'true' : 'false'}
75
+ >
76
+ <input
77
+ bind:value
78
+ {type}
79
+ {disabled}
80
+ {name}
81
+ {autocomplete}
82
+ {required}
83
+ {readonly}
84
+ {inputmode}
85
+ {placeholder}
86
+ aria-invalid={error ? 'true' : undefined}
87
+ aria-describedby={describedBy}
88
+ class="text-field-input"
89
+ />
90
+
91
+ {#if help}
92
+ <span id="text-field-message" class="text-field-message">{help}</span>
93
+ {/if}
94
+ </div>
95
+
96
+ <style>
97
+ .text-field {
98
+ display: inline-flex;
99
+ width: 100%;
100
+ min-width: 0;
101
+ flex-direction: column;
102
+ gap: var(--text-field-gap, calc(var(--sveltely-gap) * 0.75));
103
+ color: var(--text-field-color, var(--color-zinc-900));
104
+ font-size: var(--text-field-font-size, calc(var(--sveltely-font-size) * 0.875));
105
+ }
106
+
107
+ .text-field-input {
108
+ width: 100%;
109
+ min-width: 0;
110
+ border: 1px solid var(--text-field-border-color, var(--sveltely-border-color));
111
+ border-radius: var(--text-field-border-radius, var(--sveltely-border-radius));
112
+ background: var(--text-field-background, white);
113
+ color: inherit;
114
+ line-height: 1.25rem;
115
+ outline: none;
116
+ padding:
117
+ var(--text-field-padding-y, calc(var(--sveltely-padding-y) * 0.67))
118
+ var(--text-field-padding-x, var(--sveltely-padding-x));
119
+ text-align: var(--text-field-text-align, start);
120
+ transition: color 150ms, border-color 150ms, background-color 150ms, box-shadow 150ms;
121
+ }
122
+
123
+ .text-field-input:focus {
124
+ border-color: color-mix(in oklab, var(--sveltely-primary-color) 50%, white);
125
+ }
126
+
127
+ .text-field-input::placeholder {
128
+ color: var(--color-zinc-400);
129
+ }
130
+
131
+ .text-field-message {
132
+ color: var(--color-zinc-500);
133
+ font-size: calc(var(--text-field-font-size, 0.875rem) * 0.857);
134
+ line-height: 1.25;
135
+ }
136
+
137
+ .text-field[data-error='true'] .text-field-input {
138
+ border-color: var(--color-red-500);
139
+ }
140
+
141
+ .text-field[data-error='true'] .text-field-message {
142
+ color: var(--color-red-600);
143
+ }
144
+
145
+ .text-field[data-disabled='true'] {
146
+ cursor: not-allowed;
147
+ opacity: 0.6;
148
+ }
149
+ </style>
@@ -0,0 +1,19 @@
1
+ import type { HTMLInputAttributes } from 'svelte/elements';
2
+ import { type StyleProps } from '../../../style/surface';
3
+ import { type TextEditorProps, type TextFieldType, type TextInputMode } from '../../../style/text-editor';
4
+ type Props = {
5
+ value?: string;
6
+ help?: string;
7
+ error?: string | null;
8
+ type?: TextFieldType;
9
+ disabled?: boolean;
10
+ placeholder?: string;
11
+ name?: string;
12
+ autocomplete?: HTMLInputAttributes['autocomplete'];
13
+ required?: boolean;
14
+ readonly?: boolean;
15
+ inputmode?: TextInputMode;
16
+ } & StyleProps & TextEditorProps;
17
+ declare const TextField: import("svelte").Component<Props, {}, "value">;
18
+ type TextField = ReturnType<typeof TextField>;
19
+ export default TextField;
@@ -0,0 +1 @@
1
+ export { default } from './TextField.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './TextField.svelte';
@@ -0,0 +1,45 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { extractLayoutProps, layoutStyle, type LayoutProps } from '../../../style/layout';
4
+ import { extractStyleProps, surfaceStyle, type StyleProps } from '../../../style/surface';
5
+
6
+ type Props = {
7
+ children?: Snippet;
8
+ } & LayoutProps &
9
+ StyleProps;
10
+
11
+ let { children, ...restProps }: Props = $props();
12
+
13
+ const extractedLayoutProps = $derived.by(() => extractLayoutProps(restProps));
14
+ const layoutProps = $derived(extractedLayoutProps.layoutProps);
15
+ const afterLayoutProps = $derived(extractedLayoutProps.restProps);
16
+ const extractedStyleProps = $derived.by(() => extractStyleProps(afterLayoutProps));
17
+ const styleProps = $derived(extractedStyleProps.styleProps);
18
+ const rootStyle = $derived.by(() =>
19
+ [layoutStyle(layoutProps), surfaceStyle(styleProps, 'stack')].filter(Boolean).join(' ')
20
+ );
21
+ </script>
22
+
23
+ <div class="vstack" style={rootStyle}>
24
+ {#if children}
25
+ {@render children()}
26
+ {/if}
27
+ </div>
28
+
29
+ <style>
30
+ .vstack {
31
+ display: flex;
32
+ min-width: min-content;
33
+ min-height: min-content;
34
+ flex-direction: column;
35
+ gap: var(--stack-gap, 0px);
36
+ border-radius: var(--stack-border-radius, 0px);
37
+ padding:
38
+ var(--stack-padding-y, 0px)
39
+ var(--stack-padding-x, 0px);
40
+ font-size: var(--stack-font-size, inherit);
41
+ --divider-width: 100%;
42
+ --divider-height: 1px;
43
+ --divider-align-self: auto;
44
+ }
45
+ </style>
@@ -0,0 +1,9 @@
1
+ import type { Snippet } from 'svelte';
2
+ import { type LayoutProps } from '../../../style/layout';
3
+ import { type StyleProps } from '../../../style/surface';
4
+ type Props = {
5
+ children?: Snippet;
6
+ } & LayoutProps & StyleProps;
7
+ declare const VStack: import("svelte").Component<Props, {}, "">;
8
+ type VStack = ReturnType<typeof VStack>;
9
+ export default VStack;
@@ -0,0 +1 @@
1
+ export { default } from './VStack.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './VStack.svelte';
@@ -1,5 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { Component } from 'svelte';
3
+ import Grid from '../Library/Grid';
4
+ import GridItem from '../Library/GridItem';
3
5
  import HeroCard from './HeroCard.svelte';
4
6
 
5
7
  type DemoEntry = {
@@ -17,38 +19,20 @@
17
19
  let { demos }: Props = $props();
18
20
  </script>
19
21
 
20
- <div
21
- class="component-grid grid gap-4 overflow-auto md:grid-flow-dense md:grid-cols-2 xl:grid-cols-3"
22
- style="padding: calc(var(--sveltely-padding-y) * 2) calc(var(--sveltely-padding-x) * 2);"
22
+ <Grid
23
+ columns="repeat(auto-fit, minmax(min(100%, 18rem), 1fr))"
24
+ autoRows={14}
25
+ gap={1}
26
+ paddingX="calc(var(--sveltely-padding-x) * 2)"
27
+ paddingY="calc(var(--sveltely-padding-y) * 2)"
28
+ overflow="auto"
23
29
  >
24
30
  {#each demos as entry}
25
31
  {@const DemoComponent = entry.component}
26
- <HeroCard
27
- title={entry.name}
28
- description={entry.description}
29
- columnSpan={entry.columnSpan ?? 1}
30
- rowSpan={entry.rowSpan ?? 1}
31
- >
32
- <DemoComponent />
33
- </HeroCard>
32
+ <GridItem columnSpan={entry.columnSpan ?? 1} rowSpan={entry.rowSpan ?? 1}>
33
+ <HeroCard title={entry.name} description={entry.description}>
34
+ <DemoComponent />
35
+ </HeroCard>
36
+ </GridItem>
34
37
  {/each}
35
- </div>
36
-
37
- <style>
38
- .component-grid :global(.hero-card) {
39
- --sveltely-border-width: 1px;
40
- min-height: 14rem;
41
- border: 1px solid var(--sveltely-border-color);
42
- border-radius: 0.75rem;
43
- align-items: stretch;
44
- }
45
-
46
- .component-grid :global(.hero-card h1) {
47
- font-size: 1rem;
48
- line-height: 1.5rem;
49
- }
50
-
51
- .component-grid :global(.hero-card p) {
52
- max-width: none;
53
- }
54
- </style>
38
+ </Grid>