@dvcol/neo-svelte 0.1.2 → 0.1.4

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 (152) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +25 -26
  3. package/dist/buttons/NeoButton.svelte +140 -128
  4. package/dist/buttons/NeoButtonGroup.svelte +99 -108
  5. package/dist/buttons/neo-button-group.model.d.ts +18 -19
  6. package/dist/buttons/neo-button.model.d.ts +6 -10
  7. package/dist/cards/NeoCard.svelte +176 -73
  8. package/dist/cards/NeoCard.svelte.d.ts +1 -1
  9. package/dist/cards/neo-card.model.d.ts +29 -1
  10. package/dist/containers/NeoTransitionContainer.svelte +13 -2
  11. package/dist/containers/neo-transition-container.model.d.ts +9 -1
  12. package/dist/divider/NeoDivider.svelte +11 -11
  13. package/dist/icons/IconAccount.svelte +10 -2
  14. package/dist/icons/IconAdd.svelte +10 -2
  15. package/dist/icons/IconAlert.svelte +2 -2
  16. package/dist/icons/IconCalendar.svelte +23 -0
  17. package/dist/icons/IconCalendar.svelte.d.ts +26 -0
  18. package/dist/icons/IconCheckbox.svelte +87 -0
  19. package/dist/icons/IconCheckbox.svelte.d.ts +55 -0
  20. package/dist/icons/IconCircleLoading.svelte +2 -2
  21. package/dist/icons/IconClear.svelte +10 -2
  22. package/dist/icons/IconClose.svelte +2 -2
  23. package/dist/icons/IconConfirm.svelte +2 -2
  24. package/dist/icons/IconDownload.svelte +17 -0
  25. package/dist/icons/IconDownload.svelte.d.ts +26 -0
  26. package/dist/icons/IconEmpty.svelte +2 -2
  27. package/dist/icons/IconFileUpload.svelte +2 -2
  28. package/dist/icons/IconGithub.svelte +2 -2
  29. package/dist/icons/IconImage.svelte +2 -2
  30. package/dist/icons/IconMinus.svelte +2 -2
  31. package/dist/icons/IconMoon.svelte +2 -2
  32. package/dist/icons/IconPaint.svelte +19 -0
  33. package/dist/icons/{IconSunrise.svelte.d.ts → IconPaint.svelte.d.ts} +3 -3
  34. package/dist/icons/IconPencil.svelte +13 -0
  35. package/dist/icons/IconPencil.svelte.d.ts +26 -0
  36. package/dist/icons/IconRadio.svelte +14 -0
  37. package/dist/icons/IconRadio.svelte.d.ts +22 -0
  38. package/dist/icons/IconSave.svelte +1 -1
  39. package/dist/icons/IconSave.svelte.d.ts +3 -3
  40. package/dist/icons/IconSaveOff.svelte +1 -1
  41. package/dist/icons/IconSaveOff.svelte.d.ts +3 -3
  42. package/dist/icons/IconSearch.svelte +2 -2
  43. package/dist/icons/IconSun.svelte +3 -3
  44. package/dist/icons/{IconSunrise.svelte → IconSunFull.svelte} +5 -4
  45. package/dist/icons/IconSunFull.svelte.d.ts +26 -0
  46. package/dist/icons/IconVideo.svelte +2 -2
  47. package/dist/icons/IconWatch.svelte +2 -2
  48. package/dist/icons/IconWatchOff.svelte +2 -2
  49. package/dist/inputs/NeoCheckbox.svelte +316 -0
  50. package/dist/inputs/NeoCheckbox.svelte.d.ts +19 -0
  51. package/dist/inputs/NeoColorPicker.svelte +140 -0
  52. package/dist/inputs/NeoColorPicker.svelte.d.ts +19 -0
  53. package/dist/inputs/NeoDateTime.svelte +96 -0
  54. package/dist/inputs/NeoDateTime.svelte.d.ts +19 -0
  55. package/dist/inputs/NeoFilePicker.svelte +528 -0
  56. package/dist/inputs/NeoFilePicker.svelte.d.ts +19 -0
  57. package/dist/inputs/NeoFilePickerCard.svelte +314 -0
  58. package/dist/inputs/NeoFilePickerCard.svelte.d.ts +19 -0
  59. package/dist/inputs/NeoNumberStep.svelte +174 -0
  60. package/dist/inputs/NeoNumberStep.svelte.d.ts +19 -0
  61. package/dist/inputs/NeoPassword.svelte +86 -17
  62. package/dist/inputs/NeoPassword.svelte.d.ts +19 -16
  63. package/dist/inputs/NeoPin.svelte +589 -0
  64. package/dist/inputs/NeoPin.svelte.d.ts +19 -0
  65. package/dist/inputs/NeoRadio.svelte +254 -0
  66. package/dist/inputs/NeoRadio.svelte.d.ts +19 -0
  67. package/dist/inputs/NeoRange.svelte +518 -0
  68. package/dist/inputs/NeoRange.svelte.d.ts +18 -0
  69. package/dist/inputs/NeoSwitch.svelte +373 -0
  70. package/dist/inputs/NeoSwitch.svelte.d.ts +19 -0
  71. package/dist/inputs/NeoTextarea.svelte +335 -301
  72. package/dist/inputs/NeoTextarea.svelte.d.ts +5 -2
  73. package/dist/inputs/common/NeoAffix.svelte +166 -0
  74. package/dist/inputs/common/NeoAffix.svelte.d.ts +19 -0
  75. package/dist/inputs/common/NeoBaseInput.svelte +338 -0
  76. package/dist/inputs/common/NeoBaseInput.svelte.d.ts +30 -0
  77. package/dist/inputs/common/NeoInput.svelte +684 -0
  78. package/dist/inputs/{NeoInput.svelte.d.ts → common/NeoInput.svelte.d.ts} +2 -10
  79. package/dist/inputs/common/NeoInputValidation.svelte +45 -0
  80. package/dist/inputs/common/NeoInputValidation.svelte.d.ts +22 -0
  81. package/dist/inputs/common/NeoLabel.svelte +93 -0
  82. package/dist/inputs/common/NeoLabel.svelte.d.ts +19 -0
  83. package/dist/inputs/{NeoValidation.svelte → common/NeoValidation.svelte} +9 -16
  84. package/dist/inputs/common/NeoValidation.svelte.d.ts +22 -0
  85. package/dist/inputs/common/neo-affix.model.d.ts +32 -0
  86. package/dist/inputs/common/neo-input-validation.model.d.ts +20 -0
  87. package/dist/inputs/common/neo-input-validation.model.js +1 -0
  88. package/dist/inputs/{neo-input.model.d.ts → common/neo-input.model.d.ts} +148 -68
  89. package/dist/inputs/common/neo-label.model.d.ts +36 -0
  90. package/dist/inputs/common/neo-label.model.js +1 -0
  91. package/dist/inputs/common/neo-validation.model.d.ts +70 -0
  92. package/dist/inputs/common/neo-validation.model.js +1 -0
  93. package/dist/inputs/index.d.ts +2 -2
  94. package/dist/inputs/index.js +1 -1
  95. package/dist/inputs/neo-checkbox.model.d.ts +9 -0
  96. package/dist/inputs/neo-checkbox.model.js +1 -0
  97. package/dist/inputs/neo-color-picker.model.d.ts +17 -0
  98. package/dist/inputs/neo-color-picker.model.js +1 -0
  99. package/dist/inputs/neo-date-time.model.d.ts +8 -0
  100. package/dist/inputs/neo-date-time.model.js +1 -0
  101. package/dist/inputs/neo-file-picker.model.d.ts +138 -0
  102. package/dist/inputs/neo-file-picker.model.js +1 -0
  103. package/dist/inputs/neo-number-step.model.d.ts +24 -0
  104. package/dist/inputs/neo-number-step.model.js +1 -0
  105. package/dist/inputs/neo-password.model.d.ts +13 -0
  106. package/dist/inputs/neo-password.model.js +1 -0
  107. package/dist/inputs/neo-pin.model.d.ts +47 -0
  108. package/dist/inputs/neo-pin.model.js +1 -0
  109. package/dist/inputs/neo-radio.model.d.ts +3 -0
  110. package/dist/inputs/neo-radio.model.js +1 -0
  111. package/dist/inputs/neo-switch.model.d.ts +9 -0
  112. package/dist/inputs/neo-switch.model.js +1 -0
  113. package/dist/nav/NeoTab.svelte +29 -25
  114. package/dist/nav/NeoTabPanel.svelte +1 -1
  115. package/dist/nav/NeoTabs.svelte +51 -44
  116. package/dist/nav/NeoTabsCard.svelte +8 -10
  117. package/dist/nav/neo-tabs-context.svelte.d.ts +2 -11
  118. package/dist/nav/neo-tabs-context.svelte.js +1 -41
  119. package/dist/nav/neo-tabs.model.d.ts +6 -0
  120. package/dist/providers/NeoThemeProvider.svelte +417 -305
  121. package/dist/providers/NeoThemeSelector.svelte +10 -10
  122. package/dist/providers/neo-theme-provider-context.svelte.js +16 -15
  123. package/dist/providers/neo-theme-provider.model.d.ts +6 -6
  124. package/dist/providers/neo-theme-provider.model.js +17 -12
  125. package/dist/providers/neo-theme-selector.model.d.ts +2 -2
  126. package/dist/skeletons/NeoSkeletonMedia.svelte +4 -4
  127. package/dist/skeletons/NeoSkeletonText.svelte +12 -12
  128. package/dist/styles/common/colors.scss +85 -97
  129. package/dist/styles/common/filters.scss +17 -0
  130. package/dist/styles/common/shadows.scss +531 -293
  131. package/dist/styles/common/spacing.scss +7 -3
  132. package/dist/styles/common/typography.scss +1 -1
  133. package/dist/styles/common/utils.scss +1 -1
  134. package/dist/styles/common/z-index.scss +1 -1
  135. package/dist/styles/mixin.scss +80 -27
  136. package/dist/styles/reset.scss +8 -1
  137. package/dist/styles/theme.scss +39 -16
  138. package/dist/utils/html-element.utils.d.ts +3 -0
  139. package/dist/utils/regex.utils.d.ts +3 -0
  140. package/dist/utils/regex.utils.js +3 -0
  141. package/dist/utils/shadow.utils.d.ts +30 -3
  142. package/dist/utils/shadow.utils.js +41 -14
  143. package/dist/utils/transition.utils.d.ts +4 -0
  144. package/dist/utils/transition.utils.js +10 -1
  145. package/dist/utils/utils.svelte.d.ts +6 -0
  146. package/dist/utils/utils.svelte.js +13 -0
  147. package/package.json +13 -12
  148. package/dist/inputs/NeoInput.svelte +0 -750
  149. package/dist/inputs/NeoValidation.svelte.d.ts +0 -22
  150. package/dist/inputs/neo-validation.model.d.ts +0 -40
  151. /package/dist/inputs/{neo-validation.model.js → common/neo-affix.model.js} +0 -0
  152. /package/dist/inputs/{neo-input.model.js → common/neo-input.model.js} +0 -0
