@santi020k/lumen-astro 0.1.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 (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -0
  3. package/components/Accordion.astro +27 -0
  4. package/components/Affix.astro +41 -0
  5. package/components/Agenda.astro +19 -0
  6. package/components/Alert.astro +38 -0
  7. package/components/AlertDialog.astro +41 -0
  8. package/components/Anchor.astro +43 -0
  9. package/components/AnimatedLogo.astro +30 -0
  10. package/components/AnimatedNumber.astro +56 -0
  11. package/components/AnimatedPortrait.astro +124 -0
  12. package/components/AspectRatio.astro +39 -0
  13. package/components/Attachment.astro +46 -0
  14. package/components/Autocomplete.astro +24 -0
  15. package/components/Avatar.astro +36 -0
  16. package/components/BackToTop.astro +30 -0
  17. package/components/Badge.astro +36 -0
  18. package/components/Breadcrumb.astro +28 -0
  19. package/components/Bubble.astro +36 -0
  20. package/components/Button.astro +52 -0
  21. package/components/ButtonGroup.astro +27 -0
  22. package/components/ButtonLink.astro +58 -0
  23. package/components/Calendar.astro +197 -0
  24. package/components/Callout.astro +27 -0
  25. package/components/Card.astro +40 -0
  26. package/components/Carousel.astro +33 -0
  27. package/components/Cascader.astro +109 -0
  28. package/components/Chart.astro +32 -0
  29. package/components/Checkbox.astro +22 -0
  30. package/components/Code.astro +96 -0
  31. package/components/Collapsible.astro +28 -0
  32. package/components/ColorPicker.astro +16 -0
  33. package/components/Combobox.astro +67 -0
  34. package/components/Command.astro +33 -0
  35. package/components/ContextMenu.astro +44 -0
  36. package/components/CoverImage.astro +180 -0
  37. package/components/DataTable.astro +122 -0
  38. package/components/DatePicker.astro +108 -0
  39. package/components/DateRangePicker.astro +18 -0
  40. package/components/Descriptions.astro +41 -0
  41. package/components/Dialog.astro +40 -0
  42. package/components/Direction.astro +30 -0
  43. package/components/Drawer.astro +40 -0
  44. package/components/DropdownMenu.astro +40 -0
  45. package/components/Empty.astro +32 -0
  46. package/components/Eyebrow.astro +27 -0
  47. package/components/Field.astro +42 -0
  48. package/components/FileUpload.astro +44 -0
  49. package/components/FloatingBadge.astro +27 -0
  50. package/components/FormattedDate.astro +27 -0
  51. package/components/GradientDivider.astro +24 -0
  52. package/components/HoverCard.astro +40 -0
  53. package/components/Icon.astro +50 -0
  54. package/components/Image.astro +33 -0
  55. package/components/Input.astro +24 -0
  56. package/components/InputGroup.astro +27 -0
  57. package/components/InputOTP.astro +60 -0
  58. package/components/Item.astro +32 -0
  59. package/components/Kbd.astro +27 -0
  60. package/components/Label.astro +18 -0
  61. package/components/LanguageToggle.astro +30 -0
  62. package/components/Link.astro +27 -0
  63. package/components/Marker.astro +33 -0
  64. package/components/Mentions.astro +47 -0
  65. package/components/Menubar.astro +40 -0
  66. package/components/Message.astro +32 -0
  67. package/components/MessageScroller.astro +32 -0
  68. package/components/Meter.astro +31 -0
  69. package/components/NativeSelect.astro +37 -0
  70. package/components/NavigationMenu.astro +40 -0
  71. package/components/Note.astro +23 -0
  72. package/components/NumberField.astro +16 -0
  73. package/components/Pagination.astro +28 -0
  74. package/components/Particles.astro +31 -0
  75. package/components/PhoneInput.astro +86 -0
  76. package/components/Pill.astro +30 -0
  77. package/components/Popconfirm.astro +40 -0
  78. package/components/Popover.astro +40 -0
  79. package/components/Progress.astro +30 -0
  80. package/components/Prose.astro +27 -0
  81. package/components/QRCode.astro +44 -0
  82. package/components/RadioGroup.astro +28 -0
  83. package/components/Rating.astro +42 -0
  84. package/components/Resizable.astro +55 -0
  85. package/components/RevealGroup.astro +54 -0
  86. package/components/RichTextEditor.astro +19 -0
  87. package/components/Schedule.astro +19 -0
  88. package/components/ScrollArea.astro +32 -0
  89. package/components/ScrollReveal.astro +50 -0
  90. package/components/SearchField.astro +16 -0
  91. package/components/Segmented.astro +56 -0
  92. package/components/Select.astro +120 -0
  93. package/components/Separator.astro +31 -0
  94. package/components/Sheet.astro +40 -0
  95. package/components/Sidebar.astro +39 -0
  96. package/components/Skeleton.astro +36 -0
  97. package/components/SkipLink.astro +27 -0
  98. package/components/Slider.astro +20 -0
  99. package/components/Sonner.astro +38 -0
  100. package/components/SpeedDial.astro +77 -0
  101. package/components/Spinner.astro +36 -0
  102. package/components/Stat.astro +34 -0
  103. package/components/Stepper.astro +57 -0
  104. package/components/Switch.astro +23 -0
  105. package/components/Table.astro +32 -0
  106. package/components/Tabs.astro +33 -0
  107. package/components/TagGroup.astro +18 -0
  108. package/components/Textarea.astro +17 -0
  109. package/components/ThemeBuilder.astro +19 -0
  110. package/components/ThemeToggle.astro +41 -0
  111. package/components/TimeField.astro +16 -0
  112. package/components/Timeline.astro +12 -0
  113. package/components/TimelineItem.astro +19 -0
  114. package/components/Toast.astro +50 -0
  115. package/components/Toggle.astro +25 -0
  116. package/components/ToggleGroup.astro +28 -0
  117. package/components/Toolbar.astro +36 -0
  118. package/components/Tooltip.astro +27 -0
  119. package/components/Tour.astro +52 -0
  120. package/components/Transfer.astro +70 -0
  121. package/components/Tree.astro +19 -0
  122. package/components/TreeGrid.astro +19 -0
  123. package/components/TreeSelect.astro +69 -0
  124. package/components/Typography.astro +27 -0
  125. package/components/VirtualList.astro +19 -0
  126. package/components/Watermark.astro +60 -0
  127. package/index.d.ts +125 -0
  128. package/index.ts +125 -0
  129. package/package.json +74 -0
  130. package/runtime/UIPrimitives.astro +4649 -0
  131. package/styles/lumen.css +5 -0
@@ -0,0 +1,24 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'input'> {
7
+ class?: string
8
+ className?: string
9
+ list: string
10
+ }
11
+
12
+ const { class: classProp = '', className = '', type = 'search', ...rest } = Astro.props
13
+ const { classList, passthrough } = resolveLumenAstroProps(rest, ['ui-input', 'ui-autocomplete'
14
+ ], classProp, className)
15
+ ---
16
+
17
+ {/* No explicit role: an input with a `list` attribute already has native combobox
18
+ semantics, and the browser manages aria-expanded for the datalist popup. */}
19
+ <input
20
+ aria-autocomplete="list"
21
+ class:list={classList}
22
+ type={type}
23
+ {...passthrough}
24
+ />
@@ -0,0 +1,36 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'span'> {
7
+ class?: string
8
+ className?: string
9
+ alt?: string
10
+ fallback?: string
11
+ src?: string
12
+ }
13
+
14
+ const {
15
+ class: classProp = '',
16
+ className = '',
17
+ alt = '',
18
+ fallback,
19
+ src,
20
+ ...rest
21
+ } = Astro.props
22
+
23
+ const hasDefaultSlot = Astro.slots.has('default')
24
+ const fallbackText = fallback ?? (!src && !hasDefaultSlot ? '?' : undefined)
25
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
26
+ 'ui-avatar'
27
+ ], classProp, className)
28
+ ---
29
+
30
+ <span
31
+ class:list={classList}
32
+ {...passthrough}
33
+ >
34
+ {src ? <img alt={alt} src={src} /> : fallbackText && <span aria-hidden={fallback ? undefined : 'true'}>{fallbackText}</span>}
35
+ <slot />
36
+ </span>
@@ -0,0 +1,30 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'button'> {
7
+ class?: string
8
+ className?: string
9
+ }
10
+
11
+ const {
12
+ class: classProp = '',
13
+ className = '',
14
+ type = 'button',
15
+ ...rest
16
+ } = Astro.props
17
+
18
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
19
+ 'ui-back-to-top'
20
+ ], classProp, className)
21
+ ---
22
+
23
+ <button
24
+ type={type}
25
+ class:list={classList}
26
+ data-ui-back-to-top
27
+ {...passthrough}
28
+ >
29
+ <slot />
30
+ </button>
@@ -0,0 +1,36 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'span'> {
7
+ class?: string
8
+ className?: string
9
+ variant?: 'default' | 'secondary' | 'outline' | 'destructive' | 'success' | 'warning'
10
+ }
11
+
12
+ const {
13
+ class: classProp = '',
14
+ className = '',
15
+ variant = 'default',
16
+ ...rest
17
+ } = Astro.props
18
+
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'
27
+ ], classProp, className)
28
+ ---
29
+
30
+ <span
31
+ data-variant={variant}
32
+ class:list={classList}
33
+ {...passthrough}
34
+ >
35
+ <slot />
36
+ </span>
@@ -0,0 +1,28 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'nav'> {
7
+ class?: string
8
+ className?: string
9
+ }
10
+
11
+ const {
12
+ class: classProp = '',
13
+ className = '',
14
+ ...rest
15
+ } = Astro.props
16
+
17
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
18
+ 'ui-breadcrumb'
19
+ ], classProp, className)
20
+ ---
21
+
22
+ <nav
23
+ aria-label="Breadcrumb"
24
+ class:list={classList}
25
+ {...passthrough}
26
+ >
27
+ <slot />
28
+ </nav>
@@ -0,0 +1,36 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'article'> {
7
+ class?: string
8
+ className?: string
9
+ from?: 'user' | 'assistant'
10
+ glass?: boolean | 'subtle' | 'strong'
11
+ }
12
+
13
+ const {
14
+ class: classProp = '',
15
+ className = '',
16
+ from = 'assistant',
17
+ glass = false,
18
+ ...rest
19
+ } = Astro.props
20
+
21
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
22
+ 'ui-bubble',
23
+ from === 'user' && 'ui-bubble--user',
24
+ glass && 'ui-bubble--glass',
25
+ glass === 'subtle' && 'ui-glass-subtle',
26
+ glass === 'strong' && 'ui-glass-strong'
27
+ ], classProp, className)
28
+ ---
29
+
30
+ <article
31
+ data-from={from}
32
+ class:list={classList}
33
+ {...passthrough}
34
+ >
35
+ <slot />
36
+ </article>
@@ -0,0 +1,52 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'button'> {
7
+ class?: string
8
+ className?: string
9
+ loading?: boolean
10
+ size?: 'default' | 'sm' | 'lg' | 'icon'
11
+ variant?: 'default' | 'destructive' | 'ghost' | 'link' | 'outline' | 'secondary'
12
+ }
13
+
14
+ const {
15
+ class: classProp = '',
16
+ className = '',
17
+ disabled,
18
+ loading = false,
19
+ size = 'default',
20
+ type = 'button',
21
+ variant = 'default',
22
+ ...rest
23
+ } = Astro.props
24
+
25
+ const isDisabled = Boolean(disabled) || loading
26
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
27
+ 'ui-button',
28
+ variant === 'default' && 'ui-button--default',
29
+ variant === 'destructive' && 'ui-button--destructive',
30
+ variant === 'ghost' && 'ui-button--ghost',
31
+ variant === 'link' && 'ui-button--link',
32
+ variant === 'outline' && 'ui-button--outline',
33
+ variant === 'secondary' && 'ui-button--secondary',
34
+ size === 'default' && 'ui-button--default-size',
35
+ size === 'sm' && 'ui-button--sm',
36
+ size === 'lg' && 'ui-button--lg',
37
+ size === 'icon' && 'ui-button--icon',
38
+ isDisabled && 'ui-button--disabled',
39
+ loading && 'ui-button--loading'
40
+ ], classProp, className)
41
+ ---
42
+
43
+ <button
44
+ class:list={classList}
45
+ aria-busy={loading || undefined}
46
+ disabled={isDisabled || undefined}
47
+ type={type}
48
+ {...passthrough}
49
+ >
50
+ {loading && <span aria-hidden="true" class="ui-spinner"></span>}
51
+ <slot />
52
+ </button>
@@ -0,0 +1,27 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'div'> {
7
+ class?: string
8
+ className?: string
9
+ }
10
+
11
+ const {
12
+ class: classProp = '',
13
+ className = '',
14
+ ...rest
15
+ } = Astro.props
16
+
17
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
18
+ 'ui-button-group'
19
+ ], classProp, className)
20
+ ---
21
+
22
+ <div
23
+ class:list={classList}
24
+ {...passthrough}
25
+ >
26
+ <slot />
27
+ </div>
@@ -0,0 +1,58 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+ import Icon from './Icon.astro'
4
+
5
+ import type { HTMLAttributes } from 'astro/types'
6
+
7
+ interface Props extends HTMLAttributes<'a'> {
8
+ ariaLabel?: string
9
+ class?: string
10
+ className?: string
11
+ href: string
12
+ newTab?: boolean
13
+ shape?: 'default' | 'icon'
14
+ showArrow?: boolean
15
+ variant?: 'ghost' | 'inline' | 'primary' | 'secondary'
16
+ }
17
+
18
+ const {
19
+ ariaLabel,
20
+ class: classProp = '',
21
+ className = '',
22
+ href,
23
+ newTab = false,
24
+ shape = 'default',
25
+ showArrow = false,
26
+ variant = 'primary',
27
+ ...rest
28
+ } = Astro.props
29
+
30
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
31
+ 'ui-button-link',
32
+ 'group inline-flex cursor-pointer items-center justify-center gap-2 text-sm font-semibold tracking-[0.01em]',
33
+ variant !== 'inline' && 'min-h-11 rounded-full border',
34
+ variant === 'primary' && 'ui-button ui-button--primary',
35
+ variant === 'secondary' && 'ui-button ui-button--secondary',
36
+ variant === 'ghost' && 'ui-button ui-button--ghost',
37
+ variant === 'inline' && 'ui-button ui-button--inline',
38
+ shape === 'icon' && variant !== 'inline' && 'ui-button-link--icon'
39
+ ], classProp, className)
40
+ ---
41
+
42
+ <a
43
+ aria-label={ariaLabel}
44
+ class:list={classList}
45
+ href={href}
46
+ rel={newTab ? 'noreferrer noopener' : undefined}
47
+ target={newTab ? '_blank' : undefined}
48
+ {...passthrough}
49
+ >
50
+ <slot />
51
+ {showArrow && (
52
+ <Icon
53
+ aria-hidden="true"
54
+ class="size-4 shrink-0 transition-transform duration-200 motion-safe:group-hover:translate-x-0.5 motion-reduce:transition-none"
55
+ name={newTab ? 'arrow-up-right' : 'arrow-right'}
56
+ />
57
+ )}
58
+ </a>
@@ -0,0 +1,197 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends Omit<HTMLAttributes<'div'>, 'value'> {
7
+ class?: string
8
+ className?: string
9
+ disabled?: boolean
10
+ glass?: boolean | 'subtle' | 'strong'
11
+ max?: string
12
+ min?: string
13
+ month?: string
14
+ name?: string
15
+ value?: string
16
+ }
17
+
18
+ const isoDatePattern = /^\d{4}-\d{2}-\d{2}$/
19
+ const isoMonthPattern = /^\d{4}-\d{2}$/
20
+ const weekdayFormatter = new Intl.DateTimeFormat('en', { timeZone: 'UTC', weekday: 'short' })
21
+ const monthFormatter = new Intl.DateTimeFormat('en', { month: 'long', timeZone: 'UTC', year: 'numeric' })
22
+ const dayFormatter = new Intl.DateTimeFormat('en', {
23
+ day: 'numeric',
24
+ month: 'long',
25
+ timeZone: 'UTC',
26
+ weekday: 'long',
27
+ year: 'numeric'
28
+ })
29
+
30
+ const parseIsoDate = (date: string | undefined): Date | undefined => {
31
+ if (!date || !isoDatePattern.test(date)) return undefined
32
+
33
+ const [year, month, day] = date.split('-').map(Number)
34
+ const parsed = new Date(Date.UTC(year, month - 1, day))
35
+
36
+ return parsed.getUTCFullYear() === year &&
37
+ parsed.getUTCMonth() === month - 1 &&
38
+ parsed.getUTCDate() === day
39
+ ? parsed
40
+ : undefined
41
+ }
42
+
43
+ const parseIsoMonth = (date: string | undefined): Date | undefined => {
44
+ if (!date || !isoMonthPattern.test(date)) return undefined
45
+
46
+ const [year, month] = date.split('-').map(Number)
47
+ const parsed = new Date(Date.UTC(year, month - 1, 1))
48
+
49
+ return parsed.getUTCFullYear() === year && parsed.getUTCMonth() === month - 1
50
+ ? parsed
51
+ : undefined
52
+ }
53
+
54
+ const formatIsoDate = (date: Date): string => date.toISOString().slice(0, 10)
55
+ const formatIsoMonth = (date: Date): string => date.toISOString().slice(0, 7)
56
+ const addDays = (date: Date, days: number): Date =>
57
+ new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days))
58
+ const getDaysInMonth = (date: Date): number =>
59
+ new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)).getUTCDate()
60
+ const isBefore = (date: Date, limit: Date | undefined): boolean =>
61
+ Boolean(limit && formatIsoDate(date) < formatIsoDate(limit))
62
+ const isAfter = (date: Date, limit: Date | undefined): boolean =>
63
+ Boolean(limit && formatIsoDate(date) > formatIsoDate(limit))
64
+
65
+ const {
66
+ class: classProp = '',
67
+ className = '',
68
+ disabled = false,
69
+ glass = false,
70
+ id,
71
+ max,
72
+ min,
73
+ month,
74
+ name,
75
+ value,
76
+ ...rest
77
+ } = Astro.props
78
+
79
+ const today = new Date()
80
+ const todayUtc = new Date(Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()))
81
+ const selectedDate = parseIsoDate(value)
82
+ const minDate = parseIsoDate(min)
83
+ const maxDate = parseIsoDate(max)
84
+ const selectedIso = selectedDate ? formatIsoDate(selectedDate) : ''
85
+ const monthDate = parseIsoMonth(month) ??
86
+ (selectedDate ? new Date(Date.UTC(selectedDate.getUTCFullYear(), selectedDate.getUTCMonth(), 1)) : undefined) ??
87
+ new Date(Date.UTC(todayUtc.getUTCFullYear(), todayUtc.getUTCMonth(), 1))
88
+ const calendarId = id ?? `ui-calendar-${Math.random().toString(36).slice(2)}`
89
+ const labelId = `${calendarId}-label`
90
+ const monthIso = formatIsoMonth(monthDate)
91
+ const todayIso = formatIsoDate(todayUtc)
92
+ const firstWeekday = (monthDate.getUTCDay() + 6) % 7
93
+ const firstCell = addDays(monthDate, -firstWeekday)
94
+ const visibleDates = Array.from({ length: 42 }, (_, index) => addDays(firstCell, index))
95
+ const firstSelectableDate = visibleDates.find(date =>
96
+ date.getUTCMonth() === monthDate.getUTCMonth() &&
97
+ !isBefore(date, minDate) &&
98
+ !isAfter(date, maxDate)
99
+ )
100
+ const focusIso = selectedDate && formatIsoMonth(selectedDate) === monthIso
101
+ ? selectedIso
102
+ : todayUtc.getUTCMonth() === monthDate.getUTCMonth() && todayUtc.getUTCFullYear() === monthDate.getUTCFullYear()
103
+ ? todayIso
104
+ : firstSelectableDate
105
+ ? formatIsoDate(firstSelectableDate)
106
+ : formatIsoDate(monthDate)
107
+ const weekdays = Array.from({ length: 7 }, (_, index) =>
108
+ weekdayFormatter.format(new Date(Date.UTC(2026, 0, 5 + index)))
109
+ )
110
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
111
+ 'ui-calendar',
112
+ glass && 'ui-calendar--glass',
113
+ glass === 'subtle' && 'ui-glass-subtle',
114
+ glass === 'strong' && 'ui-glass-strong'
115
+ ], classProp, className)
116
+ ---
117
+
118
+ <div
119
+ aria-disabled={disabled ? 'true' : undefined}
120
+ class:list={classList}
121
+ data-ui-calendar
122
+ data-ui-calendar-initial-month={monthIso}
123
+ data-ui-calendar-max={maxDate ? formatIsoDate(maxDate) : undefined}
124
+ data-ui-calendar-min={minDate ? formatIsoDate(minDate) : undefined}
125
+ data-ui-calendar-month={monthIso}
126
+ data-ui-calendar-value={selectedIso || undefined}
127
+ data-disabled={disabled ? 'true' : undefined}
128
+ data-ui-glass-track={glass ? true : undefined}
129
+ id={calendarId}
130
+ {...passthrough}
131
+ >
132
+ <input
133
+ data-ui-calendar-input
134
+ disabled={disabled || undefined}
135
+ name={name}
136
+ type="hidden"
137
+ value={selectedIso}
138
+ />
139
+
140
+ <div class="ui-calendar__header">
141
+ <button
142
+ aria-label="Previous month"
143
+ class="ui-calendar__nav"
144
+ data-ui-calendar-prev
145
+ disabled={disabled || undefined}
146
+ type="button"
147
+ >
148
+ <span aria-hidden="true">&lsaquo;</span>
149
+ </button>
150
+ <strong class="ui-calendar__label" data-ui-calendar-label id={labelId}>{monthFormatter.format(monthDate)}</strong>
151
+ <button
152
+ aria-label="Next month"
153
+ class="ui-calendar__nav"
154
+ data-ui-calendar-next
155
+ disabled={disabled || undefined}
156
+ type="button"
157
+ >
158
+ <span aria-hidden="true">&rsaquo;</span>
159
+ </button>
160
+ </div>
161
+
162
+ <table aria-labelledby={labelId} class="ui-calendar__grid" data-ui-calendar-grid role="grid">
163
+ <thead>
164
+ <tr role="row">
165
+ {weekdays.map(weekday => <th role="columnheader" scope="col">{weekday}</th>)}
166
+ </tr>
167
+ </thead>
168
+ <tbody>
169
+ {Array.from({ length: 6 }, (_, rowIndex) => (
170
+ <tr role="row">
171
+ {visibleDates.slice(rowIndex * 7, rowIndex * 7 + 7).map(date => {
172
+ const dateIso = formatIsoDate(date)
173
+ const outside = date.getUTCMonth() !== monthDate.getUTCMonth()
174
+ const unavailable = disabled || isBefore(date, minDate) || isAfter(date, maxDate)
175
+
176
+ return (
177
+ <td
178
+ aria-disabled={unavailable ? 'true' : undefined}
179
+ aria-label={dayFormatter.format(date)}
180
+ aria-selected={selectedIso === dateIso ? 'true' : 'false'}
181
+ data-date={dateIso}
182
+ data-outside={outside ? 'true' : undefined}
183
+ data-selected={selectedIso === dateIso ? 'true' : undefined}
184
+ data-today={todayIso === dateIso ? 'true' : undefined}
185
+ data-ui-calendar-day
186
+ role="gridcell"
187
+ tabindex={!unavailable && focusIso === dateIso ? '0' : '-1'}
188
+ >
189
+ {date.getUTCDate()}
190
+ </td>
191
+ )
192
+ })}
193
+ </tr>
194
+ ))}
195
+ </tbody>
196
+ </table>
197
+ </div>
@@ -0,0 +1,27 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'aside'> {
7
+ class?: string
8
+ className?: string
9
+ }
10
+
11
+ const {
12
+ class: classProp = '',
13
+ className = '',
14
+ ...rest
15
+ } = Astro.props
16
+
17
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
18
+ 'ui-callout'
19
+ ], classProp, className)
20
+ ---
21
+
22
+ <aside
23
+ class:list={classList}
24
+ {...passthrough}
25
+ >
26
+ <slot />
27
+ </aside>
@@ -0,0 +1,40 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'div'> {
7
+ as?: 'article' | 'div' | 'section'
8
+ class?: string
9
+ className?: string
10
+ glass?: boolean | 'subtle' | 'strong'
11
+ variant?: 'default' | 'glass' | 'interactive' | 'muted'
12
+ }
13
+
14
+ const {
15
+ as: Tag = 'div',
16
+ class: classProp = '',
17
+ className = '',
18
+ glass = false,
19
+ variant = 'default',
20
+ ...rest
21
+ } = Astro.props
22
+
23
+ const isGlass = glass || variant === 'glass'
24
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
25
+ 'ui-card',
26
+ variant === 'muted' && 'ui-card--muted',
27
+ variant === 'interactive' && 'ui-card--interactive',
28
+ isGlass && 'ui-card--glass',
29
+ glass === 'subtle' && 'ui-glass-subtle',
30
+ glass === 'strong' && 'ui-glass-strong'
31
+ ], classProp, className)
32
+ ---
33
+
34
+ <Tag
35
+ data-variant={variant}
36
+ class:list={classList}
37
+ {...passthrough}
38
+ >
39
+ <slot />
40
+ </Tag>
@@ -0,0 +1,33 @@
1
+ ---
2
+ import { resolveLumenAstroProps } from '@santi020k/lumen-core'
3
+
4
+ import type { HTMLAttributes } from 'astro/types'
5
+
6
+ interface Props extends HTMLAttributes<'section'> {
7
+ class?: string
8
+ className?: string
9
+ glass?: boolean | 'subtle' | 'strong'
10
+ }
11
+
12
+ const {
13
+ class: classProp = '',
14
+ className = '',
15
+ glass = false,
16
+ ...rest
17
+ } = Astro.props
18
+
19
+ const { classList, passthrough } = resolveLumenAstroProps(rest, [
20
+ 'ui-carousel',
21
+ glass && 'ui-carousel--glass',
22
+ glass === 'subtle' && 'ui-glass-subtle',
23
+ glass === 'strong' && 'ui-glass-strong'
24
+ ], classProp, className)
25
+ ---
26
+
27
+ <section
28
+ data-ui-carousel
29
+ class:list={classList}
30
+ {...passthrough}
31
+ >
32
+ <slot />
33
+ </section>