@x33025/sveltely 0.1.1 → 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.
Files changed (156) hide show
  1. package/dist/components/Library/AnimatedNumber/AnimatedNumber.demo.svelte +1 -1
  2. package/dist/components/Library/AsyncButton/AsyncButton.svelte +42 -16
  3. package/dist/components/Library/Button/Button.demo.svelte +5 -3
  4. package/dist/components/Library/Button/Button.demo.svelte.d.ts +1 -0
  5. package/dist/components/Library/Button/Button.svelte +21 -13
  6. package/dist/components/Library/Calendar/Calendar.demo.svelte +2 -14
  7. package/dist/components/Library/Calendar/Calendar.svelte +69 -65
  8. package/dist/components/Library/Checkbox/Checkbox.svelte +13 -14
  9. package/dist/components/Library/ChipInput/ChipInput.demo.svelte +1 -1
  10. package/dist/components/Library/ChipInput/ChipInput.svelte +7 -4
  11. package/dist/components/Library/Divider/Divider.svelte +10 -0
  12. package/dist/components/Library/Divider/Divider.svelte.d.ts +26 -0
  13. package/dist/components/Library/Divider/index.d.ts +1 -0
  14. package/dist/components/Library/Divider/index.js +1 -0
  15. package/dist/components/Library/Dropdown/Action.svelte +60 -0
  16. package/dist/components/Library/Dropdown/Action.svelte.d.ts +11 -0
  17. package/dist/components/Library/Dropdown/Divider.svelte +5 -0
  18. package/dist/components/Library/Dropdown/Divider.svelte.d.ts +19 -0
  19. package/dist/components/Library/Dropdown/Dropdown.demo.svelte +182 -65
  20. package/dist/components/Library/Dropdown/Dropdown.demo.svelte.d.ts +2 -1
  21. package/dist/components/Library/Dropdown/Dropdown.svelte +95 -250
  22. package/dist/components/Library/Dropdown/Dropdown.svelte.d.ts +17 -16
  23. package/dist/components/Library/Dropdown/Item.svelte +68 -0
  24. package/dist/components/Library/Dropdown/Item.svelte.d.ts +31 -0
  25. package/dist/components/Library/Dropdown/Section.svelte +34 -0
  26. package/dist/components/Library/Dropdown/Section.svelte.d.ts +8 -0
  27. package/dist/components/Library/Dropdown/context.d.ts +34 -0
  28. package/dist/components/Library/Dropdown/context.js +6 -0
  29. package/dist/components/Library/Dropdown/index.d.ts +13 -2
  30. package/dist/components/Library/Dropdown/index.js +11 -1
  31. package/dist/components/Library/Floating/Floating.svelte +44 -7
  32. package/dist/components/Library/ForEach/ForEach.svelte +14 -0
  33. package/dist/components/Library/ForEach/ForEach.svelte.d.ts +28 -0
  34. package/dist/components/Library/ForEach/index.d.ts +1 -0
  35. package/dist/components/Library/ForEach/index.js +1 -0
  36. package/dist/components/Library/Grid/Grid.svelte +74 -0
  37. package/dist/components/Library/Grid/Grid.svelte.d.ts +13 -0
  38. package/dist/components/Library/Grid/index.d.ts +1 -0
  39. package/dist/components/Library/Grid/index.js +1 -0
  40. package/dist/components/Library/GridItem/GridItem.svelte +65 -0
  41. package/dist/components/Library/GridItem/GridItem.svelte.d.ts +14 -0
  42. package/dist/components/Library/GridItem/index.d.ts +1 -0
  43. package/dist/components/Library/GridItem/index.js +1 -0
  44. package/dist/components/Library/HStack/HStack.svelte +45 -0
  45. package/dist/components/Library/HStack/HStack.svelte.d.ts +9 -0
  46. package/dist/components/Library/HStack/index.d.ts +1 -0
  47. package/dist/components/Library/HStack/index.js +1 -0
  48. package/dist/components/Library/Image/Image.demo.svelte +18 -0
  49. package/dist/components/Library/Image/Image.demo.svelte.d.ts +23 -0
  50. package/dist/components/Library/Image/Image.svelte +57 -0
  51. package/dist/components/Library/Image/Image.svelte.d.ts +17 -0
  52. package/dist/components/Library/Image/ImagePlaceholder.svelte +202 -0
  53. package/dist/components/Library/Image/ImagePlaceholder.svelte.d.ts +7 -0
  54. package/dist/components/Library/Image/index.d.ts +1 -0
  55. package/dist/components/Library/Image/index.js +1 -0
  56. package/dist/components/Library/ImageMask/BrushPreview.svelte +119 -0
  57. package/dist/components/Library/ImageMask/BrushPreview.svelte.d.ts +11 -0
  58. package/dist/components/Library/ImageMask/ImageMask.demo.svelte +117 -0
  59. package/dist/components/Library/ImageMask/ImageMask.demo.svelte.d.ts +10 -0
  60. package/dist/components/Library/ImageMask/ImageMask.svelte +46 -0
  61. package/dist/components/Library/ImageMask/ImageMask.svelte.d.ts +20 -0
  62. package/dist/components/Library/ImageMask/MaskLayer.svelte +341 -0
  63. package/dist/components/Library/ImageMask/MaskLayer.svelte.d.ts +12 -0
  64. package/dist/components/Library/ImageMask/contour.d.ts +11 -0
  65. package/dist/components/Library/ImageMask/contour.js +152 -0
  66. package/dist/components/Library/ImageMask/index.d.ts +2 -0
  67. package/dist/components/Library/ImageMask/index.js +1 -0
  68. package/dist/components/Library/ImageMask/marchingAnts.d.ts +8 -0
  69. package/dist/components/Library/ImageMask/marchingAnts.js +29 -0
  70. package/dist/components/Library/ImageMask/maskSurface.d.ts +5 -0
  71. package/dist/components/Library/ImageMask/maskSurface.js +94 -0
  72. package/dist/components/Library/ImageMask/types.d.ts +23 -0
  73. package/dist/components/Library/Label/Label.demo.svelte +28 -0
  74. package/dist/components/Library/Label/Label.demo.svelte.d.ts +9 -0
  75. package/dist/components/Library/Label/Label.svelte +175 -0
  76. package/dist/components/Library/Label/Label.svelte.d.ts +18 -0
  77. package/dist/components/Library/Label/index.d.ts +1 -0
  78. package/dist/components/Library/Label/index.js +1 -0
  79. package/dist/components/Library/NavigationStack/NavigationStack.svelte +17 -7
  80. package/dist/components/Library/NavigationStack/Toolbar.svelte +7 -2
  81. package/dist/components/Library/NumberField/NumberField.demo.svelte +21 -0
  82. package/dist/components/Library/NumberField/NumberField.demo.svelte.d.ts +8 -0
  83. package/dist/components/Library/NumberField/NumberField.svelte +199 -0
  84. package/dist/components/Library/NumberField/NumberField.svelte.d.ts +21 -0
  85. package/dist/components/Library/NumberField/index.d.ts +1 -0
  86. package/dist/components/Library/NumberField/index.js +1 -0
  87. package/dist/components/Library/Pagination/Pagination.svelte +16 -20
  88. package/dist/components/Library/Popover/Popover.demo.svelte +2 -2
  89. package/dist/components/Library/Popover/Popover.svelte +7 -4
  90. package/dist/components/Library/ScrollView/ScrollView.svelte +165 -12
  91. package/dist/components/Library/ScrollView/ScrollView.svelte.d.ts +32 -4
  92. package/dist/components/Library/ScrollView/index.d.ts +1 -0
  93. package/dist/components/Library/{SearchInput/SearchInput.demo.svelte → SearchField/SearchField.demo.svelte} +4 -4
  94. package/dist/components/Library/SearchField/SearchField.demo.svelte.d.ts +8 -0
  95. package/dist/components/Library/{SearchInput/SearchInput.svelte → SearchField/SearchField.svelte} +26 -30
  96. package/dist/components/Library/{SearchInput/SearchInput.svelte.d.ts → SearchField/SearchField.svelte.d.ts} +3 -3
  97. package/dist/components/Library/SearchField/index.d.ts +1 -0
  98. package/dist/components/Library/SearchField/index.js +1 -0
  99. package/dist/components/Library/SegmentedPicker/SegmentedPicker.demo.svelte +1 -1
  100. package/dist/components/Library/SegmentedPicker/SegmentedPicker.svelte +9 -9
  101. package/dist/components/Library/Sheet/Sheet.demo.svelte +1 -1
  102. package/dist/components/Library/Sheet/Sheet.svelte +8 -5
  103. package/dist/components/Library/Slider/Slider.demo.svelte +1 -1
  104. package/dist/components/Library/Slider/Slider.svelte +11 -10
  105. package/dist/components/Library/Spacer/Spacer.svelte +7 -0
  106. package/dist/components/Library/Spacer/Spacer.svelte.d.ts +26 -0
  107. package/dist/components/Library/Spacer/index.d.ts +1 -0
  108. package/dist/components/Library/Spacer/index.js +1 -0
  109. package/dist/components/Library/Spinner/Spinner.demo.svelte +1 -1
  110. package/dist/components/Library/Switch/Switch.svelte +6 -11
  111. package/dist/components/Library/TextField/TextField.demo.svelte +14 -0
  112. package/dist/components/Library/TextField/TextField.demo.svelte.d.ts +8 -0
  113. package/dist/components/Library/TextField/TextField.svelte +154 -0
  114. package/dist/components/Library/TextField/TextField.svelte.d.ts +19 -0
  115. package/dist/components/Library/TextField/index.d.ts +1 -0
  116. package/dist/components/Library/TextField/index.js +1 -0
  117. package/dist/components/Library/{TokenSearchInput/TokenSearchInput.demo.svelte → TokenSearchField/TokenSearchField.demo.svelte} +4 -4
  118. package/dist/components/Library/TokenSearchField/TokenSearchField.demo.svelte.d.ts +9 -0
  119. package/dist/components/Library/{TokenSearchInput/TokenSearchInput.svelte → TokenSearchField/TokenSearchField.svelte} +70 -66
  120. package/dist/components/Library/{TokenSearchInput/TokenSearchInput.svelte.d.ts → TokenSearchField/TokenSearchField.svelte.d.ts} +3 -3
  121. package/dist/components/Library/TokenSearchField/index.d.ts +1 -0
  122. package/dist/components/Library/TokenSearchField/index.js +1 -0
  123. package/dist/components/Library/VStack/VStack.svelte +45 -0
  124. package/dist/components/Library/VStack/VStack.svelte.d.ts +9 -0
  125. package/dist/components/Library/VStack/index.d.ts +1 -0
  126. package/dist/components/Library/VStack/index.js +1 -0
  127. package/dist/components/Library/WheelPicker/WheelColumn.svelte +4 -10
  128. package/dist/components/Library/WheelPicker/WheelPicker.svelte +5 -9
  129. package/dist/components/Local/ComponentGrid.svelte +15 -31
  130. package/dist/components/Local/HeroCard.svelte +30 -38
  131. package/dist/components/Local/HeroCard.svelte.d.ts +0 -2
  132. package/dist/components/Local/StyleControls.svelte +58 -27
  133. package/dist/components/Local/StyleControls.svelte.d.ts +3 -1
  134. package/dist/index.d.ts +26 -2
  135. package/dist/index.js +19 -2
  136. package/dist/style/index.css +35 -20
  137. package/dist/style/label.d.ts +6 -0
  138. package/dist/style/label.js +4 -0
  139. package/dist/style/layout.d.ts +57 -0
  140. package/dist/style/layout.js +128 -0
  141. package/dist/style/media.d.ts +12 -0
  142. package/dist/style/media.js +8 -0
  143. package/dist/style/scroll.d.ts +7 -0
  144. package/dist/style/scroll.js +5 -0
  145. package/dist/style/text-editor.d.ts +34 -0
  146. package/dist/style/text-editor.js +29 -0
  147. package/dist/style.css +112 -58
  148. package/package.json +1 -1
  149. package/dist/components/Library/Dropdown/types.d.ts +0 -27
  150. package/dist/components/Library/SearchInput/SearchInput.demo.svelte.d.ts +0 -8
  151. package/dist/components/Library/SearchInput/index.d.ts +0 -1
  152. package/dist/components/Library/SearchInput/index.js +0 -1
  153. package/dist/components/Library/TokenSearchInput/TokenSearchInput.demo.svelte.d.ts +0 -9
  154. package/dist/components/Library/TokenSearchInput/index.d.ts +0 -1
  155. package/dist/components/Library/TokenSearchInput/index.js +0 -1
  156. /package/dist/components/Library/{Dropdown → ImageMask}/types.js +0 -0
