@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.
- package/README.md +100 -2
- package/components/Accordion.astro +4 -4
- package/components/Affix.astro +2 -2
- package/components/Agenda.astro +3 -2
- package/components/Alert.astro +9 -9
- package/components/AlertDialog.astro +7 -13
- package/components/Anchor.astro +29 -3
- package/components/AnimatedLogo.astro +2 -1
- package/components/AnimatedNumber.astro +5 -2
- package/components/AnimatedPortrait.astro +46 -36
- package/components/AspectRatio.astro +10 -8
- package/components/Attachment.astro +24 -24
- package/components/Autocomplete.astro +3 -2
- package/components/Avatar.astro +4 -3
- package/components/BackToTop.astro +2 -2
- package/components/Badge.astro +9 -9
- package/components/BarChart.astro +211 -0
- package/components/Breadcrumb.astro +3 -3
- package/components/Bubble.astro +7 -7
- package/components/Button.astro +18 -16
- package/components/ButtonGroup.astro +3 -3
- package/components/ButtonLink.astro +9 -3
- package/components/Calendar.astro +43 -31
- package/components/Callout.astro +2 -2
- package/components/Card.astro +12 -10
- package/components/CardContent.astro +26 -0
- package/components/CardDescription.astro +26 -0
- package/components/CardFooter.astro +26 -0
- package/components/CardHeader.astro +26 -0
- package/components/CardTitle.astro +26 -0
- package/components/Carousel.astro +6 -6
- package/components/Cascader.astro +10 -4
- package/components/Chart.astro +32 -6
- package/components/Checkbox.astro +3 -2
- package/components/CheckboxGroup.astro +39 -0
- package/components/Code.astro +55 -52
- package/components/CodeTabs.astro +6 -6
- package/components/Collapsible.astro +3 -3
- package/components/ColorPicker.astro +3 -2
- package/components/Combobox.astro +4 -5
- package/components/Command.astro +6 -6
- package/components/Container.astro +29 -0
- package/components/ContextMenu.astro +7 -13
- package/components/CopyButton.astro +55 -0
- package/components/CoverImage.astro +19 -9
- package/components/DataTable.astro +50 -49
- package/components/DatePicker.astro +20 -17
- package/components/DateRangePicker.astro +3 -2
- package/components/Descriptions.astro +3 -3
- package/components/Dialog.astro +8 -14
- package/components/Direction.astro +3 -3
- package/components/Drawer.astro +7 -13
- package/components/DropdownMenu.astro +7 -13
- package/components/Empty.astro +6 -6
- package/components/ErrorSummary.astro +54 -0
- package/components/Eyebrow.astro +2 -2
- package/components/Field.astro +7 -6
- package/components/FieldError.astro +29 -0
- package/components/FileUpload.astro +2 -2
- package/components/FloatingBadge.astro +2 -2
- package/components/Form.astro +33 -0
- package/components/FormattedDate.astro +2 -2
- package/components/GradientDivider.astro +2 -2
- package/components/Grid.astro +46 -0
- package/components/HoverCard.astro +7 -13
- package/components/Icon.astro +8 -6
- package/components/Image.astro +2 -1
- package/components/Input.astro +6 -5
- package/components/InputGroup.astro +3 -3
- package/components/InputOTP.astro +5 -3
- package/components/Item.astro +11 -8
- package/components/Kbd.astro +3 -3
- package/components/Label.astro +3 -2
- package/components/LanguageToggle.astro +2 -2
- package/components/LineChart.astro +244 -0
- package/components/Link.astro +6 -5
- package/components/ListBox.astro +154 -0
- package/components/Marker.astro +6 -6
- package/components/Mentions.astro +30 -10
- package/components/Menubar.astro +7 -13
- package/components/Message.astro +5 -5
- package/components/MessageScroller.astro +6 -6
- package/components/Meter.astro +1 -0
- package/components/NativeSelect.astro +4 -5
- package/components/NavigationMenu.astro +9 -14
- package/components/Note.astro +1 -1
- package/components/NumberField.astro +3 -2
- package/components/Pagination.astro +3 -3
- package/components/Particles.astro +58 -2
- package/components/PasswordField.astro +73 -0
- package/components/PhoneInput.astro +5 -7
- package/components/PieChart.astro +141 -0
- package/components/Pill.astro +15 -9
- package/components/Popconfirm.astro +8 -3
- package/components/Popover.astro +7 -13
- package/components/Progress.astro +12 -4
- package/components/Prose.astro +2 -2
- package/components/QRCode.astro +13 -5
- package/components/RadioGroup.astro +3 -3
- package/components/Rating.astro +3 -1
- package/components/Resizable.astro +8 -7
- package/components/RevealGroup.astro +4 -2
- package/components/RichTextEditor.astro +3 -2
- package/components/Schedule.astro +3 -2
- package/components/ScrollArea.astro +6 -6
- package/components/ScrollProgress.astro +38 -0
- package/components/ScrollReveal.astro +4 -2
- package/components/SearchField.astro +3 -2
- package/components/Segmented.astro +4 -6
- package/components/Select.astro +23 -14
- package/components/Separator.astro +5 -5
- package/components/Sheet.astro +7 -13
- package/components/Sidebar.astro +9 -14
- package/components/Skeleton.astro +4 -3
- package/components/SkipLink.astro +2 -2
- package/components/Slider.astro +3 -2
- package/components/Sonner.astro +3 -3
- package/components/Sparkline.astro +72 -0
- package/components/SpeedDial.astro +3 -3
- package/components/Spinner.astro +4 -3
- package/components/Stack.astro +46 -0
- package/components/Stat.astro +14 -8
- package/components/StatDescription.astro +16 -0
- package/components/StatIcon.astro +15 -0
- package/components/StatLabel.astro +16 -0
- package/components/StatTrend.astro +28 -0
- package/components/StatValue.astro +16 -0
- package/components/Stepper.astro +11 -8
- package/components/Switch.astro +3 -2
- package/components/Table.astro +7 -6
- package/components/Tabs.astro +6 -6
- package/components/TagGroup.astro +3 -2
- package/components/Textarea.astro +3 -2
- package/components/ThemeBuilder.astro +3 -2
- package/components/ThemeToggle.astro +5 -3
- package/components/TimeField.astro +3 -2
- package/components/Timeline.astro +2 -1
- package/components/TimelineItem.astro +2 -1
- package/components/Toast.astro +10 -16
- package/components/Toggle.astro +3 -2
- package/components/ToggleGroup.astro +3 -3
- package/components/Toolbar.astro +2 -2
- package/components/Tooltip.astro +3 -3
- package/components/Tour.astro +3 -3
- package/components/Transfer.astro +16 -5
- package/components/Tree.astro +3 -2
- package/components/TreeGrid.astro +3 -2
- package/components/TreeSelect.astro +10 -4
- package/components/Typography.astro +3 -3
- package/components/VirtualList.astro +3 -2
- package/components/VisuallyHidden.astro +27 -0
- package/components/Watermark.astro +11 -7
- package/forms.ts +46 -0
- package/index.ts +31 -0
- package/package.json +12 -8
- package/runtime/UIPrimitives.astro +3764 -3142
- package/runtime/controllers/motion.ts +13 -16
- package/index.d.ts +0 -126
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createLumenBarGeometry,
|
|
6
|
+
getLumenChartTicks,
|
|
7
|
+
getLumenChartToneClassName,
|
|
8
|
+
hasLumenChartData,
|
|
9
|
+
type LumenBarChartLayout,
|
|
10
|
+
type LumenChartOrientation,
|
|
11
|
+
type LumenChartSeries,
|
|
12
|
+
scaleLumenChartValue
|
|
13
|
+
} from '@santi020k/lumen-core'
|
|
14
|
+
|
|
15
|
+
import Chart from './Chart.astro'
|
|
16
|
+
|
|
17
|
+
interface Props extends HTMLAttributes<'figure'> {
|
|
18
|
+
caption?: string
|
|
19
|
+
categoryWidth?: number
|
|
20
|
+
class?: string | null
|
|
21
|
+
className?: string
|
|
22
|
+
description?: string
|
|
23
|
+
emptyLabel?: string
|
|
24
|
+
formatCategory?: (category: number | string) => string
|
|
25
|
+
formatValue?: (value: number) => string
|
|
26
|
+
glass?: boolean | 'subtle' | 'strong'
|
|
27
|
+
heading?: string
|
|
28
|
+
layout?: LumenBarChartLayout
|
|
29
|
+
orientation?: LumenChartOrientation
|
|
30
|
+
presentation?: 'bare' | 'default'
|
|
31
|
+
series: readonly LumenChartSeries[]
|
|
32
|
+
showLegend?: boolean
|
|
33
|
+
showTable?: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const {
|
|
37
|
+
caption,
|
|
38
|
+
categoryWidth,
|
|
39
|
+
class: classProp = '',
|
|
40
|
+
className = '',
|
|
41
|
+
description,
|
|
42
|
+
emptyLabel = 'No chart data available.',
|
|
43
|
+
formatCategory = String,
|
|
44
|
+
formatValue = String,
|
|
45
|
+
glass = false,
|
|
46
|
+
heading,
|
|
47
|
+
layout = 'grouped',
|
|
48
|
+
orientation = 'vertical',
|
|
49
|
+
series,
|
|
50
|
+
showLegend = series.length > 1,
|
|
51
|
+
showTable = true,
|
|
52
|
+
...rest
|
|
53
|
+
} = Astro.props
|
|
54
|
+
|
|
55
|
+
const geometry = createLumenBarGeometry(series, { categoryWidth, layout, orientation })
|
|
56
|
+
const hasData = hasLumenChartData(series)
|
|
57
|
+
const ticks = getLumenChartTicks(geometry.domain)
|
|
58
|
+
const categories = geometry.categories.map(category => category.category)
|
|
59
|
+
|
|
60
|
+
const datumFor = (item: LumenChartSeries, category: number | string) => (
|
|
61
|
+
item.data.find(datum => datum.x === category)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
const valueFor = (item: LumenChartSeries, category: number | string) => (
|
|
65
|
+
datumFor(item, category)?.y ?? null
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
const labelFor = (item: LumenChartSeries, category: number | string) => (
|
|
69
|
+
datumFor(item, category)?.label
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
const formattedValueFor = (item: LumenChartSeries, category: number | string) => {
|
|
73
|
+
const value = valueFor(item, category)
|
|
74
|
+
|
|
75
|
+
return value === null ? 'Not available' : formatValue(value)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const categoryLabelFor = (category: number | string) => {
|
|
79
|
+
const label = series.flatMap(item => item.data).find(datum => datum.x === category)?.xLabel
|
|
80
|
+
|
|
81
|
+
return label ?? formatCategory(category)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const margin = orientation === 'horizontal' ?
|
|
85
|
+
{ bottom: 24, left: Math.max(64, Math.min(240, categoryWidth ?? 112)), right: 20, top: 16 } :
|
|
86
|
+
{ bottom: 52, left: 52, right: 16, top: 16 }
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
<Chart
|
|
90
|
+
class:list={['ui-bar-chart', classProp, className]}
|
|
91
|
+
{caption}
|
|
92
|
+
{description}
|
|
93
|
+
{glass}
|
|
94
|
+
{heading}
|
|
95
|
+
{...rest}
|
|
96
|
+
>
|
|
97
|
+
{
|
|
98
|
+
showLegend && hasData && (
|
|
99
|
+
<ul class="ui-chart__legend" aria-label="Chart legend">
|
|
100
|
+
{series.map((item, index) => (
|
|
101
|
+
<li class={getLumenChartToneClassName(item.tone, index)}>
|
|
102
|
+
<span aria-hidden="true" />
|
|
103
|
+
{item.label}
|
|
104
|
+
</li>
|
|
105
|
+
))}
|
|
106
|
+
</ul>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
{!hasData && <p class="ui-chart__empty" role="status">{emptyLabel}</p>}
|
|
110
|
+
<div class="ui-chart__plot" hidden={!hasData}>
|
|
111
|
+
<svg
|
|
112
|
+
aria-hidden="true"
|
|
113
|
+
preserveAspectRatio="xMidYMid meet"
|
|
114
|
+
viewBox={`0 0 ${geometry.width} ${geometry.height}`}
|
|
115
|
+
>
|
|
116
|
+
<g class="ui-chart__grid">
|
|
117
|
+
{
|
|
118
|
+
ticks.map(tick => {
|
|
119
|
+
const coordinate =
|
|
120
|
+
orientation === 'horizontal' ?
|
|
121
|
+
scaleLumenChartValue(
|
|
122
|
+
tick, geometry.domain, margin.left, geometry.width - margin.right
|
|
123
|
+
) :
|
|
124
|
+
scaleLumenChartValue(
|
|
125
|
+
tick, geometry.domain, geometry.height - margin.bottom, margin.top
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return orientation === 'horizontal' ?
|
|
129
|
+
(
|
|
130
|
+
<line
|
|
131
|
+
x1={coordinate}
|
|
132
|
+
x2={coordinate}
|
|
133
|
+
y1={margin.top}
|
|
134
|
+
y2={geometry.height - margin.bottom}
|
|
135
|
+
/>
|
|
136
|
+
) :
|
|
137
|
+
(
|
|
138
|
+
<line
|
|
139
|
+
x1={margin.left}
|
|
140
|
+
x2={geometry.width - margin.right}
|
|
141
|
+
y1={coordinate}
|
|
142
|
+
y2={coordinate}
|
|
143
|
+
/>
|
|
144
|
+
)
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
</g>
|
|
148
|
+
<g class="ui-chart__axis-labels">
|
|
149
|
+
{
|
|
150
|
+
geometry.categories.map(category => (
|
|
151
|
+
<text
|
|
152
|
+
dominant-baseline={orientation === 'horizontal' ? 'middle' : undefined}
|
|
153
|
+
text-anchor={orientation === 'horizontal' ? 'end' : 'middle'}
|
|
154
|
+
x={category.x}
|
|
155
|
+
y={category.y}
|
|
156
|
+
>
|
|
157
|
+
{String(category.label)}
|
|
158
|
+
</text>
|
|
159
|
+
))
|
|
160
|
+
}
|
|
161
|
+
</g>
|
|
162
|
+
<g class="ui-bar-chart__marks">
|
|
163
|
+
{
|
|
164
|
+
geometry.marks.map(mark => (
|
|
165
|
+
<rect
|
|
166
|
+
class={getLumenChartToneClassName(mark.tone)}
|
|
167
|
+
height={mark.height}
|
|
168
|
+
rx="4"
|
|
169
|
+
width={mark.width}
|
|
170
|
+
x={mark.x}
|
|
171
|
+
y={mark.y}
|
|
172
|
+
>
|
|
173
|
+
<title>
|
|
174
|
+
{`${categoryLabelFor(mark.category)} · ${mark.seriesLabel}: ${formatValue(mark.value)}`}
|
|
175
|
+
</title>
|
|
176
|
+
</rect>
|
|
177
|
+
))
|
|
178
|
+
}
|
|
179
|
+
</g>
|
|
180
|
+
</svg>
|
|
181
|
+
</div>
|
|
182
|
+
{
|
|
183
|
+
showTable && hasData && (
|
|
184
|
+
<details class="ui-chart__data">
|
|
185
|
+
<summary>View chart data</summary>
|
|
186
|
+
<div>
|
|
187
|
+
<table>
|
|
188
|
+
<thead>
|
|
189
|
+
<tr>
|
|
190
|
+
<th scope="col">Category</th>
|
|
191
|
+
{series.map(item => <th scope="col">{item.label}</th>)}
|
|
192
|
+
</tr>
|
|
193
|
+
</thead>
|
|
194
|
+
<tbody>
|
|
195
|
+
{categories.map(category => (
|
|
196
|
+
<tr>
|
|
197
|
+
<th scope="row">{categoryLabelFor(category)}</th>
|
|
198
|
+
{series.map(item => (
|
|
199
|
+
<td>
|
|
200
|
+
{labelFor(item, category) ?? formattedValueFor(item, category)}
|
|
201
|
+
</td>
|
|
202
|
+
))}
|
|
203
|
+
</tr>
|
|
204
|
+
))}
|
|
205
|
+
</tbody>
|
|
206
|
+
</table>
|
|
207
|
+
</div>
|
|
208
|
+
</details>
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
</Chart>
|
|
@@ -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<'nav'> {
|
|
7
7
|
class?: string | null
|
|
8
8
|
className?: string
|
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
} = Astro.props
|
|
16
16
|
|
|
17
17
|
const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
18
|
-
|
|
18
|
+
'ui-breadcrumb'
|
|
19
19
|
], classProp, className)
|
|
20
20
|
---
|
|
21
21
|
|
package/components/Bubble.astro
CHANGED
|
@@ -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,11 +19,11 @@ const {
|
|
|
19
19
|
} = Astro.props
|
|
20
20
|
|
|
21
21
|
const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
27
|
], classProp, className)
|
|
28
28
|
---
|
|
29
29
|
|
package/components/Button.astro
CHANGED
|
@@ -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
|
|
@@ -23,26 +23,28 @@ const {
|
|
|
23
23
|
} = Astro.props
|
|
24
24
|
|
|
25
25
|
const isDisabled = Boolean(disabled) || loading
|
|
26
|
+
|
|
26
27
|
const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
'ui-button',
|
|
29
|
+
variant === 'default' && 'ui-button--default',
|
|
30
|
+
variant === 'destructive' && 'ui-button--destructive',
|
|
31
|
+
variant === 'ghost' && 'ui-button--ghost',
|
|
32
|
+
variant === 'link' && 'ui-button--link',
|
|
33
|
+
variant === 'outline' && 'ui-button--outline',
|
|
34
|
+
variant === 'secondary' && 'ui-button--secondary',
|
|
35
|
+
size === 'default' && 'ui-button--default-size',
|
|
36
|
+
size === 'sm' && 'ui-button--sm',
|
|
37
|
+
size === 'lg' && 'ui-button--lg',
|
|
38
|
+
size === 'icon' && 'ui-button--icon',
|
|
39
|
+
isDisabled && 'ui-button--disabled',
|
|
40
|
+
loading && 'ui-button--loading'
|
|
40
41
|
], classProp, className)
|
|
41
42
|
---
|
|
42
43
|
|
|
43
44
|
<button
|
|
44
|
-
class:list={classList}
|
|
45
45
|
aria-busy={loading || undefined}
|
|
46
|
+
class:list={classList}
|
|
47
|
+
data-slot="button"
|
|
46
48
|
disabled={isDisabled || undefined}
|
|
47
49
|
type={type}
|
|
48
50
|
{...passthrough}
|
|
@@ -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
|
|
@@ -15,7 +15,7 @@ const {
|
|
|
15
15
|
} = Astro.props
|
|
16
16
|
|
|
17
17
|
const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
18
|
-
|
|
18
|
+
'ui-button-group'
|
|
19
19
|
], classProp, className)
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
2
4
|
import { resolveLumenAstroProps } from '@santi020k/lumen-core'
|
|
3
|
-
import Icon from './Icon.astro'
|
|
4
5
|
|
|
5
|
-
import
|
|
6
|
+
import Icon from './Icon.astro'
|
|
6
7
|
|
|
7
8
|
interface Props extends HTMLAttributes<'a'> {
|
|
8
9
|
ariaLabel?: string
|
|
@@ -43,6 +44,7 @@ const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
|
43
44
|
<a
|
|
44
45
|
aria-label={ariaLabel}
|
|
45
46
|
class:list={classList}
|
|
47
|
+
data-slot="button-link"
|
|
46
48
|
href={href}
|
|
47
49
|
rel={newTab ? 'noreferrer noopener' : undefined}
|
|
48
50
|
target={newTab ? '_blank' : undefined}
|
|
@@ -52,7 +54,11 @@ const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
|
52
54
|
{showArrow && (
|
|
53
55
|
<Icon
|
|
54
56
|
aria-hidden="true"
|
|
55
|
-
class="
|
|
57
|
+
class="
|
|
58
|
+
size-4 shrink-0 transition-transform duration-200
|
|
59
|
+
motion-safe:group-hover:translate-x-0.5
|
|
60
|
+
motion-reduce:transition-none
|
|
61
|
+
"
|
|
56
62
|
name={newTab ? 'arrow-up-right' : 'arrow-right'}
|
|
57
63
|
/>
|
|
58
64
|
)}
|
|
@@ -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<'div'>, 'value'> {
|
|
7
7
|
class?: string | null
|
|
8
8
|
className?: string
|
|
@@ -19,6 +19,7 @@ const isoDatePattern = /^\d{4}-\d{2}-\d{2}$/
|
|
|
19
19
|
const isoMonthPattern = /^\d{4}-\d{2}$/
|
|
20
20
|
const weekdayFormatter = new Intl.DateTimeFormat('en', { timeZone: 'UTC', weekday: 'short' })
|
|
21
21
|
const monthFormatter = new Intl.DateTimeFormat('en', { month: 'long', timeZone: 'UTC', year: 'numeric' })
|
|
22
|
+
|
|
22
23
|
const dayFormatter = new Intl.DateTimeFormat('en', {
|
|
23
24
|
day: 'numeric',
|
|
24
25
|
month: 'long',
|
|
@@ -35,9 +36,9 @@ const parseIsoDate = (date: string | undefined): Date | undefined => {
|
|
|
35
36
|
|
|
36
37
|
return parsed.getUTCFullYear() === year &&
|
|
37
38
|
parsed.getUTCMonth() === month - 1 &&
|
|
38
|
-
parsed.getUTCDate() === day
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
parsed.getUTCDate() === day ?
|
|
40
|
+
parsed :
|
|
41
|
+
undefined
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
const parseIsoMonth = (date: string | undefined): Date | undefined => {
|
|
@@ -46,21 +47,27 @@ const parseIsoMonth = (date: string | undefined): Date | undefined => {
|
|
|
46
47
|
const [year, month] = date.split('-').map(Number)
|
|
47
48
|
const parsed = new Date(Date.UTC(year, month - 1, 1))
|
|
48
49
|
|
|
49
|
-
return parsed.getUTCFullYear() === year && parsed.getUTCMonth() === month - 1
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
return parsed.getUTCFullYear() === year && parsed.getUTCMonth() === month - 1 ?
|
|
51
|
+
parsed :
|
|
52
|
+
undefined
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
const formatIsoDate = (date: Date): string => date.toISOString().slice(0, 10)
|
|
55
56
|
const formatIsoMonth = (date: Date): string => date.toISOString().slice(0, 7)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
|
|
58
|
+
const addDays = (date: Date, days: number): Date => {
|
|
59
|
+
const utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate() + days)
|
|
60
|
+
|
|
61
|
+
return new Date(utc)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const isBefore = (date: Date, limit: Date | undefined): boolean => (
|
|
61
65
|
Boolean(limit && formatIsoDate(date) < formatIsoDate(limit))
|
|
62
|
-
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
const isAfter = (date: Date, limit: Date | undefined): boolean => (
|
|
63
69
|
Boolean(limit && formatIsoDate(date) > formatIsoDate(limit))
|
|
70
|
+
)
|
|
64
71
|
|
|
65
72
|
const {
|
|
66
73
|
class: classProp = '',
|
|
@@ -82,9 +89,11 @@ const selectedDate = parseIsoDate(value)
|
|
|
82
89
|
const minDate = parseIsoDate(min)
|
|
83
90
|
const maxDate = parseIsoDate(max)
|
|
84
91
|
const selectedIso = selectedDate ? formatIsoDate(selectedDate) : ''
|
|
92
|
+
|
|
85
93
|
const monthDate = parseIsoMonth(month) ??
|
|
86
94
|
(selectedDate ? new Date(Date.UTC(selectedDate.getUTCFullYear(), selectedDate.getUTCMonth(), 1)) : undefined) ??
|
|
87
95
|
new Date(Date.UTC(todayUtc.getUTCFullYear(), todayUtc.getUTCMonth(), 1))
|
|
96
|
+
|
|
88
97
|
const calendarId = id ?? `ui-calendar-${Math.random().toString(36).slice(2)}`
|
|
89
98
|
const labelId = `${calendarId}-label`
|
|
90
99
|
const monthIso = formatIsoMonth(monthDate)
|
|
@@ -92,26 +101,29 @@ const todayIso = formatIsoDate(todayUtc)
|
|
|
92
101
|
const firstWeekday = (monthDate.getUTCDay() + 6) % 7
|
|
93
102
|
const firstCell = addDays(monthDate, -firstWeekday)
|
|
94
103
|
const visibleDates = Array.from({ length: 42 }, (_, index) => addDays(firstCell, index))
|
|
95
|
-
|
|
96
|
-
|
|
104
|
+
|
|
105
|
+
const firstSelectableDate = visibleDates.find(date => date.getUTCMonth() === monthDate.getUTCMonth() &&
|
|
97
106
|
!isBefore(date, minDate) &&
|
|
98
|
-
!isAfter(date, maxDate)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
!isAfter(date, maxDate))
|
|
108
|
+
|
|
109
|
+
let focusIso = formatIsoDate(monthDate)
|
|
110
|
+
|
|
111
|
+
if (selectedDate && formatIsoMonth(selectedDate) === monthIso) focusIso = selectedIso
|
|
112
|
+
else if (
|
|
113
|
+
todayUtc.getUTCMonth() === monthDate.getUTCMonth() &&
|
|
114
|
+
todayUtc.getUTCFullYear() === monthDate.getUTCFullYear()
|
|
115
|
+
) focusIso = todayIso
|
|
116
|
+
else if (firstSelectableDate) focusIso = formatIsoDate(firstSelectableDate)
|
|
117
|
+
|
|
118
|
+
const weekdays = Array.from(
|
|
119
|
+
{ length: 7 }, (_, index) => weekdayFormatter.format(new Date(Date.UTC(2026, 0, 5 + index)))
|
|
109
120
|
)
|
|
121
|
+
|
|
110
122
|
const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
123
|
+
'ui-calendar',
|
|
124
|
+
glass && 'ui-calendar--glass',
|
|
125
|
+
glass === 'subtle' && 'ui-glass-subtle',
|
|
126
|
+
glass === 'strong' && 'ui-glass-strong'
|
|
115
127
|
], classProp, className)
|
|
116
128
|
---
|
|
117
129
|
|
package/components/Callout.astro
CHANGED
|
@@ -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
|
package/components/Card.astro
CHANGED
|
@@ -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
|
as?: 'article' | 'div' | 'section'
|
|
8
8
|
class?: string | null
|
|
@@ -21,20 +21,22 @@ const {
|
|
|
21
21
|
} = Astro.props
|
|
22
22
|
|
|
23
23
|
const isGlass = glass || variant === 'glass'
|
|
24
|
+
|
|
24
25
|
const { classList, passthrough } = resolveLumenAstroProps(rest, [
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
26
|
+
'ui-card',
|
|
27
|
+
variant === 'unstyled' && 'ui-card--unstyled',
|
|
28
|
+
variant === 'muted' && 'ui-card--muted',
|
|
29
|
+
variant === 'interactive' && 'ui-card--interactive',
|
|
30
|
+
isGlass && 'ui-card--glass',
|
|
31
|
+
glass === 'subtle' && 'ui-glass-subtle',
|
|
32
|
+
glass === 'strong' && 'ui-glass-strong'
|
|
32
33
|
], classProp, className)
|
|
33
34
|
---
|
|
34
35
|
|
|
35
36
|
<Tag
|
|
36
|
-
data-variant={variant}
|
|
37
37
|
class:list={classList}
|
|
38
|
+
data-slot="card"
|
|
39
|
+
data-variant={variant}
|
|
38
40
|
{...passthrough}
|
|
39
41
|
>
|
|
40
42
|
<slot />
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
4
|
+
import { resolveLumenAstroProps } from '@santi020k/lumen-core'
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<'div'> {
|
|
7
|
+
as?: 'div' | 'section'
|
|
8
|
+
class?: string | null
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
as: Tag = 'div',
|
|
14
|
+
class: classProp = '',
|
|
15
|
+
className = '',
|
|
16
|
+
...rest
|
|
17
|
+
} = Astro.props
|
|
18
|
+
|
|
19
|
+
const { classList, passthrough } = resolveLumenAstroProps(
|
|
20
|
+
rest, ['ui-card__content'], classProp, className
|
|
21
|
+
)
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<Tag class:list={classList} data-slot="card-content" {...passthrough}>
|
|
25
|
+
<slot />
|
|
26
|
+
</Tag>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
4
|
+
import { resolveLumenAstroProps } from '@santi020k/lumen-core'
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<'div'> {
|
|
7
|
+
as?: 'div' | 'p'
|
|
8
|
+
class?: string | null
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
as: Tag = 'div',
|
|
14
|
+
class: classProp = '',
|
|
15
|
+
className = '',
|
|
16
|
+
...rest
|
|
17
|
+
} = Astro.props
|
|
18
|
+
|
|
19
|
+
const { classList, passthrough } = resolveLumenAstroProps(
|
|
20
|
+
rest, ['ui-card__description'], classProp, className
|
|
21
|
+
)
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<Tag class:list={classList} data-slot="card-description" {...passthrough}>
|
|
25
|
+
<slot />
|
|
26
|
+
</Tag>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
4
|
+
import { resolveLumenAstroProps } from '@santi020k/lumen-core'
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<'div'> {
|
|
7
|
+
as?: 'div' | 'footer'
|
|
8
|
+
class?: string | null
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
as: Tag = 'div',
|
|
14
|
+
class: classProp = '',
|
|
15
|
+
className = '',
|
|
16
|
+
...rest
|
|
17
|
+
} = Astro.props
|
|
18
|
+
|
|
19
|
+
const { classList, passthrough } = resolveLumenAstroProps(
|
|
20
|
+
rest, ['ui-card__footer'], classProp, className
|
|
21
|
+
)
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<Tag class:list={classList} data-slot="card-footer" {...passthrough}>
|
|
25
|
+
<slot />
|
|
26
|
+
</Tag>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
4
|
+
import { resolveLumenAstroProps } from '@santi020k/lumen-core'
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<'div'> {
|
|
7
|
+
as?: 'div' | 'header'
|
|
8
|
+
class?: string | null
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
as: Tag = 'div',
|
|
14
|
+
class: classProp = '',
|
|
15
|
+
className = '',
|
|
16
|
+
...rest
|
|
17
|
+
} = Astro.props
|
|
18
|
+
|
|
19
|
+
const { classList, passthrough } = resolveLumenAstroProps(
|
|
20
|
+
rest, ['ui-card__header'], classProp, className
|
|
21
|
+
)
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<Tag class:list={classList} data-slot="card-header" {...passthrough}>
|
|
25
|
+
<slot />
|
|
26
|
+
</Tag>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types'
|
|
3
|
+
|
|
4
|
+
import { resolveLumenAstroProps } from '@santi020k/lumen-core'
|
|
5
|
+
|
|
6
|
+
interface Props extends HTMLAttributes<'div'> {
|
|
7
|
+
as?: 'div' | 'h2' | 'h3' | 'h4'
|
|
8
|
+
class?: string | null
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const {
|
|
13
|
+
as: Tag = 'div',
|
|
14
|
+
class: classProp = '',
|
|
15
|
+
className = '',
|
|
16
|
+
...rest
|
|
17
|
+
} = Astro.props
|
|
18
|
+
|
|
19
|
+
const { classList, passthrough } = resolveLumenAstroProps(
|
|
20
|
+
rest, ['ui-card__title'], classProp, className
|
|
21
|
+
)
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<Tag class:list={classList} data-slot="card-title" {...passthrough}>
|
|
25
|
+
<slot />
|
|
26
|
+
</Tag>
|