@santi020k/lumen-astro 0.3.0 → 1.0.0

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 (158) hide show
  1. package/README.md +100 -2
  2. package/components/Accordion.astro +4 -4
  3. package/components/Affix.astro +2 -2
  4. package/components/Agenda.astro +3 -2
  5. package/components/Alert.astro +9 -9
  6. package/components/AlertDialog.astro +7 -13
  7. package/components/Anchor.astro +29 -3
  8. package/components/AnimatedLogo.astro +2 -1
  9. package/components/AnimatedNumber.astro +5 -2
  10. package/components/AnimatedPortrait.astro +46 -36
  11. package/components/AspectRatio.astro +10 -8
  12. package/components/Attachment.astro +24 -24
  13. package/components/Autocomplete.astro +3 -2
  14. package/components/Avatar.astro +4 -3
  15. package/components/BackToTop.astro +2 -2
  16. package/components/Badge.astro +9 -9
  17. package/components/BarChart.astro +211 -0
  18. package/components/Breadcrumb.astro +3 -3
  19. package/components/Bubble.astro +7 -7
  20. package/components/Button.astro +18 -16
  21. package/components/ButtonGroup.astro +3 -3
  22. package/components/ButtonLink.astro +9 -3
  23. package/components/Calendar.astro +43 -31
  24. package/components/Callout.astro +2 -2
  25. package/components/Card.astro +12 -10
  26. package/components/CardContent.astro +26 -0
  27. package/components/CardDescription.astro +26 -0
  28. package/components/CardFooter.astro +26 -0
  29. package/components/CardHeader.astro +26 -0
  30. package/components/CardTitle.astro +26 -0
  31. package/components/Carousel.astro +6 -6
  32. package/components/Cascader.astro +10 -4
  33. package/components/Chart.astro +32 -6
  34. package/components/Checkbox.astro +3 -2
  35. package/components/CheckboxGroup.astro +39 -0
  36. package/components/Code.astro +55 -52
  37. package/components/CodeTabs.astro +6 -6
  38. package/components/Collapsible.astro +3 -3
  39. package/components/ColorPicker.astro +3 -2
  40. package/components/Combobox.astro +4 -5
  41. package/components/Command.astro +6 -6
  42. package/components/Container.astro +29 -0
  43. package/components/ContextMenu.astro +7 -13
  44. package/components/CopyButton.astro +55 -0
  45. package/components/CoverImage.astro +19 -9
  46. package/components/DataTable.astro +50 -49
  47. package/components/DatePicker.astro +20 -17
  48. package/components/DateRangePicker.astro +3 -2
  49. package/components/Descriptions.astro +3 -3
  50. package/components/Dialog.astro +8 -14
  51. package/components/Direction.astro +3 -3
  52. package/components/Drawer.astro +7 -13
  53. package/components/DropdownMenu.astro +7 -13
  54. package/components/Empty.astro +6 -6
  55. package/components/ErrorSummary.astro +54 -0
  56. package/components/Eyebrow.astro +2 -2
  57. package/components/Field.astro +7 -6
  58. package/components/FieldError.astro +29 -0
  59. package/components/FileUpload.astro +2 -2
  60. package/components/FloatingBadge.astro +2 -2
  61. package/components/Form.astro +33 -0
  62. package/components/FormattedDate.astro +2 -2
  63. package/components/GradientDivider.astro +2 -2
  64. package/components/Grid.astro +46 -0
  65. package/components/HoverCard.astro +7 -13
  66. package/components/Icon.astro +8 -6
  67. package/components/Image.astro +2 -1
  68. package/components/Input.astro +6 -5
  69. package/components/InputGroup.astro +3 -3
  70. package/components/InputOTP.astro +5 -3
  71. package/components/Item.astro +11 -8
  72. package/components/Kbd.astro +3 -3
  73. package/components/Label.astro +3 -2
  74. package/components/LanguageToggle.astro +2 -2
  75. package/components/LineChart.astro +244 -0
  76. package/components/Link.astro +6 -5
  77. package/components/ListBox.astro +154 -0
  78. package/components/Marker.astro +6 -6
  79. package/components/Mentions.astro +30 -10
  80. package/components/Menubar.astro +7 -13
  81. package/components/Message.astro +5 -5
  82. package/components/MessageScroller.astro +6 -6
  83. package/components/Meter.astro +1 -0
  84. package/components/NativeSelect.astro +4 -5
  85. package/components/NavigationMenu.astro +9 -14
  86. package/components/Note.astro +1 -1
  87. package/components/NumberField.astro +3 -2
  88. package/components/Pagination.astro +3 -3
  89. package/components/Particles.astro +58 -2
  90. package/components/PasswordField.astro +73 -0
  91. package/components/PhoneInput.astro +5 -7
  92. package/components/PieChart.astro +141 -0
  93. package/components/Pill.astro +15 -9
  94. package/components/Popconfirm.astro +8 -3
  95. package/components/Popover.astro +7 -13
  96. package/components/Progress.astro +12 -4
  97. package/components/Prose.astro +2 -2
  98. package/components/QRCode.astro +13 -5
  99. package/components/RadioGroup.astro +3 -3
  100. package/components/Rating.astro +3 -1
  101. package/components/Resizable.astro +8 -7
  102. package/components/RevealGroup.astro +4 -2
  103. package/components/RichTextEditor.astro +3 -2
  104. package/components/Schedule.astro +3 -2
  105. package/components/ScrollArea.astro +6 -6
  106. package/components/ScrollProgress.astro +38 -0
  107. package/components/ScrollReveal.astro +4 -2
  108. package/components/SearchField.astro +3 -2
  109. package/components/Segmented.astro +4 -6
  110. package/components/Select.astro +23 -14
  111. package/components/Separator.astro +5 -5
  112. package/components/Sheet.astro +7 -13
  113. package/components/Sidebar.astro +9 -14
  114. package/components/Skeleton.astro +4 -3
  115. package/components/SkipLink.astro +2 -2
  116. package/components/Slider.astro +3 -2
  117. package/components/Sonner.astro +3 -3
  118. package/components/Sparkline.astro +72 -0
  119. package/components/SpeedDial.astro +3 -3
  120. package/components/Spinner.astro +4 -3
  121. package/components/Stack.astro +46 -0
  122. package/components/Stat.astro +14 -8
  123. package/components/StatDescription.astro +16 -0
  124. package/components/StatIcon.astro +15 -0
  125. package/components/StatLabel.astro +16 -0
  126. package/components/StatTrend.astro +28 -0
  127. package/components/StatValue.astro +16 -0
  128. package/components/Stepper.astro +11 -8
  129. package/components/Switch.astro +3 -2
  130. package/components/Table.astro +7 -6
  131. package/components/Tabs.astro +6 -6
  132. package/components/TagGroup.astro +3 -2
  133. package/components/Textarea.astro +3 -2
  134. package/components/ThemeBuilder.astro +3 -2
  135. package/components/ThemeToggle.astro +5 -3
  136. package/components/TimeField.astro +3 -2
  137. package/components/Timeline.astro +2 -1
  138. package/components/TimelineItem.astro +2 -1
  139. package/components/Toast.astro +10 -16
  140. package/components/Toggle.astro +3 -2
  141. package/components/ToggleGroup.astro +3 -3
  142. package/components/Toolbar.astro +2 -2
  143. package/components/Tooltip.astro +3 -3
  144. package/components/Tour.astro +3 -3
  145. package/components/Transfer.astro +16 -5
  146. package/components/Tree.astro +3 -2
  147. package/components/TreeGrid.astro +3 -2
  148. package/components/TreeSelect.astro +10 -4
  149. package/components/Typography.astro +3 -3
  150. package/components/VirtualList.astro +3 -2
  151. package/components/VisuallyHidden.astro +27 -0
  152. package/components/Watermark.astro +11 -7
  153. package/forms.ts +46 -0
  154. package/index.ts +31 -0
  155. package/package.json +12 -8
  156. package/runtime/UIPrimitives.astro +3764 -3142
  157. package/runtime/controllers/motion.ts +13 -16
  158. package/index.d.ts +0 -126