@@ -0,0 +1,28 @@
1
+ <script module lang="ts">
2
+ export const demo = {
3
+ name: 'Label',
4
+ description: 'Form label wrapper with top and left orientation.',
5
+ columnSpan: 2
6
+ };
7
+ </script>
8
+
9
+ <script lang="ts">
10
+ import { HashIcon, UserIcon } from '@lucide/svelte';
11
+ import HStack from '../HStack';
12
+ import NumberField from '../NumberField';
13
+ import TextField from '../TextField';
14
+ import Label from './Label.svelte';
15
+
16
+ let name = $state('');
17
+ let amount = $state<number | null>(35);
18
+ </script>
19
+
20
+ <HStack gap={1} align="center">
21
+ <Label label="Name" icon={UserIcon} orientation="top">
22
+ <TextField bind:value={name} placeholder="Sveltely" />
23
+ </Label>
24
+
25
+ <Label label="Amount" icon={HashIcon} orientation="left">
26
+ <NumberField bind:value={amount} min={0} max={100} />
27
+ </Label>
28
+ </HStack>
@@ -0,0 +1,9 @@
1
+ export declare const demo: {
2
+ name: string;
3
+ description: string;
4
+ columnSpan: number;
5
+ };
6
+ import Label from './Label.svelte';
7
+ declare const Label: import("svelte").Component<Record<string, never>, {}, "">;
8
+ type Label = ReturnType<typeof Label>;
9
+ export default Label;
@@ -0,0 +1,175 @@
1
+ <script lang="ts">
2
+ import type { Component, Snippet } from 'svelte';
3
+ import type { LabelOrientation } from '../../../style/label';
4
+ import { layoutStyle, type LayoutProps } from '../../../style/layout';
5
+ import { surfaceStyle, type StyleProps } from '../../../style/surface';
6
+
7
+ type Props = {
8
+ children?: Snippet;
9
+ label?: string;
10
+ icon?: Component<{ class?: string; size?: number | string }>;
11
+ iconSize?: number | string;
12
+ iconColor?: string;
13
+ orientation?: LabelOrientation;
14
+ } & LayoutProps &
15
+ StyleProps;
16
+
17
+ let {
18
+ children,
19
+ label,
20
+ icon,
21
+ iconSize,
22
+ iconColor,
23
+ orientation = 'top',
24
+ size,
25
+ width,
26
+ height,
27
+ minWidth,
28
+ minHeight,
29
+ maxWidth,
30
+ maxHeight,
31
+ grow,
32
+ shrink,
33
+ basis,
34
+ border,
35
+ overflow,
36
+ align,
37
+ justify,
38
+ fontSize,
39
+ paddingX,
40
+ paddingY,
41
+ gap,
42
+ borderRadius,
43
+ inset,
44
+ background,
45
+ borderColor,
46
+ color
47
+ }: Props = $props();
48
+
49
+ const layoutProps = $derived({
50
+ size,
51
+ width,
52
+ height,
53
+ minWidth,
54
+ minHeight,
55
+ maxWidth,
56
+ maxHeight,
57
+ grow,
58
+ shrink,
59
+ basis,
60
+ border,
61
+ overflow,
62
+ align,
63
+ justify
64
+ });
65
+ const styleProps = $derived({
66
+ fontSize,
67
+ paddingX,
68
+ paddingY,
69
+ gap,
70
+ borderRadius,
71
+ inset,
72
+ background,
73
+ borderColor,
74
+ color
75
+ });
76
+
77
+ const rootStyle = $derived.by(() =>
78
+ [layoutStyle(layoutProps), surfaceStyle(styleProps, 'label')].filter(Boolean).join(' ')
79
+ );
80
+
81
+ const iconStyle = $derived.by(() => {
82
+ const declarations: string[] = [];
83
+
84
+ if (iconColor !== undefined) {
85
+ declarations.push(`color: ${iconColor};`);
86
+ }
87
+
88
+ if (iconSize !== undefined) {
89
+ const sizeValue = typeof iconSize === 'number' ? `${iconSize}rem` : iconSize;
90
+ declarations.push(`width: ${sizeValue};`, `height: ${sizeValue};`);
91
+ }
92
+
93
+ return declarations.join(' ');
94
+ });
95
+ </script>
96
+
97
+ <div class="label" data-orientation={orientation} style={rootStyle}>
98
+ {#if icon || label}
99
+ <span class="label-heading">
100
+ {#if icon}
101
+ {@const Icon = icon}
102
+ <span class="label-icon-frame" style={iconStyle}>
103
+ <Icon class="label-icon" />
104
+ </span>
105
+ {/if}
106
+
107
+ {#if label}
108
+ <span class="label-text">{label}</span>
109
+ {/if}
110
+ </span>
111
+ {/if}
112
+
113
+ {#if children}
114
+ <div class="label-content">
115
+ {@render children()}
116
+ </div>
117
+ {/if}
118
+ </div>
119
+
120
+ <style>
121
+ .label {
122
+ --label-font-size: var(--sveltely-font-size);
123
+ --label-icon-size: calc(var(--label-font-size) * 1.143);
124
+ display: inline-flex;
125
+ width: 100%;
126
+ min-width: min-content;
127
+ min-height: min-content;
128
+ gap: var(--label-gap, calc(var(--sveltely-gap) * 0.75));
129
+ border-radius: var(--label-border-radius, 0px);
130
+ color: var(--label-color, var(--sveltely-primary-color));
131
+ font-size: var(--label-font-size);
132
+ padding: var(--label-padding-y, 0px) var(--label-padding-x, 0px);
133
+ }
134
+
135
+ .label[data-orientation='top'] {
136
+ flex-direction: column;
137
+ align-items: stretch;
138
+ }
139
+
140
+ .label[data-orientation='left'] {
141
+ flex-direction: row;
142
+ align-items: center;
143
+ }
144
+
145
+ .label-heading {
146
+ display: inline-flex;
147
+ min-width: max-content;
148
+ flex-shrink: 0;
149
+ align-items: center;
150
+ gap: calc(var(--label-gap, var(--sveltely-gap)) * 0.67);
151
+ font-weight: 500;
152
+ line-height: 1.25;
153
+ }
154
+
155
+ .label-content {
156
+ display: inline-flex;
157
+ min-width: 0;
158
+ flex: 1 1 auto;
159
+ }
160
+
161
+ .label-icon-frame {
162
+ display: inline-flex;
163
+ width: var(--label-icon-size);
164
+ height: var(--label-icon-size);
165
+ flex-shrink: 0;
166
+ align-items: center;
167
+ justify-content: center;
168
+ color: var(--label-icon-color, currentColor);
169
+ }
170
+
171
+ .label-icon-frame :global(.label-icon) {
172
+ width: 100%;
173
+ height: 100%;
174
+ }
175
+ </style>
@@ -0,0 +1,18 @@
1
+ import type { Component, Snippet } from 'svelte';
2
+ import type { LabelOrientation } from '../../../style/label';
3
+ import { type LayoutProps } from '../../../style/layout';
4
+ import { type StyleProps } from '../../../style/surface';
5
+ type Props = {
6
+ children?: Snippet;
7
+ label?: string;
8
+ icon?: Component<{
9
+ class?: string;
10
+ size?: number | string;
11
+ }>;
12
+ iconSize?: number | string;
13
+ iconColor?: string;
14
+ orientation?: LabelOrientation;
15
+ } & LayoutProps & StyleProps;
16
+ declare const Label: Component<Props, {}, "">;
17
+ type Label = ReturnType<typeof Label>;
18
+ export default Label;
@@ -0,0 +1 @@
1
+ export { default } from './Label.svelte';
@@ -0,0 +1 @@
1
+ export { default } from './Label.svelte';
@@ -122,7 +122,9 @@
122
122
  </div>
123
123
  {/if}
124
124
 
125
- <div class="navigation-stack-pane navigation-stack-pane-center navigation-stack-pane-body navigation-stack-content vstack">
125
+ <div
126
+ class="navigation-stack-pane navigation-stack-pane-center navigation-stack-pane-body navigation-stack-content vstack"
127
+ >
126
128
  {#if children}
127
129
  {@render children()}
128
130
  {/if}
@@ -180,7 +182,7 @@
180
182
  .navigation-stack-pane-header {
181
183
  grid-row: 1;
182
184
  border-bottom: 1px solid var(--sveltely-border-color);
183
- background: white;
185
+ background: var(--sveltely-background-color);
184
186
  }
185
187
 
186
188
  .navigation-stack-pane-body {
@@ -204,20 +206,28 @@
204
206
  }
205
207
 
206
208
  .navigation-stack-sidebar-inner {
207
- background: var(--color-zinc-50);
209
+ background: var(--sveltely-background-color);
208
210
  transition:
209
211
  visibility 0ms linear 300ms,
210
212
  background-color 300ms ease-in-out;
211
213
  }
212
214
 
213
- .navigation-stack[data-left-open='true'] .navigation-stack-pane-left.navigation-stack-pane-body .navigation-stack-sidebar-inner,
214
- .navigation-stack[data-right-open='true'] .navigation-stack-pane-right.navigation-stack-pane-body .navigation-stack-sidebar-inner {
215
+ .navigation-stack[data-left-open='true']
216
+ .navigation-stack-pane-left.navigation-stack-pane-body
217
+ .navigation-stack-sidebar-inner,
218
+ .navigation-stack[data-right-open='true']
219
+ .navigation-stack-pane-right.navigation-stack-pane-body
220
+ .navigation-stack-sidebar-inner {
215
221
  visibility: visible;
216
222
  transition-delay: 0ms;
217
223
  }
218
224
 
219
- .navigation-stack[data-left-open='false'] .navigation-stack-pane-left.navigation-stack-pane-body .navigation-stack-sidebar-inner,
220
- .navigation-stack[data-right-open='false'] .navigation-stack-pane-right.navigation-stack-pane-body .navigation-stack-sidebar-inner {
225
+ .navigation-stack[data-left-open='false']
226
+ .navigation-stack-pane-left.navigation-stack-pane-body
227
+ .navigation-stack-sidebar-inner,
228
+ .navigation-stack[data-right-open='false']
229
+ .navigation-stack-pane-right.navigation-stack-pane-body
230
+ .navigation-stack-sidebar-inner {
221
231
  visibility: hidden;
222
232
  pointer-events: none;
223
233
  }
@@ -21,7 +21,12 @@
21
21
  const rootStyle = $derived.by(() => surfaceStyle(styleProps, 'navigation-stack-toolbar'));
22
22
  </script>
23
23
 
24
- <div class="navigation-stack-toolbar-shell vstack h-full" style={rootStyle} data-chrome={chrome ? 'true' : 'false'} {...props}>
24
+ <div
25
+ class="navigation-stack-toolbar-shell vstack h-full"
26
+ style={rootStyle}
27
+ data-chrome={chrome ? 'true' : 'false'}
28
+ {...props}
29
+ >
25
30
  {#if header}
26
31
  <div
27
32
  class="navigation-stack-toolbar flex items-center gap-2"
@@ -41,7 +46,7 @@
41
46
  <style>
42
47
  .navigation-stack-toolbar {
43
48
  border-bottom: 1px solid var(--sveltely-border-color);
44
- background: white;
49
+ background: var(--sveltely-background-color);
45
50
  }
46
51
 
47
52
  .navigation-stack-toolbar-shell[data-chrome='false'] .navigation-stack-toolbar {
@@ -0,0 +1,21 @@
1
+ <script module lang="ts">
2
+ export const demo = {
3
+ name: 'NumberField',
4
+ description: 'Token-aware numeric input with min, max, and step support.'
5
+ };
6
+ </script>
7
+
8
+ <script lang="ts">
9
+ import NumberField from './NumberField.svelte';
10
+
11
+ let value = $state<number | null>(35);
12
+ </script>
13
+
14
+ <NumberField
15
+ bind:value
16
+ min={0}
17
+ max={100}
18
+ step={1}
19
+ placeholder="0"
20
+ help={`Value: ${value ?? 'empty'}`}
21
+ />
@@ -0,0 +1,8 @@
1
+ export declare const demo: {
2
+ name: string;
3
+ description: string;
4
+ };
5
+ import NumberField from './NumberField.svelte';
6
+ declare const NumberField: import("svelte").Component<Record<string, never>, {}, "">;
7
+ type NumberField = ReturnType<typeof NumberField>;
8
+ export default NumberField;
@@ -0,0 +1,199 @@
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)]
68
+ .filter(Boolean)
69
+ .join(' ')
70
+ );
71
+ const describedBy = $derived(help ? 'text-field-message' : undefined);
72
+
73
+ let draftValue = $state(formatValue(value));
74
+ let committedValue = $state(value);
75
+
76
+ $effect(() => {
77
+ if (value !== committedValue) {
78
+ draftValue = formatValue(value);
79
+ committedValue = value;
80
+ }
81
+ });
82
+
83
+ function formatValue(nextValue: number | null | undefined) {
84
+ return nextValue === null || nextValue === undefined ? '' : String(nextValue);
85
+ }
86
+
87
+ function handleInput(event: Event) {
88
+ const input = event.currentTarget as HTMLInputElement;
89
+ const nextValue = input.value;
90
+
91
+ draftValue = nextValue;
92
+
93
+ if (nextValue === '') {
94
+ value = null;
95
+ committedValue = null;
96
+ return;
97
+ }
98
+
99
+ const numericValue = Number(nextValue);
100
+
101
+ if (!input.validity.badInput && Number.isFinite(numericValue)) {
102
+ value = numericValue;
103
+ committedValue = numericValue;
104
+ }
105
+ }
106
+
107
+ function handleBlur() {
108
+ if (draftValue !== formatValue(value)) {
109
+ draftValue = formatValue(value);
110
+ }
111
+ }
112
+ </script>
113
+
114
+ <div
115
+ use:tooltip={{ label: error ?? '', disabled: !error }}
116
+ class="text-field"
117
+ style={rootStyle}
118
+ data-disabled={disabled ? 'true' : 'false'}
119
+ data-error={error ? 'true' : 'false'}
120
+ >
121
+ <input
122
+ value={draftValue}
123
+ type="number"
124
+ {disabled}
125
+ {name}
126
+ {autocomplete}
127
+ {required}
128
+ {readonly}
129
+ {inputmode}
130
+ {placeholder}
131
+ {min}
132
+ {max}
133
+ {step}
134
+ aria-invalid={error ? 'true' : undefined}
135
+ aria-describedby={describedBy}
136
+ class="text-field-input"
137
+ oninput={handleInput}
138
+ onblur={handleBlur}
139
+ />
140
+
141
+ {#if help}
142
+ <span id="text-field-message" class="text-field-message">{help}</span>
143
+ {/if}
144
+ </div>
145
+
146
+ <style>
147
+ .text-field {
148
+ display: inline-flex;
149
+ width: 100%;
150
+ min-width: 0;
151
+ flex-direction: column;
152
+ gap: var(--text-field-gap, calc(var(--sveltely-gap) * 0.75));
153
+ color: var(--text-field-color, var(--sveltely-primary-color));
154
+ font-size: var(--text-field-font-size, calc(var(--sveltely-font-size) * 0.875));
155
+ }
156
+
157
+ .text-field-input {
158
+ width: 100%;
159
+ min-width: 0;
160
+ border: 1px solid var(--text-field-border-color, var(--sveltely-border-color));
161
+ border-radius: var(--text-field-border-radius, var(--sveltely-border-radius));
162
+ background: var(--text-field-background, var(--sveltely-background-color));
163
+ color: inherit;
164
+ font-variant-numeric: tabular-nums;
165
+ line-height: 1.25rem;
166
+ outline: none;
167
+ padding: var(--text-field-padding-y, calc(var(--sveltely-padding-y) * 0.67))
168
+ var(--text-field-padding-x, var(--sveltely-padding-x));
169
+ text-align: var(--text-field-text-align, start);
170
+ transition:
171
+ color 150ms,
172
+ border-color 150ms,
173
+ background-color 150ms,
174
+ box-shadow 150ms;
175
+ }
176
+
177
+ .text-field-input:focus {
178
+ border-color: color-mix(in oklab, var(--sveltely-active-color) 50%, white);
179
+ }
180
+
181
+ .text-field-input::placeholder {
182
+ color: var(--sveltely-secondary-color);
183
+ }
184
+
185
+ .text-field-message {
186
+ color: var(--sveltely-secondary-color);
187
+ font-size: calc(var(--text-field-font-size, 0.875rem) * 0.857);
188
+ line-height: 1.25;
189
+ }
190
+
191
+ .text-field[data-error='true'] .text-field-input {
192
+ border-color: var(--color-red-500);
193
+ }
194
+
195
+ .text-field[data-disabled='true'] {
196
+ cursor: not-allowed;
197
+ opacity: 0.6;
198
+ }
199
+ </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';
@@ -26,7 +26,8 @@
26
26
  onPageChange?: (page: number, href: string) => void | Promise<void>;
27
27
  showFirstLast?: boolean;
28
28
  variant?: 'icon' | 'label';
29
- } & StyleProps & Record<string, unknown> = $props();
29
+ } & StyleProps &
30
+ Record<string, unknown> = $props();
30
31
 
31
32
  const extractedStyleProps = $derived.by(() => extractStyleProps(restProps));
32
33
  const styleProps = $derived(extractedStyleProps.styleProps);
@@ -48,7 +49,7 @@
48
49
  const hasNext = () => (typeof data.hasNext === 'boolean' ? data.hasNext : safePage() < maxPage());
49
50
  const hasPrevious = () => safePage() > 1;
50
51
  const buttonClass = () =>
51
- `pagination-button action disabled:bg-zinc-200 disabled:text-zinc-500 inline-flex items-center justify-center leading-none ${
52
+ `pagination-button action disabled:bg-zinc-200 disabled:text-[var(--sveltely-secondary-color)] inline-flex items-center justify-center leading-none ${
52
53
  variant === 'icon' ? 'pagination-button-icon' : ''
53
54
  }`;
54
55
 
@@ -114,14 +115,8 @@
114
115
 
115
116
  <form method="GET" style="display: inline;" novalidate onsubmit={handleSubmit}>
116
117
  <input type="hidden" name="view" value={data.view} />
117
- <input
118
- id="page"
119
- name="page"
120
- type="number"
121
- class="pagination-input"
122
- value={safePage()}
123
- />
124
- </form>
118
+ <input id="page" name="page" type="number" class="pagination-input" value={safePage()} />
119
+ </form>
125
120
 
126
121
  <span>of {maxPage()}</span>
127
122
 
@@ -192,18 +187,20 @@
192
187
 
193
188
  .pagination-button {
194
189
  border-radius: var(--sveltely-border-radius);
195
- background: var(--color-zinc-100);
196
- padding:
197
- calc(var(--sveltely-padding-y) * 0.67 * var(--pagination-scale))
190
+ background: var(--sveltely-inactive-color);
191
+ padding: calc(var(--sveltely-padding-y) * 0.67 * var(--pagination-scale))
198
192
  calc(var(--sveltely-padding-x) * 0.67 * var(--pagination-scale));
199
193
  }
200
194
 
201
195
  .pagination-button-icon {
202
- padding:
203
- calc(var(--sveltely-padding-y) * 0.67 * var(--pagination-scale))
196
+ padding: calc(var(--sveltely-padding-y) * 0.67 * var(--pagination-scale))
204
197
  calc(var(--sveltely-padding-x) * 0.67 * var(--pagination-scale));
205
- min-width: calc((var(--sveltely-padding-x) * 1.34 * var(--pagination-scale)) + var(--pagination-icon-size));
206
- min-height: calc((var(--sveltely-padding-y) * 1.34 * var(--pagination-scale)) + var(--pagination-icon-size));
198
+ min-width: calc(
199
+ (var(--sveltely-padding-x) * 1.34 * var(--pagination-scale)) + var(--pagination-icon-size)
200
+ );
201
+ min-height: calc(
202
+ (var(--sveltely-padding-y) * 1.34 * var(--pagination-scale)) + var(--pagination-icon-size)
203
+ );
207
204
  }
208
205
 
209
206
  .pagination-button:disabled {
@@ -214,12 +211,11 @@
214
211
  .pagination-input {
215
212
  width: 10ch;
216
213
  border-radius: var(--sveltely-border-radius);
217
- background: var(--color-zinc-100);
214
+ background: var(--sveltely-inactive-color);
218
215
  font-size: inherit;
219
216
  line-height: 1.25;
220
217
  outline: none;
221
- padding:
222
- calc(var(--sveltely-padding-y) * 0.33 * var(--pagination-scale))
218
+ padding: calc(var(--sveltely-padding-y) * 0.33 * var(--pagination-scale))
223
219
  calc(var(--sveltely-padding-y) * 0.33 * var(--pagination-scale))
224
220
  calc(var(--sveltely-padding-y) * 0.33 * var(--pagination-scale))
225
221
  calc(var(--sveltely-padding-x) * var(--pagination-scale));
@@ -7,7 +7,7 @@
7
7
 
8
8
  <script lang="ts">
9
9
  import Popover from './Popover.svelte';
10
- import SearchInput from '../SearchInput/SearchInput.svelte';
10
+ import SearchField from '../SearchField/SearchField.svelte';
11
11
 
12
12
  let search = $state('');
13
13
  </script>
@@ -17,5 +17,5 @@
17
17
  <span>Open popover</span>
18
18
  {/snippet}
19
19
 
20
- <SearchInput id="popover-demo-search" bind:value={search} placeholder="Type to search..." />
20
+ <SearchField id="popover-demo-search" bind:value={search} placeholder="Type to search..." />
21
21
  </Popover>