@@ -1,11 +1,18 @@
1
1
  <script lang="ts">
2
+ import type { FocusEventHandler, MouseEventHandler } from 'svelte/elements';
2
3
  import type { NeoCardContext, NeoCardProps } from './neo-card.model.js';
3
4
 
4
5
  import NeoButton from '../buttons/NeoButton.svelte';
5
6
  import NeoDivider from '../divider/NeoDivider.svelte';
6
7
  import IconClose from '../icons/IconClose.svelte';
7
8
  import { toAction, toActionProps, toTransition, toTransitionProps } from '../utils/action.utils.js';
8
- import { computeGlassFilter, computeHoverShadowElevation, computeShadowElevation } from '../utils/shadow.utils.js';
9
+ import {
10
+ computeGlassFilter,
11
+ computeHoverShadowElevation,
12
+ computeShadowElevation,
13
+ getDefaultElevation,
14
+ isShadowFlat,
15
+ } from '../utils/shadow.utils.js';
9
16
 
10
17
  /* eslint-disable prefer-const -- necessary for binding checked */
11
18
  let {
@@ -18,11 +25,16 @@
18
25
 
19
26
  // States
20
27
  ref = $bindable(),
28
+ hovered = $bindable(false),
29
+ focused = $bindable(false),
21
30
  tag = 'div',
22
31
  close,
32
+ disabled,
23
33
 
24
34
  // Styles
25
- elevation = 3,
35
+ pressed,
36
+ convex,
37
+ elevation = getDefaultElevation(pressed),
26
38
  hover = 0,
27
39
  borderless,
28
40
  rounded,
@@ -30,6 +42,7 @@
30
42
  segmented,
31
43
  cover,
32
44
  start,
45
+ skeleton,
33
46
  horizontal,
34
47
 
35
48
  // Flex
@@ -47,6 +60,10 @@
47
60
 
48
61
  // Events
49
62
  onClose,
63
+ onfocusin,
64
+ onfocusout,
65
+ onmouseenter,
66
+ onmouseleave,
50
67
 
51
68
  // Other props
52
69
  contentTag = 'div',
@@ -59,30 +76,54 @@
59
76
  actionProps,
60
77
  mediaTag = 'div',
61
78
  mediaProps,
79
+ closeProps,
62
80
  ...rest
63
81
  }: NeoCardProps = $props();