package/README.md CHANGED
@@ -18,6 +18,10 @@ enhances all matching Lumen markup on the page.
18
18
  @import "@santi020k/lumen-astro/styles.css";
19
19
  ```
20
20
 
21
+ The stylesheet defaults `--ui-font` to `"Montserrat", "Avenir Next", "Segoe UI", sans-serif`.
22
+ It declares the family stack but does not bundle or load font files. Load Montserrat once through
23
+ your preferred delivery path, or override `--ui-font` in application CSS.
24
+
21
25
  With Tailwind, keep the Lumen import in the same shared CSS entry:
22
26
 
23
27
  ```css
@@ -47,6 +51,35 @@ import { Button, Card, Input } from '@santi020k/lumen-astro'
47
51
  </Card>
48
52
  ```
49
53
 
54
+ ## Forms and Astro Actions
55
+
56
+ `Form` renders a semantic form and preserves native `method`, `action`, `enctype`, autocomplete,
57
+ reset, and no-JavaScript submission. Compose it with `Field`, `Label`, `FieldError`, and
58
+ `ErrorSummary`.
59
+
60
+ Astro Actions remain application-owned. Use `accept: 'form'`, read the result with
61
+ `Astro.getActionResult()`, and pass `ActionInputError` to `normalizeAstroActionErrors()` so field
62
+ errors receive stable control IDs.
63
+
64
+ ```astro
65
+ ---
66
+ import { actions, isInputError } from 'astro:actions'
67
+ import { ErrorSummary, Form, normalizeAstroActionErrors } from '@santi020k/lumen-astro'
68
+
69
+ const result = Astro.getActionResult(actions.updateProfile)
70
+ const errors = result?.error && isInputError(result.error)
71
+ ? normalizeAstroActionErrors(result.error)
72
+ : normalizeAstroActionErrors(result?.error)
73
+ ---
74
+
75
+ <Form action={actions.updateProfile} method="POST">
76
+ <ErrorSummary {errors} />
77
+ <!-- fields -->
78
+ </Form>
79
+ ```
80
+
81
+ See the [Astro Actions form guide](https://lumen.santi020k.com/docs/forms/astro-actions).
82
+
50
83
  Use `Icon` for Lucide icons by name across framework adapters.
51
84
 
52
85
  ```astro