64
82
  /* eslint-enable prefer-const */
65
83
 
66
- const filter = $derived.by(() => computeGlassFilter(elevation, glass));
84
+ const filter = $derived(computeGlassFilter(elevation, glass));
67
85
 
68
- const boxShadow = $derived.by(() => computeShadowElevation(elevation, glass));
86
+ const boxShadow = $derived(computeShadowElevation(elevation, { glass, pressed, convex }));
69
87
  const hoverElevation = $derived(elevation + hover);
70
- const hoverShadow = $derived.by(() => computeHoverShadowElevation(elevation, hover, glass) ?? boxShadow);
88
+ const hoverShadow = $derived(computeHoverShadowElevation(elevation, hover, { glass, pressed, convex }) ?? boxShadow);
71
89
 
72
- const hoverFlat = $derived(boxShadow.endsWith('flat') && !hoverShadow.endsWith('flat'));
73
- const flatHover = $derived(hoverShadow.endsWith('flat') && !boxShadow.endsWith('flat'));
90
+ const hoverFlat = $derived(isShadowFlat(boxShadow) && !isShadowFlat(hoverShadow));
91
+ const flatHover = $derived(isShadowFlat(hoverShadow) && !isShadowFlat(boxShadow));
74
92
 
75
93
  const segments = $derived([content, header, action, footer, media, close].filter(Boolean).length > 1);
76
94
 
95
+ const onMouseEnter: MouseEventHandler<HTMLDivElement> = e => {
96
+ hovered = true;
97
+ onmouseenter?.(e);
98
+ };
99
+
100
+ const onMouseLeave: MouseEventHandler<HTMLDivElement> = e => {
101
+ hovered = false;
102
+ onmouseleave?.(e);
103
+ };
104
+
105
+ const onFocusIn: FocusEventHandler<HTMLInputElement> = e => {
106
+ focused = true;
107
+ onfocusin?.(e);
108
+ };
109
+
110
+ const onFocusOut: FocusEventHandler<HTMLInputElement> = e => {
111
+ focused = false;
112
+ onfocusout?.(e);
113
+ };
114
+
77
115
  const context: NeoCardContext = $derived({
78
116
  elevation,
79
117
  hover,
118
+ hovered,
119
+ disabled,
80
120
  borderless,
81
121
  rounded,
82
122
  glass,
83
123
  segmented,
84
124
  cover,
85
125
  start,
126
+ skeleton,
86
127
  horizontal,
87
128
  close,
88
129
  onClose,
@@ -100,7 +141,7 @@
100
141
  {#snippet closeBtn()}
101
142
  {#if close}
102
143
  <div class="neo-card-close">
103
- <NeoButton aria-label="Close card" rounded text onclick={onClose}>
144
+ <NeoButton aria-label="Close card" rounded text onclick={onClose} {...closeProps}>
104
145
  {#snippet icon()}
105
146
  <IconClose />
106
147
  {/snippet}
@@ -119,21 +160,28 @@
119
160
 
120
161
  <svelte:element
121
162
  this={tag}
163
+ role="none"
122
164
  bind:this={ref}
123
165
  class:neo-card={true}
124
- class:horizontal
125
- class:borderless
126
- class:segmented={segmented === true}
127
- class:segments
128
- class:image={media && !segments}
129
- class:rounded
130
- class:hover
131
- class:start
132
- class:raised={elevation > 3}
133
- class:flat={!elevation}
134
- class:hover-flat={hoverFlat}
135
- class:flat-hover={flatHover}
136
- class:glass
166
+ class:neo-horizontal={horizontal}
167
+ class:neo-borderless={borderless}
168
+ class:neo-segmented={segmented === true}
169
+ class:neo-segments={segments}
170
+ class:neo-image={media && !segments}
171
+ class:neo-rounded={rounded}
172
+ class:neo-disabled={disabled}
173
+ class:neo-skeleton={skeleton}
174
+ class:neo-pressed={pressed}
175
+ class:neo-convex={convex}
176
+ class:neo-hover={hover}
177
+ class:neo-hovered={hovered}
178
+ class:neo-start={start}
179
+ class:neo-raised={elevation > 3 || hoverElevation > 3}
180
+ class:neo-inset={elevation < -3 || hoverElevation < -3}
181
+ class:neo-flat={!elevation}
182
+ class:neo-hover-flat={hoverFlat}
183
+ class:neo-flat-hover={flatHover}
184
+ class:neo-glass={glass}
137
185
  style:--neo-card-hover-shadow={hoverShadow}
138
186
  style:--neo-card-box-shadow={boxShadow}
139
187
  style:--neo-card-glass-blur={filter}
@@ -144,14 +192,18 @@
144
192
  out:outFn={outProps}
145
193
  in:inFn={inProps}
146
194
  {...rest}
195
+ onmouseenter={onMouseEnter}
196
+ onmouseleave={onMouseLeave}
197
+ onfocusin={onFocusIn}
198
+ onfocusout={onFocusOut}
147
199
  >
148
200
  {#if media}
149
201
  <svelte:element
150
202
  this={mediaTag}
151
203
  class:neo-card-segment={true}
152
204
  class:neo-card-media={true}
153
- class:cover
154
- class:inset={elevation < 0 || hoverElevation < 0}
205
+ class:neo-cover={cover}
206
+ class:neo-inset={elevation < 0 || hoverElevation < 0}
155
207
  {...mediaProps}
156
208
  >
157
209
  {@render media?.(context)}
@@ -193,63 +245,72 @@
193
245
  </svelte:element>
194
246
 
195
247
  <style>.neo-card {
196
- --neo-card-full-spacing: var(--neo-card-spacing, 1.5rem);
197
- --neo-card-half-spacing: calc(var(--neo-card-spacing, 1.5rem) / 2);
198
248
  display: flex;
199
249
  flex-direction: column;
200
250
  box-sizing: border-box;
201
251
  width: fit-content;
202
- margin: var(--neo-shadow-margin, 0.6rem);
203
- padding: var(--neo-card-full-spacing);
252
+ margin: var(--neo-card-margin, var(--neo-shadow-margin, 0.625rem));
253
+ padding: var(--neo-card-spacing, 1.5rem);
204
254
  color: var(--neo-card-text-color, inherit);
205
255
  background-color: var(--neo-card-bg-color, transparent);
206
- border: var(--neo-border-width, 1px) var(--neo-card-border-color, transparent) solid;
256
+ border: var(--neo-card-border-width, var(--neo-border-width, 1px)) var(--neo-card-border-color, transparent) solid;
207
257
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius));
208
258
  box-shadow: var(--neo-card-box-shadow, var(--neo-box-shadow-flat));
209
259
  transition: margin 0.3s ease, color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease, border-radius 0.3s ease, backdrop-filter 0.3s ease, box-shadow 0.3s ease-out;
210
260
  }
211
- .neo-card.borderless {
261
+ .neo-card-content {
262
+ flex: 1 1 auto;
263
+ }
264
+ .neo-card.neo-borderless {
212
265
  border-color: transparent !important;
213
266
  }
214
- .neo-card.raised {
267
+ .neo-card.neo-disabled {
268
+ box-shadow: var(--neo-box-shadow-flat) !important;
269
+ opacity: var(--neo-card-opacity-disabled, var(--neo-opacity-disabled));
270
+ }
271
+ .neo-card.neo-disabled:not(.neo-borderless) {
272
+ border-color: var(--neo-card-border-color-disabled, var(--neo-border-color-disabled)) !important;
273
+ }
274
+ .neo-card.neo-inset.neo-pressed, .neo-card.neo-raised:not(.neo-convex) {
215
275
  margin: var(--neo-shadow-margin-lg, 1.125rem);
216
276
  }
217
- .neo-card.hover.flat-hover:hover, .neo-card.flat:not(.borderless, .hover-flat:hover) {
277
+ .neo-card.neo-hover.neo-flat-hover.neo-hovered, .neo-card.neo-hover.neo-flat-hover:hover, .neo-card.neo-hover.neo-flat-hover:focus-within, .neo-card.neo-flat:not(.neo-borderless, .neo-hover-flat:hover, .neo-hover-flat.neo-hovered, .neo-hover-flat:focus-within) {
218
278
  border-color: var(--neo-card-border-color, var(--neo-border-color));
219
279
  }
220
- .neo-card.hover:hover {
280
+ .neo-card:focus-within, .neo-card.neo-hover:hover, .neo-card.neo-hover.neo-hovered {
221
281
  box-shadow: var(--neo-card-hover-shadow, var(--neo-card-box-shadow));
222
282
  }
223
283
  .neo-card .neo-card-divider {
224
- margin: 0.5rem calc(var(--neo-card-full-spacing) - 0.25rem);
284
+ margin: 0.5rem calc(var(--neo-card-spacing, 1.5rem) - 0.25rem);
225
285
  }
226
286
  .neo-card .neo-card-segment {
227
287
  transition: border-radius 0.3s ease;
228
288
  }
229
289
  .neo-card .neo-card-segment:not(.neo-card-media) {
230
- padding: var(--neo-card-half-spacing) var(--neo-card-full-spacing);
290
+ padding: calc(var(--neo-card-spacing, 1.5rem) / 2) var(--neo-card-spacing, 1.5rem);
231
291
  }
232
292
  .neo-card .neo-card-segment:not(.neo-card-media):first-child {
233
- padding: var(--neo-card-full-spacing) var(--neo-card-full-spacing) var(--neo-card-half-spacing);
293
+ padding: var(--neo-card-spacing, 1.5rem) var(--neo-card-spacing, 1.5rem) calc(var(--neo-card-spacing, 1.5rem) / 2);
234
294
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius)) var(--neo-card-border-radius, var(--neo-border-radius)) 0 0;
235
295
  }
236
296
  .neo-card .neo-card-segment:not(.neo-card-media):last-child {
237
- padding: var(--neo-card-half-spacing) var(--neo-card-full-spacing) var(--neo-card-full-spacing);
297
+ padding: calc(var(--neo-card-spacing, 1.5rem) / 2) var(--neo-card-spacing, 1.5rem) var(--neo-card-spacing, 1.5rem);
238
298
  border-radius: 0 0 var(--neo-card-border-radius, var(--neo-border-radius)) var(--neo-card-border-radius, var(--neo-border-radius));
239
299
  }
240
300
  .neo-card .neo-card-media {
241
- margin: var(--neo-card-full-spacing);
301
+ margin: var(--neo-card-spacing, 1.5rem);
242
302
  overflow: hidden;
243
303
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius));
304
+ scrollbar-gutter: auto;
244
305
  }
245
- .neo-card .neo-card-media.cover:not(.inset) {
306
+ .neo-card .neo-card-media.neo-cover:not(.neo-inset) {
246
307
  padding: 0;
247
308
  }
248
- .neo-card .neo-card-media.cover:not(.inset):not(:only-child) {
249
- margin: 0 0 var(--neo-card-full-spacing);
309
+ .neo-card .neo-card-media.neo-cover:not(.neo-inset):not(:only-child) {
310
+ margin: 0 0 var(--neo-card-spacing, 1.5rem);
250
311
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius)) var(--neo-card-border-radius, var(--neo-border-radius)) 0 0;
251
312
  }
252
- .neo-card .neo-card-media.cover:not(.inset) :global(.neo-skeleton-media) {
313
+ .neo-card .neo-card-media.neo-cover:not(.neo-inset) :global(.neo-skeleton-media) {
253
314
  border-radius: 0;
254
315
  }
255
316
  .neo-card .neo-card-action,
@@ -271,87 +332,129 @@
271
332
  .neo-card:focus-within .neo-card-close, .neo-card:focus .neo-card-close, .neo-card:hover .neo-card-close {
272
333
  opacity: 1;
273
334
  }
274
- .neo-card.image {
335
+ .neo-card.neo-image {
275
336
  padding: 0;
276
337
  }
277
- .neo-card.image .neo-card-media.cover:not(.inset) {
338
+ .neo-card.neo-image .neo-card-media.neo-cover:not(.neo-inset) {
278
339
  margin: 0;
279
340
  }
280
- .neo-card.segments {
341
+ .neo-card.neo-segments {
281
342
  padding: 0;
282
343
  }
283
- .neo-card.segmented .neo-card-segment:not(.neo-card-media) {
284
- padding: var(--neo-card-full-spacing);
344
+ .neo-card.neo-segmented .neo-card-segment:not(.neo-card-media) {
345
+ padding: var(--neo-card-spacing, 1.5rem);
285
346
  }
286
- .neo-card.segmented .neo-card-segment:not(.neo-card-media, :last-child) {
347
+ .neo-card.neo-segmented .neo-card-segment:not(.neo-card-media, :last-child) {
287
348
  border-bottom: var(--neo-border-width, 1px) solid var(--neo-card-border-color, var(--neo-border-color));
288
349
  }
289
- .neo-card.glass {
350
+ .neo-card.neo-glass {
290
351
  --neo-skeleton-color: var(--neo-glass-skeleton-color);
352
+ --neo-border-color: var(--neo-glass-border-color);
291
353
  background-color: var(--neo-card-bg-color, var(--neo-glass-background-color));
292
354
  border-color: var(--neo-card-border-color, var(--neo-glass-top-border-color) var(--neo-glass-right-border-color) var(--neo-glass-bottom-border-color) var(--neo-glass-left-border-color));
293
- backdrop-filter: var(--neo-card-glass-blur, var(--neo-blur-4) var(--neo-saturate-2));
355
+ backdrop-filter: var(--neo-card-glass-blur, var(--neo-blur-3) var(--neo-saturate-2));
294
356
  }
295
357
  @starting-style {
296
- .neo-card.start {
358
+ .neo-card.neo-start {
297
359
  box-shadow: var(--neo-box-shadow-flat);
298
360
  }
299
- .neo-card.start:not(.borderless) {
361
+ .neo-card.neo-start:not(.neo-borderless) {
300
362
  border-color: var(--neo-card-border-color, var(--neo-border-color));
301
363
  }
302
364
  }
303
- .neo-card.horizontal {
365
+ .neo-card.neo-horizontal {
304
366
  flex-direction: row;
305
367
  }
306
- .neo-card.horizontal .neo-card-action {
368
+ .neo-card.neo-horizontal .neo-card-action {
307
369
  flex-direction: column;
308
370
  }
309
- .neo-card.horizontal .neo-card-close {
371
+ .neo-card.neo-horizontal .neo-card-close {
310
372
  align-self: flex-end;
311
373
  margin-bottom: auto;
312
374
  }
313
- .neo-card.horizontal .neo-card-media.cover:not(.inset, :only-child) {
314
- margin: 0 var(--neo-card-full-spacing) 0 0;
375
+ .neo-card.neo-horizontal .neo-card-media.neo-cover:not(.neo-inset, :only-child) {
376
+ margin: 0 var(--neo-card-spacing, 1.5rem) 0 0;
315
377
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius)) 0 0 var(--neo-card-border-radius, var(--neo-border-radius));
316
378
  }
317
- .neo-card.horizontal .neo-card-segment:not(.neo-card-media) {
318
- padding: var(--neo-card-full-spacing) var(--neo-card-half-spacing);
379
+ .neo-card.neo-horizontal .neo-card-segment:not(.neo-card-media) {
380
+ padding: var(--neo-card-spacing, 1.5rem) calc(var(--neo-card-spacing, 1.5rem) / 2);
319
381
  }
320
- .neo-card.horizontal .neo-card-segment:not(.neo-card-media):first-child {
321
- padding: var(--neo-card-full-spacing) var(--neo-card-half-spacing) var(--neo-card-full-spacing) var(--neo-card-full-spacing);
382
+ .neo-card.neo-horizontal .neo-card-segment:not(.neo-card-media):first-child {
383
+ padding: var(--neo-card-spacing, 1.5rem) calc(var(--neo-card-spacing, 1.5rem) / 2) var(--neo-card-spacing, 1.5rem) var(--neo-card-spacing, 1.5rem);
322
384
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius)) 0 0 var(--neo-card-border-radius, var(--neo-border-radius));
323
385
  }
324
- .neo-card.horizontal .neo-card-segment:not(.neo-card-media):last-child {
325
- padding: var(--neo-card-full-spacing) var(--neo-card-full-spacing) var(--neo-card-full-spacing) var(--neo-card-half-spacing);
386
+ .neo-card.neo-horizontal .neo-card-segment:not(.neo-card-media):last-child {
387
+ padding: var(--neo-card-spacing, 1.5rem) var(--neo-card-spacing, 1.5rem) var(--neo-card-spacing, 1.5rem) calc(var(--neo-card-spacing, 1.5rem) / 2);
326
388
  border-radius: 0 var(--neo-card-border-radius, var(--neo-border-radius)) var(--neo-card-border-radius, var(--neo-border-radius)) 0;
327
389
  }
328
- .neo-card.rounded {
390
+ .neo-card.neo-rounded {
329
391
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-lg));
330
392
  }
331
- .neo-card.rounded .neo-card-media {
393
+ .neo-card.neo-rounded .neo-card-media {
332
394
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-md));
333
395
  }
334
- .neo-card.rounded .neo-card-media.cover:not(.inset) {
396
+ .neo-card.neo-rounded .neo-card-media.neo-cover:not(.neo-inset) {
335
397
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-lg));
336
398
  }
337
- .neo-card.rounded .neo-card-media.cover:not(.inset):not(:only-child) {
399
+ .neo-card.neo-rounded .neo-card-media.neo-cover:not(.neo-inset):not(:only-child) {
338
400
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-lg)) var(--neo-card-border-radius, var(--neo-border-radius-lg)) 0 0;
339
401
  }
340
- .neo-card.rounded .neo-card-segment:not(.neo-card-media):first-child {
402
+ .neo-card.neo-rounded .neo-card-segment:not(.neo-card-media):first-child {
341
403
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-lg)) var(--neo-card-border-radius, var(--neo-border-radius-lg)) 0 0;
342
404
  }
343
- .neo-card.rounded .neo-card-segment:not(.neo-card-media):last-child {
405
+ .neo-card.neo-rounded .neo-card-segment:not(.neo-card-media):last-child {
344
406
  border-radius: 0 0 var(--neo-card-border-radius, var(--neo-border-radius-lg)) var(--neo-card-border-radius, var(--neo-border-radius-lg));
345
407
  }
346
- .neo-card.rounded.horizontal .neo-card-segment:not(.neo-card-media):first-child {
408
+ .neo-card.neo-rounded.neo-horizontal .neo-card-segment:not(.neo-card-media):first-child {
347
409
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-lg)) 0 0 var(--neo-card-border-radius, var(--neo-border-radius-lg));
348
410
  }
349
- .neo-card.rounded.horizontal .neo-card-segment:not(.neo-card-media):last-child {
411
+ .neo-card.neo-rounded.neo-horizontal .neo-card-segment:not(.neo-card-media):last-child {
350
412
  border-radius: 0 var(--neo-card-border-radius, var(--neo-border-radius-lg)) var(--neo-card-border-radius, var(--neo-border-radius-lg)) 0;
351
413
  }
352
- .neo-card.rounded.horizontal .neo-card-media.cover:not(.inset, :only-child) {
414
+ .neo-card.neo-rounded.neo-horizontal .neo-card-media.neo-cover:not(.neo-inset, :only-child) {
353
415
  border-radius: var(--neo-card-border-radius, var(--neo-border-radius-lg)) 0 0 var(--neo-card-border-radius, var(--neo-border-radius-lg));
354
416
  }
417
+ .neo-card.neo-skeleton {
418
+ box-shadow: var(--neo-box-shadow-flat);
419
+ pointer-events: none;
420
+ --neo-skeleton-color-start: var(--neo-skeleton-color);
421
+ --neo-skeleton-color-end: oklch(from var(--neo-skeleton-color) calc(l - var(--neo-skeleton-color-step, 0.05)) c h);
422
+ color: var(--neo-skeleton-color-start);
423
+ background-color: var(--neo-skeleton-color-start);
424
+ border-color: var(--neo-skeleton-color-start);
425
+ transition: background-color 1s ease, color 1s ease, border-color 1s ease;
426
+ animation: skeleton 3s var(--neo-transition-skeleton) infinite;
427
+ animation-delay: 1s;
428
+ }
429
+ .neo-card.neo-skeleton::before, .neo-card.neo-skeleton::after,
430
+ .neo-card.neo-skeleton :global(> *::before),
431
+ .neo-card.neo-skeleton :global(> *::after),
432
+ .neo-card.neo-skeleton :global(> *) {
433
+ visibility: hidden;
434
+ pointer-events: none;
435
+ }
436
+ @keyframes skeleton {
437
+ 0% {
438
+ color: var(--neo-skeleton-color-start);
439
+ background-color: var(--neo-skeleton-color-start);
440
+ border-color: var(--neo-skeleton-color-start);
441
+ }
442
+ 40% {
443
+ color: var(--neo-skeleton-color-end);
444
+ background-color: var(--neo-skeleton-color-end);
445
+ border-color: var(--neo-skeleton-color-end);
446
+ }
447
+ 80% {
448
+ color: var(--neo-skeleton-color-start);
449
+ background-color: var(--neo-skeleton-color-start);
450
+ border-color: var(--neo-skeleton-color-start);
451
+ }
452
+ 100% {
453
+ color: var(--neo-skeleton-color-start);
454
+ background-color: var(--neo-skeleton-color-start);
455
+ border-color: var(--neo-skeleton-color-start);
456
+ }
457
+ }
355
458
 
356
459
  .neo-card,
357
460
  .neo-card-media,
@@ -367,7 +470,7 @@
367
470
  .neo-card-content::-webkit-scrollbar,
368
471
  .neo-card-action::-webkit-scrollbar,
369
472
  .neo-card-footer::-webkit-scrollbar {
370
- width: var(--neo-scrollbar-width, 0.45rem);
473
+ width: var(--neo-scrollbar-width, 0.375rem);
371
474
  background-color: transparent;
372
475
  border: none;
373
476
  cursor: pointer;
@@ -408,6 +511,6 @@
408
511
  .neo-card-content::-webkit-resizer,
409
512
  .neo-card-action::-webkit-resizer,
410
513
  .neo-card-footer::-webkit-resizer {
411
- background: url("~/assets/neo-icon-resizer-bottom-right.svg") no-repeat bottom;
514
+ background: url("../assets/neo-icon-resizer-bottom-right.svg") no-repeat bottom;
412
515
  background-clip: border-box;
413
516
  }</style>
@@ -14,6 +14,6 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
14
14
  }
15
15
  declare const NeoCard: $$__sveltets_2_IsomorphicComponent<NeoCardProps, {
16
16
  [evt: string]: CustomEvent<any>;
17
- }, {}, {}, "ref">;
17
+ }, {}, {}, "ref" | "hovered" | "focused">;
18
18
  type NeoCard = InstanceType<typeof NeoCard>;
19
19
  export default NeoCard;
@@ -11,10 +11,30 @@ export type NeoCardContext = {
11
11
  */
12
12
  elevation?: NeoCardElevation;
13
13
  /**
14
- * Weather to increase/decrease the elevation when hovered.
14
+ * Weather to increase/decrease the elevation when hovered/focused.
15
15
  * @default 0
16
16
  */
17
17
  hover?: number;
18
+ /**
19
+ * If the card is currently hovered.
20
+ */
21
+ hovered?: boolean;
22
+ /**
23
+ * If the card has focus within.
24
+ */
25
+ focused?: boolean;
26
+ /**
27
+ * If true, the card will be displayed as a flat card and hover will be ignored.
28
+ */
29
+ disabled?: boolean;
30
+ /**
31
+ * If true, negative elevation (< 0) will be displayed as pressed instead of inset.
32
+ */
33
+ pressed?: boolean;
34
+ /**
35
+ * If true, positive elevation (> 0) will be displayed as convex instead of raised.
36
+ */
37
+ convex?: boolean;
18
38
  /**
19
39
  * By default, cards with no elevation will display a border.
20
40
  * If this is `true`, the card will never display a border.
@@ -42,6 +62,10 @@ export type NeoCardContext = {
42
62
  * @see [@starting-style](https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style) for browser support
43
63
  */
44
64
  start?: boolean;
65
+ /**
66
+ * If true, the card will be disabled and a loading skeleton will be displayed instead of the text.
67
+ */
68
+ skeleton?: boolean;
45
69
  /**
46
70
  * If true, the card will be displayed as a horizontal card.
47
71
  */
@@ -126,4 +150,8 @@ export type NeoCardProps = {
126
150
  * Props for the card media.
127
151
  */
128
152
  mediaProps?: HTMLNeoBaseElement;
153
+ /**
154
+ * Props for the close button.
155
+ */
156
+ closeProps?: NeoButtonProps;
129
157
  } & NeoCardContext & HTMLNeoBaseElement & HTMLFlexProps & HTMLActionProps & HTMLRefProps;
@@ -9,7 +9,9 @@
9
9
  tag = 'div',
10
10
 
11
11
  // Styles
12
- overflow = 'hidden',
12
+ overflow,
13
+ overflowX,
14
+ overflowY,
13
15
  width,
14
16
  height,
15
17
 
@@ -18,7 +20,16 @@
18
20
  }: NeoTransitionContainerProps = $props();
19
21
  </script>
20
22
 
21
- <svelte:element this={tag} class:neo-transition-container={true} style:overflow-x={overflow} style:width style:height {...rest}>
23
+ <svelte:element
24
+ this={tag}
25
+ class:neo-transition-container={true}
26
+ style:overflow
27
+ style:overflow-x={overflowX}
28
+ style:overflow-y={overflowY}
29
+ style:width
30
+ style:height
31
+ {...rest}
32
+ >
22
33
  {@render children?.()}
23
34
  </svelte:element>
24
35
 
@@ -10,10 +10,18 @@ export type NeoTransitionContainerProps = {
10
10
  * @default 'div'
11
11
  */
12
12
  tag?: keyof HTMLElementTagNameMap;
13
+ /**
14
+ * Overflow style (overflow-x).
15
+ */
16
+ overflow?: CSSStyleDeclaration['overflow'];
13
17
  /**
14
18
  * Horizontal overflow style (overflow-x).
15
19
  */
16
- overflow?: CSSStyleDeclaration['overflowX'];
20
+ overflowX?: CSSStyleDeclaration['overflowX'];
21
+ /**
22
+ * Vertical overflow style (overflow-x).
23
+ */
24
+ overflowY?: CSSStyleDeclaration['overflowY'];
17
25
  /**
18
26
  * Width of the container.
19
27
  */
@@ -5,16 +5,16 @@
5
5
 
6
6
  const { elevation = -1, vertical = false, height, width, ...rest }: NeoDividerProps = $props();
7
7
 
8
- const boxShadow = $derived.by(() => computeShadowElevation(elevation));
8
+ const boxShadow = $derived(computeShadowElevation(elevation));
9
9
  </script>
10
10
 
11
11
  <div
12
12
  role="separator"
13
13
  aria-orientation={vertical ? 'vertical' : 'horizontal'}
14
14
  class:neo-divider={true}
15
- class:vertical
16
- class:inset={elevation < 0}
17
- class:flat={!elevation}
15
+ class:neo-vertical={vertical}
16
+ class:neo-inset={elevation < 0}
17
+ class:neo-flat={!elevation}
18
18
  style:--neo-divider-height={height}
19
19
  style:--neo-divider-width={width}
20
20
  style:--neo-divider-box-shadow={boxShadow}
@@ -24,24 +24,24 @@
24
24
  </div>
25
25
 
26
26
  <style>.neo-divider {
27
- width: calc(var(--neo-divider-width, 100%) - var(--neo-shadow-margin, 0.6rem) * 2);
27
+ width: calc(var(--neo-divider-width, 100%) - var(--neo-shadow-margin, 0.625rem) * 2);
28
28
  height: max(4px, var(--neo-divider-height, 4px));
29
- margin: var(--neo-shadow-margin, 0.6rem);
29
+ margin: var(--neo-shadow-margin, 0.625rem);
30
30
  border-radius: var(--neo-divider-border-radius, var(--neo-border-radius-lg));
31
31
  box-shadow: var(--neo-divider-box-shadow, var(--neo-box-shadow-raised-2));
32
32
  }
33
- .neo-divider.inset {
33
+ .neo-divider.neo-inset {
34
34
  height: max(6px, var(--neo-divider-height, 6px));
35
35
  box-shadow: var(--neo-divider-box-shadow, var(--neo-box-shadow-inset-2));
36
36
  }
37
- .neo-divider.vertical {
37
+ .neo-divider.neo-vertical {
38
38
  width: var(--neo-divider-height, 4px);
39
- height: calc(var(--neo-divider-height, 100%) - var(--neo-shadow-margin, 0.6rem) * 2);
39
+ height: calc(var(--neo-divider-height, 100%) - var(--neo-shadow-margin, 0.625rem) * 2);
40
40
  }
41
- .neo-divider.vertical.inset {
41
+ .neo-divider.neo-vertical.neo-inset {
42
42
  width: max(6px, var(--neo-divider-width, 6px));
43
43
  }
44
- .neo-divider.flat {
44
+ .neo-divider.neo-flat {
45
45
  background-color: var(--neo-divider-color, var(--neo-border-color));
46
46
  box-shadow: none;
47
47
  }</style>
@@ -1,5 +1,13 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
2
- <g fill="none" stroke="currentColor" stroke-dasharray="28" stroke-dashoffset="28" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props} style:scale={$$props.scale} scale={undefined}>
2
+ <g
3
+ fill="none"
4
+ stroke="currentColor"
5
+ stroke-dasharray="28"
6
+ stroke-dashoffset="28"
7
+ stroke-linecap="round"
8
+ stroke-linejoin="round"
9
+ stroke-width={$$props.stroke ?? 1.5}
10
+ >
3
11
  <path d="M4 21v-1c0 -3.31 2.69 -6 6 -6h4c3.31 0 6 2.69 6 6v1">
4
12
  <animate fill="freeze" attributeName="stroke-dashoffset" dur="0.4s" values="28;0" />
5
13
  </path>
@@ -1,5 +1,13 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
2
- <g fill="none" stroke="currentColor" stroke-dasharray="16" stroke-dashoffset="16" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props} style:scale={$$props.scale} scale={undefined}>
2
+ <g
3
+ fill="none"
4
+ stroke="currentColor"
5
+ stroke-dasharray="16"
6
+ stroke-dashoffset="16"
7
+ stroke-linecap="round"
8
+ stroke-linejoin="round"
9
+ stroke-width={$$props.stroke ?? 1.5}
10
+ >
3
11
  <path d="M5 12h14">
4
12
  <animate fill="freeze" attributeName="stroke-dashoffset" dur="0.4s" values="16;0" />
5
13
  </path>
@@ -1,5 +1,5 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props}>
2
- <g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5">
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" {...$$props} style:scale={$$props.scale} scale={undefined}>
2
+ <g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width={$$props.stroke ?? 1.5}>
3
3
  <path
4
4
  stroke-dasharray="64"
5
5
  stroke-dashoffset="64"