@@ -61,6 +94,58 @@ import { Button, Icon } from '@santi020k/lumen-astro'
61
94
  <Icon name="search" label="Search" />
62
95
  ```
63
96
 
97
+ ## Long-form navigation
98
+
99
+ `Anchor` accepts heading `depth`, `index`, and `description` metadata plus an `activationOffset`.
100
+ Its current link stays synchronized on click and scroll, including at the end of the document.
101
+ `ScrollProgress` derives reading progress from the document and pins the indicator to the top or
102
+ bottom viewport edge. Both use the single root `UIPrimitives` runtime.
103
+
104
+ ```astro
105
+ ---
106
+ import { Anchor, CopyButton, ScrollProgress } from '@santi020k/lumen-astro'
107
+ ---
108
+
109
+ <ScrollProgress aria-label="Article reading progress" />
110
+ <Anchor items={[
111
+ { depth: 2, href: '#install', label: 'Install' },
112
+ { depth: 3, href: '#astro', label: 'Astro' }
113
+ ]} />
114
+ ```
115
+
116
+ `Progress` can be updated after hydration by dispatching `ui:progress-change` from its root with
117
+ `{ value, max? }`. Use `CopyButton` to copy arbitrary text or a referenced element without giving
118
+ non-code content `Code` semantics.
119
+
120
+ ```astro
121
+ <p id="invite">Join the Lumen workspace</p>
122
+ <CopyButton target="#invite" toast>Copy invite</CopyButton>
123
+ ```
124
+
125
+ ## Data visualization
126
+
127
+ Use `Sparkline` beside a metric, `BarChart` for categorical comparison, `LineChart` for ordered
128
+ trends, and `PieChart` for a small part-to-whole breakdown. The chart components accept
129
+ already-aggregated series, use Lumen data-color tokens, and include a revealable semantic data
130
+ table by default.
131
+
132
+ ```astro
133
+ ---
134
+ import { LineChart } from '@santi020k/lumen-astro'
135
+
136
+ const series = [{
137
+ id: 'views',
138
+ label: 'Views',
139
+ data: [{ x: 'Mon', y: 42 }, { x: 'Tue', y: 68 }]
140
+ }]
141
+ ---
142
+
143
+ <LineChart aria-label="Views by day" heading="Website traffic" {series} />
144
+ ```
145
+
146
+ `PieChart` accepts one `LumenChartSeries`; its data points become slices. It defaults to
147
+ `variant="donut"` and also supports `variant="pie"`.
148
+
64
149
  Lucide intentionally excludes brand marks. For GitHub and other project-specific icons, put the
65
150
  SVG in the default slot instead of passing an unsupported `name`; Astro warns about unknown named
66
151
  icons during development.
@@ -158,8 +243,7 @@ content readable without JavaScript and honor reduced-motion preferences.
158
243
 
159
244
  Lumen includes glassmorphism tokens and reusable classes in the shared stylesheet. Cards use a
160
245
  boolean prop, and overlays or navigation primitives use the same prop while preserving semantic
161
- variants. The older `variant="glass"` form remains supported for cards. Overlay
162
- `surface="glass"` props are deprecated compatibility aliases that map to `glass`.
246
+ variants. The older `variant="glass"` form remains supported for cards.
163
247
 
164
248
  ```astro
165
249
  <Card glass>Glass card</Card>
@@ -168,3 +252,17 @@ variants. The older `variant="glass"` form remains supported for cards. Overlay
168
252
  <DatePicker glass="subtle" />
169
253
  <Select glass="strong" options={['Astro', 'React']} />
170
254
  ```
255
+
256
+ ## Semantic stat roots
257
+
258
+ `Stat` renders a `div` by default. Use `as="article"` when the metric and its supporting content
259
+ form a standalone item, or `as="section"` when it is a labeled region in a larger view.
260
+
261
+ ```astro
262
+ <Stat as="article" label="Active workspaces" value="1,234" variant="accent">
263
+ <p>Across all production organizations.</p>
264
+ </Stat>
265
+ ```
266
+
267
+ Use `variant="default"` for the original neutral surface, `variant="accent"` for a featured metric,
268
+ or `variant="glass"` for selective translucency.
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  type AccordionVariant = 'default' | 'flush'
7
7
 
8
8
  interface Props extends HTMLAttributes<'div'> {
@@ -19,8 +19,8 @@ const {
19
19
  } = Astro.props
20
20
 
21
21
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
22
- 'ui-accordion',
23
- variant === 'flush' && 'ui-accordion--flush'
22
+ 'ui-accordion',
23
+ variant === 'flush' && 'ui-accordion--flush'
24
24
  ], classProp, className)
25
25
  ---
26
26
 
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'div'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'section'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -10,6 +10,7 @@ interface Props extends HTMLAttributes<'section'> {
10
10
  }
11
11
 
12
12
  const { class: classProp = '', className = '', glass = false, ...rest } = Astro.props
13
+
13
14
  const { classList, passthrough } = resolveLumenAstroProps(rest, ['ui-agenda', glass && 'ui-agenda--glass', glass === 'subtle' && 'ui-glass-subtle', glass === 'strong' && 'ui-glass-strong'
14
15
  ], classProp, className)
15
16
  ---
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'aside'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -19,13 +19,13 @@ const {
19
19
  } = Astro.props
20
20
 
21
21
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
22
- 'ui-alert',
23
- variant === 'destructive' && 'ui-alert--destructive',
24
- variant === 'success' && 'ui-alert--success',
25
- variant === 'warning' && 'ui-alert--warning',
26
- glass && 'ui-alert--glass',
27
- glass === 'subtle' && 'ui-glass-subtle',
28
- glass === 'strong' && 'ui-glass-strong'
22
+ 'ui-alert',
23
+ variant === 'destructive' && 'ui-alert--destructive',
24
+ variant === 'success' && 'ui-alert--success',
25
+ variant === 'warning' && 'ui-alert--warning',
26
+ glass && 'ui-alert--glass',
27
+ glass === 'subtle' && 'ui-glass-subtle',
28
+ glass === 'strong' && 'ui-glass-strong'
29
29
  ], classProp, className)
30
30
  ---
31
31
 
@@ -1,37 +1,31 @@
1
1
  ---
2
- import { resolveLumenAstroProps, resolveLumenGlass } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'dialog'> {
7
7
  class?: string | null
8
8
  className?: string
9
9
  glass?: boolean | 'subtle' | 'strong'
10
- /**
11
- * @deprecated Use `glass` instead. `surface="glass"` maps to `glass={true}`.
12
- */
13
- surface?: 'default' | 'glass'
14
10
  }
15
11
 
16
12
  const {
17
13
  class: classProp = '',
18
14
  className = '',
19
15
  glass = false,
20
- surface = 'default',
21
16
  ...rest
22
17
  } = Astro.props
23
18
 
24
- const resolvedGlass = resolveLumenGlass(glass, surface)
25
19
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
26
- 'ui-dialog ui-alert-dialog',
27
- resolvedGlass && 'ui-dialog--glass',
28
- glass === 'subtle' && 'ui-glass-subtle',
29
- glass === 'strong' && 'ui-glass-strong'
20
+ 'ui-dialog ui-alert-dialog',
21
+ glass && 'ui-dialog--glass',
22
+ glass === 'subtle' && 'ui-glass-subtle',
23
+ glass === 'strong' && 'ui-glass-strong'
30
24
  ], classProp, className)
31
25
  ---
32
26
 
33
27
  <dialog
34
- data-surface={resolvedGlass ? 'glass' : 'default'}
28
+ data-surface={glass ? 'glass' : 'default'}
35
29
  data-ui-alert-dialog
36
30
  role="alertdialog"
37
31
  class:list={classList}
@@ -1,18 +1,28 @@
1
1
  ---
2
+ import type { HTMLAttributes } from 'astro/types'
3
+
2
4
  import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
5
 
4
- import type { HTMLAttributes } from 'astro/types'
6
+ type AnchorDepth = 1 | 2 | 3 | 4 | 5 | 6
5
7
 
6
- type AnchorLink = { href: string; label: string }
8
+ interface AnchorLink {
9
+ description?: string
10
+ depth?: AnchorDepth
11
+ href: string
12
+ index?: number | string
13
+ label: string
14
+ }
7
15
 
8
16
  export interface Props extends HTMLAttributes<'nav'> {
9
17
  class?: string | null
10
18
  className?: string
19
+ activationOffset?: number
11
20
  items?: AnchorLink[]
12
21
  }
13
22
 
14
23
  const {
15
24
  'aria-label': ariaLabel = 'On this page',
25
+ activationOffset = 96,
16
26
  class: classProp = '',
17
27
  className = '',
18
28
  items = [],
@@ -28,13 +38,29 @@ const { classList, passthrough } = resolveLumenAstroProps(rest, [
28
38
  aria-label={ariaLabel}
29
39
  class:list={classList}
30
40
  data-ui-anchor
41
+ data-ui-anchor-offset={Math.max(0, activationOffset)}
31
42
  {...passthrough}
32
43
  >
33
44
  {items.length > 0 && (
34
45
  <ol>
35
46
  {items.map((item, index) => (
36
47
  <li>
37
- <a data-active={index === 0 ? 'true' : 'false'} href={item.href}>{item.label}</a>
48
+ <a
49
+ aria-current={index === 0 ? 'location' : undefined}
50
+ data-active={index === 0 ? 'true' : 'false'}
51
+ data-depth={item.depth}
52
+ href={item.href}
53
+ >
54
+ {item.index !== undefined && (
55
+ <span class="ui-anchor__index">{item.index}</span>
56
+ )}
57
+ <span class="ui-anchor__content">
58
+ <span class="ui-anchor__label">{item.label}</span>
59
+ {item.description && (
60
+ <span class="ui-anchor__description">{item.description}</span>
61
+ )}
62
+ </span>
63
+ </a>
38
64
  </li>
39
65
  ))}
40
66
  </ol>
@@ -1,7 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
2
  import type { HTMLAttributes } from 'astro/types'
4
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
5
6
  interface Props extends HTMLAttributes<'span'> {
6
7
  animation?: 'reveal' | 'sequence'
7
8
  class?: string | null
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends Omit<HTMLAttributes<'span'>, 'prefix'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -29,11 +29,14 @@ const {
29
29
  } = Astro.props
30
30
 
31
31
  const safeDecimals = Math.max(0, Math.min(20, Math.floor(decimals)))
32
+
32
33
  const formatter = new Intl.NumberFormat(locale, {
33
34
  maximumFractionDigits: safeDecimals,
34
35
  minimumFractionDigits: safeDecimals
35
36
  })
37
+
36
38
  const formattedValue = `${prefix}${formatter.format(value)}${suffix}`
39
+
37
40
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
38
41
  'ui-animated-number',
39
42
  `ui-motion-duration-${duration}`
@@ -1,9 +1,10 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
2
  import type { ImageMetadata } from 'astro'
3
+ import type { HTMLAttributes } from 'astro/types'
4
+
4
5
  import { Picture } from 'astro:assets'
5
6
 
6
- import type { HTMLAttributes } from 'astro/types'
7
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
7
8
 
8
9
  interface Props extends HTMLAttributes<'div'> {
9
10
  alt: string
@@ -70,42 +71,48 @@ const { classList, passthrough } = resolveLumenAstroProps(rest, [
70
71
  aria-hidden="true"
71
72
  class="ui-animated-portrait__wash"
72
73
  />
73
- {typeof src === 'string'
74
- ? (
75
- <Picture
76
- alt={alt}
77
- class="ui-animated-portrait__image"
78
- decoding="sync"
79
- fetchpriority="high"
80
- formats={['avif', 'webp']}
81
- height={440}
82
- loading="eager"
83
- sizes={sizes}
84
- src={src}
85
- width={352}
86
- widths={widths}
87
- />
88
- )
89
- : (
90
- <Picture
91
- alt={alt}
92
- class="ui-animated-portrait__image"
93
- decoding="sync"
94
- fetchpriority="high"
95
- formats={['avif', 'webp']}
96
- height={440}
97
- loading="eager"
98
- sizes={sizes}
99
- src={src}
100
- width={352}
101
- widths={widths}
102
- />
103
- )}
74
+ {typeof src === 'string' ?
75
+ (
76
+ <Picture
77
+ alt={alt}
78
+ class="ui-animated-portrait__image"
79
+ decoding="sync"
80
+ fetchpriority="high"
81
+ formats={['avif', 'webp']}
82
+ height={440}
83
+ loading="eager"
84
+ sizes={sizes}
85
+ src={src}
86
+ width={352}
87
+ widths={widths}
88
+ />
89
+ ) :
90
+ (
91
+ <Picture
92
+ alt={alt}
93
+ class="ui-animated-portrait__image"
94
+ decoding="sync"
95
+ fetchpriority="high"
96
+ formats={['avif', 'webp']}
97
+ height={440}
98
+ loading="eager"
99
+ sizes={sizes}
100
+ src={src}
101
+ width={352}
102
+ widths={widths}
103
+ />
104
+ )}
104
105
  </div>
105
106
 
106
107
  {showFloatingBadges && badgeProps?.location && (
107
- <div class="ui-animated-portrait__badge ui-animated-portrait__badge--location">
108
- <p class="ui-animated-portrait__label ui-animated-portrait__label--location">
108
+ <div class="
109
+ ui-animated-portrait__badge ui-animated-portrait__badge--location
110
+ "
111
+ >
112
+ <p class="
113
+ ui-animated-portrait__label ui-animated-portrait__label--location
114
+ "
115
+ >
109
116
  <span class="ui-animated-portrait__status" />
110
117
  {badgeProps.location.label}
111
118
  </p>
@@ -114,7 +121,10 @@ const { classList, passthrough } = resolveLumenAstroProps(rest, [
114
121
  )}
115
122
 
116
123
  {showFloatingBadges && badgeProps?.experience && (
117
- <div class="ui-animated-portrait__badge ui-animated-portrait__badge--experience">
124
+ <div class="
125
+ ui-animated-portrait__badge ui-animated-portrait__badge--experience
126
+ "
127
+ >
118
128
  <p class="ui-animated-portrait__label">{badgeProps.experience.label}</p>
119
129
  <p class="ui-animated-portrait__experience">
120
130
  {badgeProps.experience.value}
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'div'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -17,16 +17,18 @@ const {
17
17
  } = Astro.props
18
18
 
19
19
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
20
- 'ui-aspect-ratio'
20
+ 'ui-aspect-ratio'
21
21
  ], classProp, className)
22
- const ratioValue = typeof ratio === 'number' && Number.isFinite(ratio)
23
- ? String(ratio)
24
- : typeof ratio === 'string'
25
- ? ratio.trim()
26
- : ''
22
+
23
+ let ratioValue = ''
24
+
25
+ if (typeof ratio === 'number' && Number.isFinite(ratio)) ratioValue = String(ratio)
26
+ else if (typeof ratio === 'string') ratioValue = ratio.trim()
27
+
27
28
  const isValidRatio =
28
29
  /^\d+(\.\d+)?(\s*\/\s*\d+(\.\d+)?)?$/.test(ratioValue) &&
29
30
  ratioValue.split('/').every(value => Number(value.trim()) > 0)
31
+
30
32
  const safeRatio = isValidRatio ? ratioValue : '16 / 9'
31
33
  ---
32
34
 
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'article'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -19,28 +19,28 @@ const {
19
19
  } = Astro.props
20
20
 
21
21
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
22
- 'ui-attachment',
23
- glass && 'ui-attachment--glass',
24
- glass === 'subtle' && 'ui-glass-subtle',
25
- glass === 'strong' && 'ui-glass-strong'
22
+ 'ui-attachment',
23
+ glass && 'ui-attachment--glass',
24
+ glass === 'subtle' && 'ui-glass-subtle',
25
+ glass === 'strong' && 'ui-glass-strong'
26
26
  ], classProp, className)
27
27
  ---
28
28
 
29
- {href
30
- ? (
31
- <a
32
- href={href}
33
- class:list={classList}
34
- {...passthrough}
35
- >
36
- <slot />
37
- </a>
38
- )
39
- : (
40
- <article
41
- class:list={classList}
42
- {...passthrough}
43
- >
44
- <slot />
45
- </article>
46
- )}
29
+ {href ?
30
+ (
31
+ <a
32
+ href={href}
33
+ class:list={classList}
34
+ {...passthrough}
35
+ >
36
+ <slot />
37
+ </a>
38
+ ) :
39
+ (
40
+ <article
41
+ class:list={classList}
42
+ {...passthrough}
43
+ >
44
+ <slot />
45
+ </article>
46
+ )}
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'input'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -10,6 +10,7 @@ interface Props extends HTMLAttributes<'input'> {
10
10
  }
11
11
 
12
12
  const { class: classProp = '', className = '', type = 'search', ...rest } = Astro.props
13
+
13
14
  const { classList, passthrough } = resolveLumenAstroProps(rest, ['ui-input', 'ui-autocomplete'
14
15
  ], classProp, className)
15
16
  ---
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'span'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -22,8 +22,9 @@ const {
22
22
 
23
23
  const hasDefaultSlot = Astro.slots.has('default')
24
24
  const fallbackText = fallback ?? (!src && !hasDefaultSlot ? '?' : undefined)
25
+
25
26
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
26
- 'ui-avatar'
27
+ 'ui-avatar'
27
28
  ], classProp, className)
28
29
  ---
29
30
 
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'button'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -1,8 +1,8 @@
1
1
  ---
2
- import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
-
4
2
  import type { HTMLAttributes } from 'astro/types'
5
3
 
4
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
5
+
6
6
  interface Props extends HTMLAttributes<'span'> {
7
7
  class?: string | null
8
8
  className?: string
@@ -17,13 +17,13 @@ const {
17
17
  } = Astro.props
18
18
 
19
19
  const { classList, passthrough } = resolveLumenAstroProps(rest, [
20
- 'ui-badge',
21
- variant === 'default' && 'ui-badge--default',
22
- variant === 'secondary' && 'ui-badge--secondary',
23
- variant === 'outline' && 'ui-badge--outline',
24
- variant === 'destructive' && 'ui-badge--destructive',
25
- variant === 'success' && 'ui-badge--success',
26
- variant === 'warning' && 'ui-badge--warning'
20
+ 'ui-badge',
21
+ variant === 'default' && 'ui-badge--default',
22
+ variant === 'secondary' && 'ui-badge--secondary',
23
+ variant === 'outline' && 'ui-badge--outline',
24
+ variant === 'destructive' && 'ui-badge--destructive',
25
+ variant === 'success' && 'ui-badge--success',
26
+ variant === 'warning' && 'ui-badge--warning'
27
27
  ], classProp, className)
28
28
  ---
29
29