@santi020k/lumen-mcp 0.2.0 → 0.4.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/bin/lumen-mcp-local.mjs +3 -2
- package/data/lumen-data.json +2542 -423
- package/dist/data.d.ts +1 -0
- package/dist/data.d.ts.map +1 -1
- package/dist/data.js +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -35
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +1 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +74 -54
- package/package.json +1 -1
package/data/lumen-data.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"Avatar": "8919014913a38d94a33da2898d775feb109770345ed33fe4184fea34ad7162e3",
|
|
12
12
|
"BackToTop": "1c53e690626c2e9eaed71fafde5ec065b39a943b63048ad9ccf24f0c16edaa68",
|
|
13
13
|
"Badge": "7e2d3cafb52609251056230c8389c731acfdf55895b8cf5e7712b138ad05e09b",
|
|
14
|
+
"BarChart": "c58fadb0fe2335edbf022a6c0fa11cb77c474830ccc2fb97a775595054653f7b",
|
|
14
15
|
"Breadcrumb": "07e39012551d5916abd2ae7f8266386907b889ddba41da2eee34af7f6fea6673",
|
|
15
16
|
"Bubble": "40e168ca39bac88b431e6104659c315a85bedd6198dd59f3f26582021df538b4",
|
|
16
17
|
"Button": "ec006af669eecd5011afabeaaf244eab3f090e9858e368d13109232a2ae26d06",
|
|
@@ -19,10 +20,11 @@
|
|
|
19
20
|
"Callout": "c13fbded24bcea45c0a9f9ddccef8cec4f4ed39e07809d5ff2a850485397eb51",
|
|
20
21
|
"Card": "e50266a9cf255a7a1706373b5859272dd17ba0e57fd7aff37f2a7ac35797c669",
|
|
21
22
|
"Carousel": "811a7ca777563b88766a6ae97a796ba789c7fb22ab06f253773e280ba5804a38",
|
|
22
|
-
"Chart": "
|
|
23
|
+
"Chart": "473c4e02c80803565f0409e4e4024c2e06c09f476a8bd13a118e75f2b2ddce1b",
|
|
23
24
|
"Checkbox": "d971d97482ba924a07d4891cc782dd14c87b9f8bdb7b4070181b2189748b8be1",
|
|
24
25
|
"Collapsible": "7652876be7a40fc2451168ea8220c49a5ef0fcfddc04d6d5ff424e6d2d26a04a",
|
|
25
26
|
"Code": "e2f5eea415e1d2212dcb782487b417806f7ba6a7b1469f1b74a082fe35523275",
|
|
27
|
+
"CodeTabs": "2fc520388101b91ed507df0bc2d26cd97cb45cdf7510017d81c6fb4c85e7d51a",
|
|
26
28
|
"Combobox": "93821fbc97e296cf426a53f52eda225b0361fba9c22a2f612436008be8efe4e2",
|
|
27
29
|
"Command": "41c6175a15f7267bbf42fd00b74127571875e80a79d3f6700fad0abc3ccde09a",
|
|
28
30
|
"ContextMenu": "93130a486b3e5c33c3ba05c510069bb51ab7be4a37ab0f1d45c50064527e8512",
|
|
@@ -30,7 +32,7 @@
|
|
|
30
32
|
"DataTable": "98b6681fe1324a2367d47cac7a406b9ad85fc2c04746ff1c5b0fe7bc7c9fea68",
|
|
31
33
|
"DatePicker": "6a70845a80a56e740a6a9dd8958d20255812e4dde78ace4beb86338a08f9bcae",
|
|
32
34
|
"DateRangePicker": "e4d2f62fac35eda4d7662a745b0121bfa1aa995658cd51f8203836298a4028a8",
|
|
33
|
-
"Dialog": "
|
|
35
|
+
"Dialog": "35302b79415111b97316bf2590e1b50d25f4ab606705e4a51feb768b5c79e8c5",
|
|
34
36
|
"Direction": "ceba5f37b9f7a2e8f0b0d70175b1dc161bfe0674db962adc837838f2f20de51c",
|
|
35
37
|
"Drawer": "8ef5a38b8fbcce6a27b10523b57cfd30728ec2f902515ada9566a2f21b2ec302",
|
|
36
38
|
"DropdownMenu": "104ffe49547e89a91d312d9bdfcbab4ec76188decbad8140ef920bfe91804d7c",
|
|
@@ -40,7 +42,7 @@
|
|
|
40
42
|
"FloatingBadge": "db0fb0b64ba740b195c7ddebd6f0573ce3da25dbca7e80eb82fe0fb425e15d04",
|
|
41
43
|
"FormattedDate": "c4f24887c4746220a641e34590e22434d08f02345abde6316246d76e77bacfb6",
|
|
42
44
|
"HoverCard": "7600efb83ed7b3d71b8a12d073a408d8663fb0b644b64e35d2c9b113a4130473",
|
|
43
|
-
"Icon": "
|
|
45
|
+
"Icon": "a8957b7c35f2bce93c240e7a420e96fecdd47f548583f9a87808fb2a8a152e09",
|
|
44
46
|
"Image": "ae96c90e196f84f026fc0298a29b167a31b04599a5d229bccd01e6118f811649",
|
|
45
47
|
"Input": "a928bc600c02646eae2162bb4ebe292d54a30a13107dda6c5b1152fa47619340",
|
|
46
48
|
"InputGroup": "ce2011ca129f23c62f0dd34e75d2b8f15437fbc72bd95d77ad1e4d7de1124754",
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"Kbd": "28e109087067cc5c71a4fd84c9add36be7de7a39ce376d3ef59fc8d9465ecee1",
|
|
50
52
|
"Label": "e76c47b92db619d66ce76c15f10e440c599c2759cb96c328d2bbd0d75659ef92",
|
|
51
53
|
"Link": "c3e950ce51c641e6593868d99aea43936cd35b8559127dd3b881b04f4aa565a0",
|
|
54
|
+
"LineChart": "b4f03a5cd9bd8bfff94d4182163630af5939ba6b67508b778d9422a51620617b",
|
|
52
55
|
"Marker": "4875fd7e8792aac78bb6b3733a48d0a2f1c298d812db89c0680d736bf4c07a15",
|
|
53
56
|
"Menubar": "5450c01fa81f0b9dce4d1f39ce7507f6d744b2147cfa68d859e8e02714e2f16c",
|
|
54
57
|
"Message": "f7f25f4c9e727d83af8b4c42751d024f7de418d45771ba3a975ac229d332cb7c",
|
|
@@ -58,14 +61,16 @@
|
|
|
58
61
|
"NumberField": "97db5294f8232c25958c15bf93e2c78caf55651a5cc9439e3de6eb58e727e9bf",
|
|
59
62
|
"Pagination": "79afd85add73b34c6c6f954b7755ee8e795b8836bee6193efc22910bdeb9f333",
|
|
60
63
|
"PhoneInput": "585a257a1cc654fa653c7bd81a400ce8991f71a9d67596c3b2511ea9b8d83614",
|
|
61
|
-
"
|
|
64
|
+
"PieChart": "19eae80895734a9f5be30f8ff66ba87b7d1e7b438df3195efcd738e7f82a932c",
|
|
65
|
+
"Pill": "bbab3e93037d35258eff820a57892bf6002dd2cbcebb8241866da89e30d8b52c",
|
|
62
66
|
"Popover": "a596714668a14c81c2e6edf7666ca2cc17939c057470cc90c10a18a13924c401",
|
|
63
|
-
"Progress": "
|
|
67
|
+
"Progress": "405786d7a0e5681adfa520df338957d6d486db14006e5aab652b1822a78bc26d",
|
|
64
68
|
"Prose": "14454809f9ae5e0b509418fa1d74d00af480b5ce2d289e7c608c1ad78ef93eff",
|
|
65
69
|
"RadioGroup": "5f9bd9181f6fd47d3c168846cc21eed2308064535bc527e8fc1a60460b3138fb",
|
|
66
70
|
"Resizable": "36d3a5b19ec3eb74e8ebfdd92a7e0105a1deb115142c76df1784ce5a8f4bdb61",
|
|
67
71
|
"RichTextEditor": "dbc639a21744cf725ae78c3dfe90c310285c34034f1a59ce42969f46d651539f",
|
|
68
72
|
"ScrollArea": "a0b2ea629429009e7b51bf33ab256150f320c5704370347ce16a70a84d627c55",
|
|
73
|
+
"ScrollProgress": "071a889086890c45934369fbb85c65a49cefc238c522aadd4723cb48505ad01e",
|
|
69
74
|
"Schedule": "d1cb86cb6132a0352c75eaf3413d204dba48832ab385ce205c1e61d59633139c",
|
|
70
75
|
"SearchField": "561a310b3c8b112ed1baa7a01783be4471d73b47f3f2800460b4ccc23ca7bf42",
|
|
71
76
|
"Select": "2986d0d3dd9def947c418df15758bff6881d2a81fe1e1e68b6ef15d9b0dd19bc",
|
|
@@ -76,6 +81,7 @@
|
|
|
76
81
|
"SkipLink": "d660feaa0edbfdbb72d6da0c2bb62e725448ee4ff75ac1b34588cf4ceb3dbcd8",
|
|
77
82
|
"Slider": "cca90425ee92d9710e7b31d815d58027f2c3bcbd372282d20b6ef2fbd0aadb27",
|
|
78
83
|
"Sonner": "a7767b9f7a4d5d8b7263c19a9833336ef965c8a697ae6607ccd5fee9a69c0529",
|
|
84
|
+
"Sparkline": "d3d21505eae092a9161a82c30599d30f86246c1c45e2c0755bf1ae323a02e5fe",
|
|
79
85
|
"Spinner": "f5817573620b0fd870b2f0cca52c2baa1f00eb2f6d6a8087fe2f2db3e0051ff2",
|
|
80
86
|
"Switch": "046af1a323a3f49f7e83cae17c9eceac80afb8fa5afe91478bd10a1f65e33e5a",
|
|
81
87
|
"Table": "8481dc8028e49bae10d46ce66c29fb0fe06154ebbb7d66724749ff8d6f881d98",
|
|
@@ -94,12 +100,12 @@
|
|
|
94
100
|
"Typography": "0bc81b7dd562a010f8a4892370fd7a4382e929cc3c9e504126d65c4d3da2c040",
|
|
95
101
|
"VirtualList": "9f9277e3cc92a61cf35d2959a5ee08f01f627aee71fd9c3f1ffafb206b1f07e9",
|
|
96
102
|
"LanguageToggle": "8f3cd99de808d9983e1ad304a7867d55505d51c7867e04ce7ba155aea59afb23",
|
|
97
|
-
"Particles": "
|
|
103
|
+
"Particles": "06b1b05dea30b0d0992835599ac18101b6d08c28bbe9e39139562d30db1c973f",
|
|
98
104
|
"AnimatedNumber": "afbf3dfadcd3338199dbdc2d2e6c80182b90a3b6741ae4009f2ab68cf326235a",
|
|
99
105
|
"RevealGroup": "57ef595e6aff5c7a2843054d18639466022b2bebad2da2ce6b14a4970757c484",
|
|
100
106
|
"ScrollReveal": "940d69fc6bf5427c8bece747727872a8707c5b0c7fbefe60dad65d3b066ab35d",
|
|
101
|
-
"Stat": "
|
|
102
|
-
"Meter": "
|
|
107
|
+
"Stat": "b46bde93ea058c24fb0a685b48ba3c85915e3506c6dfb0ba21e373619230b0b1",
|
|
108
|
+
"Meter": "19a209d62f2f68750bb4092130fbc9e8d1c33a11132eb5871110eba45f93af9f",
|
|
103
109
|
"Note": "17c44fe3a3b08193ebba56b20d3d04f90f906b477e24a21c059b8531eac1aa16",
|
|
104
110
|
"Rating": "ec00e1b7f39a38884922bd48490b1dd5625b2eb41ed5265cf83600f7705180b5",
|
|
105
111
|
"Timeline": "93ffea4de7b9007c8a2badc99cf965fe7d974ae4ba5ad01c275183af5c3d6d79",
|
|
@@ -111,7 +117,7 @@
|
|
|
111
117
|
"Stepper": "3974df2b0c0be37a1e0c1f69dd7ce77bd6655d0f7b03a86a8dbf61191193598d",
|
|
112
118
|
"FileUpload": "91fa5aea1c3318c9b255ce2c700c014bc3ca98a54a2dfd599f7e3bfd5a0e5558",
|
|
113
119
|
"Tour": "4a294319873159d566d1dfc1878937fd2338629f2c57702daa822c275de80110",
|
|
114
|
-
"Anchor": "
|
|
120
|
+
"Anchor": "eb86f012637c44fba25025ceb667aec83899decd5e4833ff92e33e75090642b5",
|
|
115
121
|
"Segmented": "fea2f68a5935678aa892e39ae4808dd2fc36be992215a1665e321594d4cd8755",
|
|
116
122
|
"Toolbar": "eb3d645b5f843ad028122d6d5244b3c1eab8b4b6a25f2cec1ae4f56e72f009b8",
|
|
117
123
|
"Descriptions": "5e1a8991654626fbe3fe541f299be774dfc2801313a49cbd4b11cf4eb31de983",
|
|
@@ -121,7 +127,7 @@
|
|
|
121
127
|
"TreeSelect": "8d4b1475eab41f4e41b632dc535f31d6fe6fa44cbb6bbbebbdfed73eaefd3d35",
|
|
122
128
|
"Mentions": "bf9b8f29f881ebe7022a28744ae8fcc63329e887f3bfd6d660708192e9f912cd",
|
|
123
129
|
"QRCode": "ecd8c0488bc4ef147208627cc6d4298be62633e9293a0c5cd7f0835594c85d71",
|
|
124
|
-
"Watermark": "
|
|
130
|
+
"Watermark": "4e942660bb7dee0623c4d41553fd0e162b1e1f04f195e5a0b55eddae18bdbee3",
|
|
125
131
|
"Affix": "4215241a8b0633eb191a00b50a875e10cb226ab7ef21f2f6842431d8f6acc3be",
|
|
126
132
|
"SpeedDial": "b6a51b1715c92c4a2860759b146b4ceeab01acf326faeeb1e023a01e8b811fc9"
|
|
127
133
|
},
|
|
@@ -131,7 +137,8 @@
|
|
|
131
137
|
"scheduler": "fe25905d95e8d4294df9075e47ee9257d7db8e6542a3ac81272c4dee2ea1fdc0",
|
|
132
138
|
"data-collections": "fbbc09e60caed2449b5b904f9f1432278b52c8d28e7fe22de30af21208a4dfaf",
|
|
133
139
|
"theme-builder": "8de1d5f902b728af947f57e0f3667a5a8991ef71755bca7d985cdcaec9572252",
|
|
134
|
-
"rich-text-editor": "3c47135e8e10890e1d41b1878fdd497a5c87c34c5663821cf4005602cd7adbc9"
|
|
140
|
+
"rich-text-editor": "3c47135e8e10890e1d41b1878fdd497a5c87c34c5663821cf4005602cd7adbc9",
|
|
141
|
+
"data-visualization": "97f8f447cd36dfe026478f3eea379abe0907d5094f06285ec351c14a62908259"
|
|
135
142
|
}
|
|
136
143
|
},
|
|
137
144
|
"components": [
|
|
@@ -1935,6 +1942,335 @@
|
|
|
1935
1942
|
"recipes": [],
|
|
1936
1943
|
"runtimeEvents": []
|
|
1937
1944
|
},
|
|
1945
|
+
{
|
|
1946
|
+
"apiReference": [
|
|
1947
|
+
{
|
|
1948
|
+
"attribute": "glass",
|
|
1949
|
+
"defaultValue": "false",
|
|
1950
|
+
"description": "Applies the tokenized liquid-glass surface treatment with backdrop-filter fallbacks; \"subtle\" and \"strong\" adjust the fill intensity.",
|
|
1951
|
+
"values": "boolean | \"subtle\" | \"strong\""
|
|
1952
|
+
},
|
|
1953
|
+
{
|
|
1954
|
+
"attribute": "series",
|
|
1955
|
+
"defaultValue": "required",
|
|
1956
|
+
"description": "Provides already-aggregated categorical values and stable series metadata.",
|
|
1957
|
+
"values": "LumenChartSeries[]"
|
|
1958
|
+
},
|
|
1959
|
+
{
|
|
1960
|
+
"attribute": "orientation",
|
|
1961
|
+
"defaultValue": "\"vertical\"",
|
|
1962
|
+
"description": "Controls whether values extend across the x or y axis.",
|
|
1963
|
+
"values": "\"horizontal\" | \"vertical\""
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
"attribute": "layout",
|
|
1967
|
+
"defaultValue": "\"grouped\"",
|
|
1968
|
+
"description": "Places series beside one another or combines their positive and negative totals.",
|
|
1969
|
+
"values": "\"grouped\" | \"stacked\""
|
|
1970
|
+
},
|
|
1971
|
+
{
|
|
1972
|
+
"attribute": "showLegend",
|
|
1973
|
+
"defaultValue": "true for multiple series",
|
|
1974
|
+
"description": "Shows the color-independent series key.",
|
|
1975
|
+
"values": "boolean"
|
|
1976
|
+
},
|
|
1977
|
+
{
|
|
1978
|
+
"attribute": "showTable",
|
|
1979
|
+
"defaultValue": "true",
|
|
1980
|
+
"description": "Provides a revealable semantic table containing every plotted value.",
|
|
1981
|
+
"values": "boolean"
|
|
1982
|
+
},
|
|
1983
|
+
{
|
|
1984
|
+
"attribute": "heading, description, caption",
|
|
1985
|
+
"defaultValue": "-",
|
|
1986
|
+
"description": "Adds visible chart context without replacing the accessible name.",
|
|
1987
|
+
"values": "string"
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
"attribute": "class, className",
|
|
1991
|
+
"defaultValue": "\"\"",
|
|
1992
|
+
"description": "Merges custom classes with the generated ui-* root classes.",
|
|
1993
|
+
"values": "string"
|
|
1994
|
+
},
|
|
1995
|
+
{
|
|
1996
|
+
"attribute": "...native attributes",
|
|
1997
|
+
"defaultValue": "-",
|
|
1998
|
+
"description": "Forwards standard attributes to the root element unless the component consumes them.",
|
|
1999
|
+
"values": "HTML attributes"
|
|
2000
|
+
}
|
|
2001
|
+
],
|
|
2002
|
+
"astroSource": "---\nimport {\n createLumenBarGeometry,\n getLumenChartTicks,\n hasLumenChartData,\n type LumenBarChartLayout,\n type LumenChartOrientation,\n type LumenChartSeries,\n resolveLumenChartTone,\n scaleLumenChartValue\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Chart from './Chart.astro'\n\ninterface Props extends HTMLAttributes<'figure'> {\n caption?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n layout?: LumenBarChartLayout\n orientation?: LumenChartOrientation\n series: readonly LumenChartSeries[]\n showLegend?: boolean\n showTable?: boolean\n}\n\nconst {\n caption,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n layout = 'grouped',\n orientation = 'vertical',\n series,\n showLegend = series.length > 1,\n showTable = true,\n ...rest\n} = Astro.props\nconst geometry = createLumenBarGeometry(series, { layout, orientation })\nconst hasData = hasLumenChartData(series)\nconst ticks = getLumenChartTicks(geometry.domain)\nconst categories = geometry.categories.map(category => category.label)\nconst valueFor = (item: LumenChartSeries, category: number | string) =>\n item.data.find(datum => datum.x === category)?.y ?? null\nconst labelFor = (item: LumenChartSeries, category: number | string) =>\n item.data.find(datum => datum.x === category)?.label\nconst margin = orientation === 'horizontal'\n ? { bottom: 24, left: 112, right: 20, top: 16 }\n : { bottom: 52, left: 52, right: 16, top: 16 }\n---\n\n<Chart\n class:list={['ui-bar-chart', classProp, className]}\n {caption}\n {description}\n {glass}\n {heading}\n {...rest}\n>\n {\n showLegend && hasData && (\n <ul class=\"ui-chart__legend\" aria-label=\"Chart legend\">\n {series.map((item, index) => (\n <li class={`ui-chart-tone--${resolveLumenChartTone(item.tone, index)}`}>\n <span aria-hidden=\"true\" />\n {item.label}\n </li>\n ))}\n </ul>\n )\n }\n {!hasData && <p class=\"ui-chart__empty\" role=\"status\">No chart data available.</p>}\n <div class=\"ui-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${geometry.width} ${geometry.height}`}\n >\n <g class=\"ui-chart__grid\">\n {\n ticks.map((tick) => {\n const coordinate =\n orientation === 'horizontal'\n ? scaleLumenChartValue(\n tick,\n geometry.domain,\n margin.left,\n geometry.width - margin.right\n )\n : scaleLumenChartValue(\n tick,\n geometry.domain,\n geometry.height - margin.bottom,\n margin.top\n )\n\n return orientation === 'horizontal' ? (\n <line\n x1={coordinate}\n x2={coordinate}\n y1={margin.top}\n y2={geometry.height - margin.bottom}\n />\n ) : (\n <line\n x1={margin.left}\n x2={geometry.width - margin.right}\n y1={coordinate}\n y2={coordinate}\n />\n )\n })\n }\n </g>\n <g class=\"ui-chart__axis-labels\">\n {\n geometry.categories.map((category) => (\n <text\n dominant-baseline={orientation === 'horizontal' ? 'middle' : undefined}\n text-anchor={orientation === 'horizontal' ? 'end' : 'middle'}\n x={category.x}\n y={category.y}\n >\n {String(category.label)}\n </text>\n ))\n }\n </g>\n <g class=\"ui-bar-chart__marks\">\n {\n geometry.marks.map((mark) => (\n <rect\n class={`ui-chart-tone--${mark.tone}`}\n height={mark.height}\n rx=\"4\"\n width={mark.width}\n x={mark.x}\n y={mark.y}\n >\n <title>\n {`${String(mark.category)} · ${mark.seriesLabel}: ${mark.value}`}\n </title>\n </rect>\n ))\n }\n </g>\n </svg>\n </div>\n {\n showTable && hasData && (\n <details class=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n {series.map(item => <th scope=\"col\">{item.label}</th>)}\n </tr>\n </thead>\n <tbody>\n {categories.map(category => (\n <tr>\n <th scope=\"row\">{String(category)}</th>\n {series.map(item => (\n <td>\n {labelFor(item, category) ??\n String(valueFor(item, category) ?? 'Not available')}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )\n }\n</Chart>\n",
|
|
2003
|
+
"category": "Data display",
|
|
2004
|
+
"collections": [
|
|
2005
|
+
"Data visualization"
|
|
2006
|
+
],
|
|
2007
|
+
"dependencies": [
|
|
2008
|
+
"Chart",
|
|
2009
|
+
"styles"
|
|
2010
|
+
],
|
|
2011
|
+
"description": "Compares categorical or discrete-period values with grouped and stacked bars.",
|
|
2012
|
+
"files": [
|
|
2013
|
+
"packages/astro/components/BarChart.astro",
|
|
2014
|
+
"packages/astro/components/Chart.astro",
|
|
2015
|
+
"packages/astro/styles/lumen.css"
|
|
2016
|
+
],
|
|
2017
|
+
"frameworkDetails": {
|
|
2018
|
+
"astro": {
|
|
2019
|
+
"available": true,
|
|
2020
|
+
"example": "<BarChart aria-label=\"Downloads by project\" heading=\"Package downloads\" orientation=\"horizontal\" series={[{ id: \"downloads\", label: \"Downloads\", data: [{ x: \"Lumen\", y: 18420 }, { x: \"Observatory\", y: 6320 }] }]} />",
|
|
2021
|
+
"importStatement": "import { BarChart } from '@santi020k/lumen-astro'",
|
|
2022
|
+
"language": "astro",
|
|
2023
|
+
"packageName": "@santi020k/lumen-astro",
|
|
2024
|
+
"props": [
|
|
2025
|
+
{
|
|
2026
|
+
"name": "caption",
|
|
2027
|
+
"optional": true,
|
|
2028
|
+
"type": "string"
|
|
2029
|
+
},
|
|
2030
|
+
{
|
|
2031
|
+
"name": "class",
|
|
2032
|
+
"optional": true,
|
|
2033
|
+
"type": "string | null"
|
|
2034
|
+
},
|
|
2035
|
+
{
|
|
2036
|
+
"name": "className",
|
|
2037
|
+
"optional": true,
|
|
2038
|
+
"type": "string"
|
|
2039
|
+
},
|
|
2040
|
+
{
|
|
2041
|
+
"name": "description",
|
|
2042
|
+
"optional": true,
|
|
2043
|
+
"type": "string"
|
|
2044
|
+
},
|
|
2045
|
+
{
|
|
2046
|
+
"name": "glass",
|
|
2047
|
+
"optional": true,
|
|
2048
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
2049
|
+
},
|
|
2050
|
+
{
|
|
2051
|
+
"name": "heading",
|
|
2052
|
+
"optional": true,
|
|
2053
|
+
"type": "string"
|
|
2054
|
+
},
|
|
2055
|
+
{
|
|
2056
|
+
"name": "layout",
|
|
2057
|
+
"optional": true,
|
|
2058
|
+
"type": "LumenBarChartLayout"
|
|
2059
|
+
},
|
|
2060
|
+
{
|
|
2061
|
+
"name": "orientation",
|
|
2062
|
+
"optional": true,
|
|
2063
|
+
"type": "LumenChartOrientation"
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
"name": "series",
|
|
2067
|
+
"optional": false,
|
|
2068
|
+
"type": "readonly LumenChartSeries[]"
|
|
2069
|
+
},
|
|
2070
|
+
{
|
|
2071
|
+
"name": "showLegend",
|
|
2072
|
+
"optional": true,
|
|
2073
|
+
"type": "boolean"
|
|
2074
|
+
},
|
|
2075
|
+
{
|
|
2076
|
+
"name": "showTable",
|
|
2077
|
+
"optional": true,
|
|
2078
|
+
"type": "boolean"
|
|
2079
|
+
}
|
|
2080
|
+
],
|
|
2081
|
+
"propsExtends": "HTMLAttributes<'figure'>",
|
|
2082
|
+
"source": "---\nimport {\n createLumenBarGeometry,\n getLumenChartTicks,\n hasLumenChartData,\n type LumenBarChartLayout,\n type LumenChartOrientation,\n type LumenChartSeries,\n resolveLumenChartTone,\n scaleLumenChartValue\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Chart from './Chart.astro'\n\ninterface Props extends HTMLAttributes<'figure'> {\n caption?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n layout?: LumenBarChartLayout\n orientation?: LumenChartOrientation\n series: readonly LumenChartSeries[]\n showLegend?: boolean\n showTable?: boolean\n}\n\nconst {\n caption,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n layout = 'grouped',\n orientation = 'vertical',\n series,\n showLegend = series.length > 1,\n showTable = true,\n ...rest\n} = Astro.props\nconst geometry = createLumenBarGeometry(series, { layout, orientation })\nconst hasData = hasLumenChartData(series)\nconst ticks = getLumenChartTicks(geometry.domain)\nconst categories = geometry.categories.map(category => category.label)\nconst valueFor = (item: LumenChartSeries, category: number | string) =>\n item.data.find(datum => datum.x === category)?.y ?? null\nconst labelFor = (item: LumenChartSeries, category: number | string) =>\n item.data.find(datum => datum.x === category)?.label\nconst margin = orientation === 'horizontal'\n ? { bottom: 24, left: 112, right: 20, top: 16 }\n : { bottom: 52, left: 52, right: 16, top: 16 }\n---\n\n<Chart\n class:list={['ui-bar-chart', classProp, className]}\n {caption}\n {description}\n {glass}\n {heading}\n {...rest}\n>\n {\n showLegend && hasData && (\n <ul class=\"ui-chart__legend\" aria-label=\"Chart legend\">\n {series.map((item, index) => (\n <li class={`ui-chart-tone--${resolveLumenChartTone(item.tone, index)}`}>\n <span aria-hidden=\"true\" />\n {item.label}\n </li>\n ))}\n </ul>\n )\n }\n {!hasData && <p class=\"ui-chart__empty\" role=\"status\">No chart data available.</p>}\n <div class=\"ui-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${geometry.width} ${geometry.height}`}\n >\n <g class=\"ui-chart__grid\">\n {\n ticks.map((tick) => {\n const coordinate =\n orientation === 'horizontal'\n ? scaleLumenChartValue(\n tick,\n geometry.domain,\n margin.left,\n geometry.width - margin.right\n )\n : scaleLumenChartValue(\n tick,\n geometry.domain,\n geometry.height - margin.bottom,\n margin.top\n )\n\n return orientation === 'horizontal' ? (\n <line\n x1={coordinate}\n x2={coordinate}\n y1={margin.top}\n y2={geometry.height - margin.bottom}\n />\n ) : (\n <line\n x1={margin.left}\n x2={geometry.width - margin.right}\n y1={coordinate}\n y2={coordinate}\n />\n )\n })\n }\n </g>\n <g class=\"ui-chart__axis-labels\">\n {\n geometry.categories.map((category) => (\n <text\n dominant-baseline={orientation === 'horizontal' ? 'middle' : undefined}\n text-anchor={orientation === 'horizontal' ? 'end' : 'middle'}\n x={category.x}\n y={category.y}\n >\n {String(category.label)}\n </text>\n ))\n }\n </g>\n <g class=\"ui-bar-chart__marks\">\n {\n geometry.marks.map((mark) => (\n <rect\n class={`ui-chart-tone--${mark.tone}`}\n height={mark.height}\n rx=\"4\"\n width={mark.width}\n x={mark.x}\n y={mark.y}\n >\n <title>\n {`${String(mark.category)} · ${mark.seriesLabel}: ${mark.value}`}\n </title>\n </rect>\n ))\n }\n </g>\n </svg>\n </div>\n {\n showTable && hasData && (\n <details class=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n {series.map(item => <th scope=\"col\">{item.label}</th>)}\n </tr>\n </thead>\n <tbody>\n {categories.map(category => (\n <tr>\n <th scope=\"row\">{String(category)}</th>\n {series.map(item => (\n <td>\n {labelFor(item, category) ??\n String(valueFor(item, category) ?? 'Not available')}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )\n }\n</Chart>\n",
|
|
2083
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
2084
|
+
},
|
|
2085
|
+
"elements": {
|
|
2086
|
+
"attributes": [
|
|
2087
|
+
"layout",
|
|
2088
|
+
"orientation",
|
|
2089
|
+
"glass",
|
|
2090
|
+
"series",
|
|
2091
|
+
"showLegend",
|
|
2092
|
+
"showTable",
|
|
2093
|
+
"heading, description, caption",
|
|
2094
|
+
"class, className",
|
|
2095
|
+
"...native attributes"
|
|
2096
|
+
],
|
|
2097
|
+
"available": true,
|
|
2098
|
+
"behavior": {
|
|
2099
|
+
"mode": "registration",
|
|
2100
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
2101
|
+
},
|
|
2102
|
+
"example": "<lumen-bar-chart></lumen-bar-chart>",
|
|
2103
|
+
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
2104
|
+
"language": "html",
|
|
2105
|
+
"packageName": "@santi020k/lumen-elements",
|
|
2106
|
+
"props": [],
|
|
2107
|
+
"propsExtends": "HTMLElement attributes",
|
|
2108
|
+
"registration": "defineLumenElements()",
|
|
2109
|
+
"source": "BarChart: {\n attributeClasses: glassAttributeClasses('ui-chart--glass'),\n baseClassName: 'ui-chart ui-bar-chart',\n defaults: { layout: 'grouped', orientation: 'vertical' },\n role: 'figure',\n tagName: 'lumen-bar-chart'\n }",
|
|
2110
|
+
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
2111
|
+
"tagName": "lumen-bar-chart"
|
|
2112
|
+
},
|
|
2113
|
+
"react": {
|
|
2114
|
+
"available": true,
|
|
2115
|
+
"example": "<BarChart aria-label=\"Downloads by project\" heading=\"Package downloads\" orientation=\"horizontal\" series={[{ id: \"downloads\", label: \"Downloads\", data: [{ x: \"Lumen\", y: 18420 }, { x: \"Observatory\", y: 6320 }] }]} />",
|
|
2116
|
+
"importStatement": "import { BarChart } from '@santi020k/lumen-react'",
|
|
2117
|
+
"language": "tsx",
|
|
2118
|
+
"packageName": "@santi020k/lumen-react",
|
|
2119
|
+
"props": [
|
|
2120
|
+
{
|
|
2121
|
+
"name": "layout",
|
|
2122
|
+
"optional": true,
|
|
2123
|
+
"type": "LumenBarChartLayout"
|
|
2124
|
+
},
|
|
2125
|
+
{
|
|
2126
|
+
"name": "orientation",
|
|
2127
|
+
"optional": true,
|
|
2128
|
+
"type": "LumenChartOrientation"
|
|
2129
|
+
},
|
|
2130
|
+
{
|
|
2131
|
+
"name": "series",
|
|
2132
|
+
"optional": true,
|
|
2133
|
+
"type": "readonly LumenChartSeries[]"
|
|
2134
|
+
},
|
|
2135
|
+
{
|
|
2136
|
+
"name": "showLegend",
|
|
2137
|
+
"optional": true,
|
|
2138
|
+
"type": "boolean"
|
|
2139
|
+
},
|
|
2140
|
+
{
|
|
2141
|
+
"name": "showTable",
|
|
2142
|
+
"optional": true,
|
|
2143
|
+
"type": "boolean"
|
|
2144
|
+
}
|
|
2145
|
+
],
|
|
2146
|
+
"propsExtends": "Omit<ChartProps, 'children'>",
|
|
2147
|
+
"source": "export interface BarChartProps extends Omit<ChartProps, 'children'> {\n layout?: LumenBarChartLayout\n orientation?: LumenChartOrientation\n series?: readonly LumenChartSeries[]\n showLegend?: boolean\n showTable?: boolean\n}\n\nexport const BarChart = ({\n className,\n layout = 'grouped',\n orientation = 'vertical',\n series = emptyChartSeries,\n showLegend = series.length > 1,\n showTable = true,\n ...props\n}: BarChartProps) => {\n const geometry = createLumenBarGeometry(series, { layout, orientation })\n const hasData = hasLumenChartData(series)\n const ticks = getLumenChartTicks(geometry.domain)\n const categories = geometry.categories.map(category => category.label)\n\n const margin = orientation === 'horizontal'\n ? { bottom: 24, left: 112, right: 20, top: 16 }\n : { bottom: 52, left: 52, right: 16, top: 16 }\n\n return (\n <Chart className={composeClassName('ui-bar-chart', className)} {...props}>\n {showLegend && hasData && <ChartLegend series={series} />}\n {!hasData && (\n <p className=\"ui-chart__empty\" role=\"status\">No chart data available.</p>\n )}\n <div className=\"ui-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${geometry.width} ${geometry.height}`}\n >\n <g className=\"ui-chart__grid\">\n {ticks.map(tick => {\n const coordinate = orientation === 'horizontal'\n ? scaleLumenChartValue(\n tick,\n geometry.domain,\n margin.left,\n geometry.width - margin.right\n )\n : scaleLumenChartValue(\n tick,\n geometry.domain,\n geometry.height - margin.bottom,\n margin.top\n )\n\n return orientation === 'horizontal' ? (\n <line\n key={tick}\n x1={coordinate}\n x2={coordinate}\n y1={margin.top}\n y2={geometry.height - margin.bottom}\n />\n ) : (\n <line\n key={tick}\n x1={margin.left}\n x2={geometry.width - margin.right}\n y1={coordinate}\n y2={coordinate}\n />\n )\n })}\n </g>\n <g className=\"ui-chart__axis-labels\">\n {geometry.categories.map(category => (\n <text\n dominantBaseline={orientation === 'horizontal' ? 'middle' : undefined}\n key={`${typeof category.label}:${String(category.label)}`}\n textAnchor={orientation === 'horizontal' ? 'end' : 'middle'}\n x={category.x}\n y={category.y}\n >\n {String(category.label)}\n </text>\n ))}\n </g>\n <g className=\"ui-bar-chart__marks\">\n {geometry.marks.map(mark => (\n <rect\n className={`ui-chart-tone--${mark.tone}`}\n height={mark.height}\n key={`${mark.seriesId}:${String(mark.category)}`}\n rx=\"4\"\n width={mark.width}\n x={mark.x}\n y={mark.y}\n >\n <title>{`${String(mark.category)} · ${mark.seriesLabel}: ${mark.value}`}</title>\n </rect>\n ))}\n </g>\n </svg>\n </div>\n {showTable && hasData && (\n <ChartDataTable categories={categories} series={series} />\n )}\n </Chart>\n )\n}",
|
|
2148
|
+
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
2149
|
+
}
|
|
2150
|
+
},
|
|
2151
|
+
"frameworks": {
|
|
2152
|
+
"astro": true,
|
|
2153
|
+
"elements": true,
|
|
2154
|
+
"react": true
|
|
2155
|
+
},
|
|
2156
|
+
"guidance": {
|
|
2157
|
+
"when": "Use to compare categories, rankings, or discrete periods from already-aggregated values.",
|
|
2158
|
+
"distinction": "Use LineChart for continuous ordered trends and Sparkline for a compact trend attached to one metric."
|
|
2159
|
+
},
|
|
2160
|
+
"kebab": "bar-chart",
|
|
2161
|
+
"keyboardInteractions": [],
|
|
2162
|
+
"keywords": [
|
|
2163
|
+
"aggregated",
|
|
2164
|
+
"already",
|
|
2165
|
+
"and",
|
|
2166
|
+
"attached",
|
|
2167
|
+
"barchart",
|
|
2168
|
+
"bars",
|
|
2169
|
+
"breakdowns",
|
|
2170
|
+
"categorical",
|
|
2171
|
+
"categories",
|
|
2172
|
+
"compact",
|
|
2173
|
+
"compare",
|
|
2174
|
+
"compares",
|
|
2175
|
+
"comparisons",
|
|
2176
|
+
"continuous",
|
|
2177
|
+
"custom",
|
|
2178
|
+
"data",
|
|
2179
|
+
"discrete",
|
|
2180
|
+
"display",
|
|
2181
|
+
"for",
|
|
2182
|
+
"from",
|
|
2183
|
+
"grouped",
|
|
2184
|
+
"linechart",
|
|
2185
|
+
"match",
|
|
2186
|
+
"metric",
|
|
2187
|
+
"metrics",
|
|
2188
|
+
"one",
|
|
2189
|
+
"ordered",
|
|
2190
|
+
"part",
|
|
2191
|
+
"period",
|
|
2192
|
+
"periods",
|
|
2193
|
+
"plots",
|
|
2194
|
+
"question",
|
|
2195
|
+
"rankings",
|
|
2196
|
+
"sparkline",
|
|
2197
|
+
"stacked",
|
|
2198
|
+
"the",
|
|
2199
|
+
"trend",
|
|
2200
|
+
"trends",
|
|
2201
|
+
"use",
|
|
2202
|
+
"values",
|
|
2203
|
+
"visualization",
|
|
2204
|
+
"whole",
|
|
2205
|
+
"with"
|
|
2206
|
+
],
|
|
2207
|
+
"name": "BarChart",
|
|
2208
|
+
"props": [
|
|
2209
|
+
{
|
|
2210
|
+
"name": "caption",
|
|
2211
|
+
"optional": true,
|
|
2212
|
+
"type": "string"
|
|
2213
|
+
},
|
|
2214
|
+
{
|
|
2215
|
+
"name": "class",
|
|
2216
|
+
"optional": true,
|
|
2217
|
+
"type": "string | null"
|
|
2218
|
+
},
|
|
2219
|
+
{
|
|
2220
|
+
"name": "className",
|
|
2221
|
+
"optional": true,
|
|
2222
|
+
"type": "string"
|
|
2223
|
+
},
|
|
2224
|
+
{
|
|
2225
|
+
"name": "description",
|
|
2226
|
+
"optional": true,
|
|
2227
|
+
"type": "string"
|
|
2228
|
+
},
|
|
2229
|
+
{
|
|
2230
|
+
"name": "glass",
|
|
2231
|
+
"optional": true,
|
|
2232
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
2233
|
+
},
|
|
2234
|
+
{
|
|
2235
|
+
"name": "heading",
|
|
2236
|
+
"optional": true,
|
|
2237
|
+
"type": "string"
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
"name": "layout",
|
|
2241
|
+
"optional": true,
|
|
2242
|
+
"type": "LumenBarChartLayout"
|
|
2243
|
+
},
|
|
2244
|
+
{
|
|
2245
|
+
"name": "orientation",
|
|
2246
|
+
"optional": true,
|
|
2247
|
+
"type": "LumenChartOrientation"
|
|
2248
|
+
},
|
|
2249
|
+
{
|
|
2250
|
+
"name": "series",
|
|
2251
|
+
"optional": false,
|
|
2252
|
+
"type": "readonly LumenChartSeries[]"
|
|
2253
|
+
},
|
|
2254
|
+
{
|
|
2255
|
+
"name": "showLegend",
|
|
2256
|
+
"optional": true,
|
|
2257
|
+
"type": "boolean"
|
|
2258
|
+
},
|
|
2259
|
+
{
|
|
2260
|
+
"name": "showTable",
|
|
2261
|
+
"optional": true,
|
|
2262
|
+
"type": "boolean"
|
|
2263
|
+
}
|
|
2264
|
+
],
|
|
2265
|
+
"propsExtends": "HTMLAttributes<'figure'>",
|
|
2266
|
+
"recipes": [
|
|
2267
|
+
{
|
|
2268
|
+
"name": "data-visualization",
|
|
2269
|
+
"type": "recipe"
|
|
2270
|
+
}
|
|
2271
|
+
],
|
|
2272
|
+
"runtimeEvents": []
|
|
2273
|
+
},
|
|
1938
2274
|
{
|
|
1939
2275
|
"apiReference": [
|
|
1940
2276
|
{
|
|
@@ -3532,8 +3868,20 @@
|
|
|
3532
3868
|
{
|
|
3533
3869
|
"attribute": "children",
|
|
3534
3870
|
"defaultValue": "required",
|
|
3535
|
-
"description": "Composes
|
|
3536
|
-
"values": "
|
|
3871
|
+
"description": "Composes a specialized visualization while the consumer owns its data and accessible description.",
|
|
3872
|
+
"values": "custom SVG, canvas, HTML plot, and optional table"
|
|
3873
|
+
},
|
|
3874
|
+
{
|
|
3875
|
+
"attribute": "heading, description, value",
|
|
3876
|
+
"defaultValue": "-",
|
|
3877
|
+
"description": "Builds the standard visible chart header without consuming the native title attribute.",
|
|
3878
|
+
"values": "string"
|
|
3879
|
+
},
|
|
3880
|
+
{
|
|
3881
|
+
"attribute": "caption",
|
|
3882
|
+
"defaultValue": "-",
|
|
3883
|
+
"description": "Adds a semantic figcaption after the custom plot.",
|
|
3884
|
+
"values": "string"
|
|
3537
3885
|
},
|
|
3538
3886
|
{
|
|
3539
3887
|
"attribute": "class, className",
|
|
@@ -3548,9 +3896,11 @@
|
|
|
3548
3896
|
"values": "HTML attributes"
|
|
3549
3897
|
}
|
|
3550
3898
|
],
|
|
3551
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'figure'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-chart',\n glass && 'ui-chart--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<figure\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</figure>\n",
|
|
3899
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'figure'> {\n caption?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n value?: string\n}\n\nconst {\n caption,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n value,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-chart',\n glass && 'ui-chart--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<figure\n class:list={classList}\n {...passthrough}\n>\n {\n (heading || description || value || Astro.slots.has('header')) && (\n <header>\n <slot name=\"header\">\n <div class=\"ui-chart__heading\">\n {heading && <h3>{heading}</h3>}\n {description && <p>{description}</p>}\n </div>\n {value && <strong data-ui-chart-value>{value}</strong>}\n </slot>\n <slot name=\"actions\" />\n </header>\n )\n }\n <slot />\n {caption && <figcaption>{caption}</figcaption>}\n</figure>\n",
|
|
3552
3900
|
"category": "Data display",
|
|
3553
|
-
"collections": [
|
|
3901
|
+
"collections": [
|
|
3902
|
+
"Data visualization"
|
|
3903
|
+
],
|
|
3554
3904
|
"dependencies": [
|
|
3555
3905
|
"styles"
|
|
3556
3906
|
],
|
|
@@ -3567,6 +3917,11 @@
|
|
|
3567
3917
|
"language": "astro",
|
|
3568
3918
|
"packageName": "@santi020k/lumen-astro",
|
|
3569
3919
|
"props": [
|
|
3920
|
+
{
|
|
3921
|
+
"name": "caption",
|
|
3922
|
+
"optional": true,
|
|
3923
|
+
"type": "string"
|
|
3924
|
+
},
|
|
3570
3925
|
{
|
|
3571
3926
|
"name": "class",
|
|
3572
3927
|
"optional": true,
|
|
@@ -3577,20 +3932,37 @@
|
|
|
3577
3932
|
"optional": true,
|
|
3578
3933
|
"type": "string"
|
|
3579
3934
|
},
|
|
3935
|
+
{
|
|
3936
|
+
"name": "description",
|
|
3937
|
+
"optional": true,
|
|
3938
|
+
"type": "string"
|
|
3939
|
+
},
|
|
3580
3940
|
{
|
|
3581
3941
|
"name": "glass",
|
|
3582
3942
|
"optional": true,
|
|
3583
3943
|
"type": "boolean | 'subtle' | 'strong'"
|
|
3944
|
+
},
|
|
3945
|
+
{
|
|
3946
|
+
"name": "heading",
|
|
3947
|
+
"optional": true,
|
|
3948
|
+
"type": "string"
|
|
3949
|
+
},
|
|
3950
|
+
{
|
|
3951
|
+
"name": "value",
|
|
3952
|
+
"optional": true,
|
|
3953
|
+
"type": "string"
|
|
3584
3954
|
}
|
|
3585
3955
|
],
|
|
3586
3956
|
"propsExtends": "HTMLAttributes<'figure'>",
|
|
3587
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'figure'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-chart',\n glass && 'ui-chart--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<figure\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</figure>\n",
|
|
3957
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'figure'> {\n caption?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n value?: string\n}\n\nconst {\n caption,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n value,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-chart',\n glass && 'ui-chart--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<figure\n class:list={classList}\n {...passthrough}\n>\n {\n (heading || description || value || Astro.slots.has('header')) && (\n <header>\n <slot name=\"header\">\n <div class=\"ui-chart__heading\">\n {heading && <h3>{heading}</h3>}\n {description && <p>{description}</p>}\n </div>\n {value && <strong data-ui-chart-value>{value}</strong>}\n </slot>\n <slot name=\"actions\" />\n </header>\n )\n }\n <slot />\n {caption && <figcaption>{caption}</figcaption>}\n</figure>\n",
|
|
3588
3958
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
3589
3959
|
},
|
|
3590
3960
|
"elements": {
|
|
3591
3961
|
"attributes": [
|
|
3592
3962
|
"glass",
|
|
3593
3963
|
"children",
|
|
3964
|
+
"heading, description, value",
|
|
3965
|
+
"caption",
|
|
3594
3966
|
"class, className",
|
|
3595
3967
|
"...native attributes"
|
|
3596
3968
|
],
|
|
@@ -3617,14 +3989,34 @@
|
|
|
3617
3989
|
"language": "tsx",
|
|
3618
3990
|
"packageName": "@santi020k/lumen-react",
|
|
3619
3991
|
"props": [
|
|
3992
|
+
{
|
|
3993
|
+
"name": "caption",
|
|
3994
|
+
"optional": true,
|
|
3995
|
+
"type": "ReactNode"
|
|
3996
|
+
},
|
|
3997
|
+
{
|
|
3998
|
+
"name": "description",
|
|
3999
|
+
"optional": true,
|
|
4000
|
+
"type": "ReactNode"
|
|
4001
|
+
},
|
|
3620
4002
|
{
|
|
3621
4003
|
"name": "glass",
|
|
3622
4004
|
"optional": true,
|
|
3623
4005
|
"type": "LumenGlassProp"
|
|
4006
|
+
},
|
|
4007
|
+
{
|
|
4008
|
+
"name": "heading",
|
|
4009
|
+
"optional": true,
|
|
4010
|
+
"type": "ReactNode"
|
|
4011
|
+
},
|
|
4012
|
+
{
|
|
4013
|
+
"name": "value",
|
|
4014
|
+
"optional": true,
|
|
4015
|
+
"type": "ReactNode"
|
|
3624
4016
|
}
|
|
3625
4017
|
],
|
|
3626
4018
|
"propsExtends": "ComponentPropsWithoutRef<'figure'>",
|
|
3627
|
-
"source": "export interface ChartProps extends ComponentPropsWithoutRef<'figure'> {\n glass?: LumenGlassProp\n}\n\nexport const Chart = ({
|
|
4019
|
+
"source": "export interface ChartProps extends ComponentPropsWithoutRef<'figure'> {\n caption?: ReactNode\n description?: ReactNode\n glass?: LumenGlassProp\n heading?: ReactNode\n value?: ReactNode\n}\n\nexport const Chart = ({\n caption,\n children,\n className,\n description,\n glass = false,\n heading,\n value,\n ...props\n}: ChartProps) => (\n <figure className={composeClassName('ui-chart', glassClass('ui-chart', glass), className)} {...props}>\n {(heading || description || value) && (\n <header>\n <div className=\"ui-chart__heading\">\n {heading && <h3>{heading}</h3>}\n {description && <p>{description}</p>}\n </div>\n {value && <strong data-ui-chart-value>{value}</strong>}\n </header>\n )}\n {children}\n {caption && <figcaption>{caption}</figcaption>}\n </figure>\n)",
|
|
3628
4020
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
3629
4021
|
}
|
|
3630
4022
|
},
|
|
@@ -3638,21 +4030,39 @@
|
|
|
3638
4030
|
"keyboardInteractions": [],
|
|
3639
4031
|
"keywords": [
|
|
3640
4032
|
"and",
|
|
4033
|
+
"breakdowns",
|
|
3641
4034
|
"captions",
|
|
4035
|
+
"categorical",
|
|
3642
4036
|
"chart",
|
|
4037
|
+
"compact",
|
|
4038
|
+
"comparisons",
|
|
4039
|
+
"custom",
|
|
3643
4040
|
"data",
|
|
3644
4041
|
"display",
|
|
3645
4042
|
"for",
|
|
3646
4043
|
"frames",
|
|
3647
4044
|
"headers",
|
|
3648
4045
|
"lightweight",
|
|
4046
|
+
"match",
|
|
3649
4047
|
"metric",
|
|
4048
|
+
"metrics",
|
|
4049
|
+
"ordered",
|
|
4050
|
+
"part",
|
|
3650
4051
|
"plots",
|
|
4052
|
+
"question",
|
|
3651
4053
|
"svg",
|
|
3652
|
-
"
|
|
4054
|
+
"the",
|
|
4055
|
+
"trends",
|
|
4056
|
+
"visualization",
|
|
4057
|
+
"whole"
|
|
3653
4058
|
],
|
|
3654
4059
|
"name": "Chart",
|
|
3655
4060
|
"props": [
|
|
4061
|
+
{
|
|
4062
|
+
"name": "caption",
|
|
4063
|
+
"optional": true,
|
|
4064
|
+
"type": "string"
|
|
4065
|
+
},
|
|
3656
4066
|
{
|
|
3657
4067
|
"name": "class",
|
|
3658
4068
|
"optional": true,
|
|
@@ -3663,14 +4073,34 @@
|
|
|
3663
4073
|
"optional": true,
|
|
3664
4074
|
"type": "string"
|
|
3665
4075
|
},
|
|
4076
|
+
{
|
|
4077
|
+
"name": "description",
|
|
4078
|
+
"optional": true,
|
|
4079
|
+
"type": "string"
|
|
4080
|
+
},
|
|
3666
4081
|
{
|
|
3667
4082
|
"name": "glass",
|
|
3668
4083
|
"optional": true,
|
|
3669
4084
|
"type": "boolean | 'subtle' | 'strong'"
|
|
4085
|
+
},
|
|
4086
|
+
{
|
|
4087
|
+
"name": "heading",
|
|
4088
|
+
"optional": true,
|
|
4089
|
+
"type": "string"
|
|
4090
|
+
},
|
|
4091
|
+
{
|
|
4092
|
+
"name": "value",
|
|
4093
|
+
"optional": true,
|
|
4094
|
+
"type": "string"
|
|
3670
4095
|
}
|
|
3671
4096
|
],
|
|
3672
4097
|
"propsExtends": "HTMLAttributes<'figure'>",
|
|
3673
|
-
"recipes": [
|
|
4098
|
+
"recipes": [
|
|
4099
|
+
{
|
|
4100
|
+
"name": "data-visualization",
|
|
4101
|
+
"type": "recipe"
|
|
4102
|
+
}
|
|
4103
|
+
],
|
|
3674
4104
|
"runtimeEvents": []
|
|
3675
4105
|
},
|
|
3676
4106
|
{
|
|
@@ -4284,28 +4714,46 @@
|
|
|
4284
4714
|
{
|
|
4285
4715
|
"apiReference": [
|
|
4286
4716
|
{
|
|
4287
|
-
"attribute": "
|
|
4717
|
+
"attribute": "items",
|
|
4288
4718
|
"defaultValue": "required",
|
|
4289
|
-
"description": "
|
|
4719
|
+
"description": "Defines the labelled code examples and their stable selection values.",
|
|
4720
|
+
"values": "Array<{ code, label, language?, value }>"
|
|
4721
|
+
},
|
|
4722
|
+
{
|
|
4723
|
+
"attribute": "ariaLabel",
|
|
4724
|
+
"defaultValue": "\"Code examples\"",
|
|
4725
|
+
"description": "Names the tab list for assistive technology.",
|
|
4290
4726
|
"values": "string"
|
|
4291
4727
|
},
|
|
4292
4728
|
{
|
|
4293
|
-
"attribute": "
|
|
4729
|
+
"attribute": "initialValue",
|
|
4730
|
+
"defaultValue": "first item value",
|
|
4731
|
+
"description": "Selects the matching code example before interaction.",
|
|
4732
|
+
"values": "string"
|
|
4733
|
+
},
|
|
4734
|
+
{
|
|
4735
|
+
"attribute": "storageKey",
|
|
4294
4736
|
"defaultValue": "-",
|
|
4295
|
-
"description": "
|
|
4737
|
+
"description": "Persists selection and synchronizes CodeTabs instances that share this key.",
|
|
4296
4738
|
"values": "string"
|
|
4297
4739
|
},
|
|
4298
4740
|
{
|
|
4299
|
-
"attribute": "
|
|
4300
|
-
"defaultValue": "
|
|
4301
|
-
"description": "
|
|
4302
|
-
"values": "
|
|
4741
|
+
"attribute": "copy",
|
|
4742
|
+
"defaultValue": "true",
|
|
4743
|
+
"description": "Shows a copy button for each code example.",
|
|
4744
|
+
"values": "boolean"
|
|
4303
4745
|
},
|
|
4304
4746
|
{
|
|
4305
|
-
"attribute": "
|
|
4306
|
-
"defaultValue": "\"
|
|
4307
|
-
"description": "
|
|
4308
|
-
"values": "
|
|
4747
|
+
"attribute": "theme",
|
|
4748
|
+
"defaultValue": "\"auto\"",
|
|
4749
|
+
"description": "Selects the code palette family.",
|
|
4750
|
+
"values": "\"auto\" | \"lumen\" | \"santi020k\""
|
|
4751
|
+
},
|
|
4752
|
+
{
|
|
4753
|
+
"attribute": "wrap",
|
|
4754
|
+
"defaultValue": "true",
|
|
4755
|
+
"description": "Wraps long code lines instead of requiring horizontal scrolling.",
|
|
4756
|
+
"values": "boolean"
|
|
4309
4757
|
},
|
|
4310
4758
|
{
|
|
4311
4759
|
"attribute": "class, className",
|
|
@@ -4320,18 +4768,20 @@
|
|
|
4320
4768
|
"values": "HTML attributes"
|
|
4321
4769
|
}
|
|
4322
4770
|
],
|
|
4323
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\
|
|
4324
|
-
"category": "
|
|
4325
|
-
"collections": [
|
|
4326
|
-
"Selection controls"
|
|
4327
|
-
],
|
|
4771
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Code from './Code.astro'\nimport Tabs from './Tabs.astro'\n\ntype CodeTheme = 'auto' | 'lumen' | 'santi020k'\n\nexport interface CodeTabItem {\n code: string\n label: string\n language?: string\n value: string\n}\n\ninterface Props extends HTMLAttributes<'div'> {\n ariaLabel?: string\n class?: string | null\n className?: string\n copy?: boolean\n initialValue?: string\n items: readonly CodeTabItem[]\n storageKey?: string\n theme?: CodeTheme\n wrap?: boolean\n}\n\nconst {\n ariaLabel = 'Code examples',\n class: classProp = '',\n className = '',\n copy = true,\n initialValue,\n items,\n storageKey,\n theme = 'auto',\n wrap = true,\n ...rest\n} = Astro.props\n\nconst selectedValue = initialValue ?? items[0]?.value\nconst tabsStateProps = {\n ...(selectedValue === undefined ? {} : { initialValue: selectedValue }),\n ...(storageKey === undefined ? {} : { storageKey })\n}\nconst { classList, passthrough } = resolveLumenAstroProps(\n rest,\n ['ui-code-tabs'],\n classProp ?? '',\n className\n)\n---\n\n<Tabs\n class:list={classList}\n {...tabsStateProps}\n {...passthrough}\n>\n <div class=\"ui-code-tabs__list\" role=\"tablist\" aria-label={ariaLabel}>\n {items.map(item => (\n <button\n aria-selected={item.value === selectedValue ? 'true' : 'false'}\n class=\"ui-code-tabs__tab\"\n data-value={item.value}\n role=\"tab\"\n type=\"button\"\n >\n {item.label}\n </button>\n ))}\n </div>\n\n {items.map(item => (\n <div\n class=\"ui-code-tabs__panel\"\n data-value={item.value}\n hidden={item.value !== selectedValue}\n role=\"tabpanel\"\n >\n <Code\n code={item.code}\n copy={copy}\n {...(item.language === undefined ? {} : { language: item.language })}\n theme={theme}\n variant=\"block\"\n wrap={wrap}\n />\n </div>\n ))}\n</Tabs>\n",
|
|
4772
|
+
"category": "Data display",
|
|
4773
|
+
"collections": [],
|
|
4328
4774
|
"dependencies": [
|
|
4775
|
+
"Code",
|
|
4776
|
+
"Tabs",
|
|
4329
4777
|
"styles",
|
|
4330
4778
|
"runtime"
|
|
4331
4779
|
],
|
|
4332
|
-
"description": "
|
|
4780
|
+
"description": "Groups related code examples into accessible, persistent tabs.",
|
|
4333
4781
|
"files": [
|
|
4334
|
-
"packages/astro/components/
|
|
4782
|
+
"packages/astro/components/CodeTabs.astro",
|
|
4783
|
+
"packages/astro/components/Code.astro",
|
|
4784
|
+
"packages/astro/components/Tabs.astro",
|
|
4335
4785
|
"packages/astro/styles/lumen.css",
|
|
4336
4786
|
"packages/astro/runtime/UIPrimitives.astro"
|
|
4337
4787
|
],
|
|
@@ -4342,11 +4792,16 @@
|
|
|
4342
4792
|
"mode": "runtime",
|
|
4343
4793
|
"setup": "Mount UIPrimitives once in the application's root layout; do not mount it beside each component."
|
|
4344
4794
|
},
|
|
4345
|
-
"example": "<
|
|
4346
|
-
"importStatement": "import {
|
|
4795
|
+
"example": "<CodeTabs ariaLabel=\"Package manager\" items={[{ value: \"pnpm\", label: \"pnpm\", code: \"pnpm add @santi020k/lumen-astro\", language: \"bash\" }, { value: \"npm\", label: \"npm\", code: \"npm install @santi020k/lumen-astro\", language: \"bash\" }]} storageKey=\"preferred-package-manager\" />",
|
|
4796
|
+
"importStatement": "import { CodeTabs } from '@santi020k/lumen-astro'",
|
|
4347
4797
|
"language": "astro",
|
|
4348
4798
|
"packageName": "@santi020k/lumen-astro",
|
|
4349
4799
|
"props": [
|
|
4800
|
+
{
|
|
4801
|
+
"name": "ariaLabel",
|
|
4802
|
+
"optional": true,
|
|
4803
|
+
"type": "string"
|
|
4804
|
+
},
|
|
4350
4805
|
{
|
|
4351
4806
|
"name": "class",
|
|
4352
4807
|
"optional": true,
|
|
@@ -4358,32 +4813,50 @@
|
|
|
4358
4813
|
"type": "string"
|
|
4359
4814
|
},
|
|
4360
4815
|
{
|
|
4361
|
-
"name": "
|
|
4816
|
+
"name": "copy",
|
|
4817
|
+
"optional": true,
|
|
4818
|
+
"type": "boolean"
|
|
4819
|
+
},
|
|
4820
|
+
{
|
|
4821
|
+
"name": "initialValue",
|
|
4362
4822
|
"optional": true,
|
|
4363
4823
|
"type": "string"
|
|
4364
4824
|
},
|
|
4365
4825
|
{
|
|
4366
|
-
"name": "
|
|
4826
|
+
"name": "items",
|
|
4367
4827
|
"optional": false,
|
|
4828
|
+
"type": "readonly CodeTabItem[]"
|
|
4829
|
+
},
|
|
4830
|
+
{
|
|
4831
|
+
"name": "storageKey",
|
|
4832
|
+
"optional": true,
|
|
4368
4833
|
"type": "string"
|
|
4369
4834
|
},
|
|
4370
4835
|
{
|
|
4371
|
-
"name": "
|
|
4836
|
+
"name": "theme",
|
|
4372
4837
|
"optional": true,
|
|
4373
|
-
"type": "
|
|
4838
|
+
"type": "CodeTheme"
|
|
4839
|
+
},
|
|
4840
|
+
{
|
|
4841
|
+
"name": "wrap",
|
|
4842
|
+
"optional": true,
|
|
4843
|
+
"type": "boolean"
|
|
4374
4844
|
}
|
|
4375
4845
|
],
|
|
4376
|
-
"propsExtends": "HTMLAttributes<'
|
|
4377
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\
|
|
4846
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
4847
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Code from './Code.astro'\nimport Tabs from './Tabs.astro'\n\ntype CodeTheme = 'auto' | 'lumen' | 'santi020k'\n\nexport interface CodeTabItem {\n code: string\n label: string\n language?: string\n value: string\n}\n\ninterface Props extends HTMLAttributes<'div'> {\n ariaLabel?: string\n class?: string | null\n className?: string\n copy?: boolean\n initialValue?: string\n items: readonly CodeTabItem[]\n storageKey?: string\n theme?: CodeTheme\n wrap?: boolean\n}\n\nconst {\n ariaLabel = 'Code examples',\n class: classProp = '',\n className = '',\n copy = true,\n initialValue,\n items,\n storageKey,\n theme = 'auto',\n wrap = true,\n ...rest\n} = Astro.props\n\nconst selectedValue = initialValue ?? items[0]?.value\nconst tabsStateProps = {\n ...(selectedValue === undefined ? {} : { initialValue: selectedValue }),\n ...(storageKey === undefined ? {} : { storageKey })\n}\nconst { classList, passthrough } = resolveLumenAstroProps(\n rest,\n ['ui-code-tabs'],\n classProp ?? '',\n className\n)\n---\n\n<Tabs\n class:list={classList}\n {...tabsStateProps}\n {...passthrough}\n>\n <div class=\"ui-code-tabs__list\" role=\"tablist\" aria-label={ariaLabel}>\n {items.map(item => (\n <button\n aria-selected={item.value === selectedValue ? 'true' : 'false'}\n class=\"ui-code-tabs__tab\"\n data-value={item.value}\n role=\"tab\"\n type=\"button\"\n >\n {item.label}\n </button>\n ))}\n </div>\n\n {items.map(item => (\n <div\n class=\"ui-code-tabs__panel\"\n data-value={item.value}\n hidden={item.value !== selectedValue}\n role=\"tabpanel\"\n >\n <Code\n code={item.code}\n copy={copy}\n {...(item.language === undefined ? {} : { language: item.language })}\n theme={theme}\n variant=\"block\"\n wrap={wrap}\n />\n </div>\n ))}\n</Tabs>\n",
|
|
4378
4848
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
4379
4849
|
},
|
|
4380
4850
|
"elements": {
|
|
4381
4851
|
"attributes": [
|
|
4382
|
-
"data-ui-
|
|
4383
|
-
"
|
|
4384
|
-
"
|
|
4385
|
-
"
|
|
4386
|
-
"
|
|
4852
|
+
"data-ui-tabs",
|
|
4853
|
+
"items",
|
|
4854
|
+
"ariaLabel",
|
|
4855
|
+
"initialValue",
|
|
4856
|
+
"storageKey",
|
|
4857
|
+
"copy",
|
|
4858
|
+
"theme",
|
|
4859
|
+
"wrap",
|
|
4387
4860
|
"class, className",
|
|
4388
4861
|
"...native attributes"
|
|
4389
4862
|
],
|
|
@@ -4392,16 +4865,16 @@
|
|
|
4392
4865
|
"mode": "registration",
|
|
4393
4866
|
"setup": "Call defineLumenElements() once before rendering Lumen custom elements. Registration includes this component’s interactive behavior."
|
|
4394
4867
|
},
|
|
4395
|
-
"example": "<lumen-
|
|
4868
|
+
"example": "<lumen-code-tabs></lumen-code-tabs>",
|
|
4396
4869
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
4397
4870
|
"language": "html",
|
|
4398
4871
|
"packageName": "@santi020k/lumen-elements",
|
|
4399
4872
|
"props": [],
|
|
4400
4873
|
"propsExtends": "HTMLElement attributes",
|
|
4401
4874
|
"registration": "defineLumenElements()",
|
|
4402
|
-
"source": "
|
|
4875
|
+
"source": "CodeTabs: {\n baseClassName: 'ui-code-tabs',\n defaults: { 'data-ui-tabs': '' },\n tagName: 'lumen-code-tabs'\n }",
|
|
4403
4876
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
4404
|
-
"tagName": "lumen-
|
|
4877
|
+
"tagName": "lumen-code-tabs"
|
|
4405
4878
|
},
|
|
4406
4879
|
"react": {
|
|
4407
4880
|
"available": true,
|
|
@@ -4409,34 +4882,49 @@
|
|
|
4409
4882
|
"mode": "built-in",
|
|
4410
4883
|
"setup": "Interactive behavior is implemented by the React component; do not mount Astro UIPrimitives."
|
|
4411
4884
|
},
|
|
4412
|
-
"example": "<
|
|
4413
|
-
"importStatement": "import {
|
|
4885
|
+
"example": "<CodeTabs ariaLabel=\"Package manager\" items={[{ value: \"pnpm\", label: \"pnpm\", code: \"pnpm add @santi020k/lumen-astro\", language: \"bash\" }, { value: \"npm\", label: \"npm\", code: \"npm install @santi020k/lumen-astro\", language: \"bash\" }]} storageKey=\"preferred-package-manager\" />",
|
|
4886
|
+
"importStatement": "import { CodeTabs } from '@santi020k/lumen-react'",
|
|
4414
4887
|
"language": "tsx",
|
|
4415
4888
|
"packageName": "@santi020k/lumen-react",
|
|
4416
4889
|
"props": [
|
|
4417
4890
|
{
|
|
4418
|
-
"name": "
|
|
4891
|
+
"name": "ariaLabel",
|
|
4419
4892
|
"optional": true,
|
|
4420
|
-
"type": "
|
|
4893
|
+
"type": "string"
|
|
4421
4894
|
},
|
|
4422
4895
|
{
|
|
4423
|
-
"name": "
|
|
4424
|
-
"optional":
|
|
4896
|
+
"name": "copy",
|
|
4897
|
+
"optional": true,
|
|
4898
|
+
"type": "boolean"
|
|
4899
|
+
},
|
|
4900
|
+
{
|
|
4901
|
+
"name": "initialValue",
|
|
4902
|
+
"optional": true,
|
|
4425
4903
|
"type": "string"
|
|
4426
4904
|
},
|
|
4427
4905
|
{
|
|
4428
|
-
"name": "
|
|
4906
|
+
"name": "items",
|
|
4429
4907
|
"optional": true,
|
|
4430
|
-
"type": "
|
|
4908
|
+
"type": "readonly CodeTabItem[]"
|
|
4431
4909
|
},
|
|
4432
4910
|
{
|
|
4433
|
-
"name": "
|
|
4911
|
+
"name": "storageKey",
|
|
4434
4912
|
"optional": true,
|
|
4435
4913
|
"type": "string"
|
|
4914
|
+
},
|
|
4915
|
+
{
|
|
4916
|
+
"name": "theme",
|
|
4917
|
+
"optional": true,
|
|
4918
|
+
"type": "CodeTheme"
|
|
4919
|
+
},
|
|
4920
|
+
{
|
|
4921
|
+
"name": "wrap",
|
|
4922
|
+
"optional": true,
|
|
4923
|
+
"type": "boolean"
|
|
4436
4924
|
}
|
|
4437
4925
|
],
|
|
4438
|
-
"propsExtends": "ComponentPropsWithoutRef<'
|
|
4439
|
-
"source": "export interface
|
|
4926
|
+
"propsExtends": "Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'defaultValue'>",
|
|
4927
|
+
"source": "export interface CodeTabsProps extends Omit<ComponentPropsWithoutRef<'div'>, 'children' | 'defaultValue'> {\n ariaLabel?: string\n copy?: boolean\n initialValue?: string\n items?: readonly CodeTabItem[]\n storageKey?: string\n theme?: CodeTheme\n wrap?: boolean\n}\n\nexport const CodeTabs = ({\n ariaLabel = 'Code examples',\n className,\n copy = true,\n initialValue,\n items = emptyCodeTabItems,\n storageKey,\n theme = 'auto',\n wrap = true,\n ...props\n}: CodeTabsProps) => {\n const selectedValue = initialValue ?? items[0]?.value\n\n const [value, setValue] = useState(() => {\n let storedValue: string | null = null\n\n if (storageKey && typeof localStorage !== 'undefined') {\n try {\n storedValue = localStorage.getItem(storageKey)\n } catch {\n // Storage can be unavailable in privacy modes; tab selection should still work.\n }\n }\n\n return storedValue && items.some(item => item.value === storedValue)\n ? storedValue\n : (selectedValue ?? '')\n })\n\n useEffect(() => {\n const synchronize = (event: Event) => {\n const detail = (event as CustomEvent<{ storageKey?: string; value?: string }>).detail\n\n if (\n storageKey &&\n detail.storageKey === storageKey &&\n detail.value &&\n items.some(item => item.value === detail.value)\n ) {\n setValue(detail.value)\n }\n }\n\n document.addEventListener('ui:tabs-change', synchronize)\n\n return () => {\n document.removeEventListener('ui:tabs-change', synchronize)\n }\n }, [items, storageKey])\n\n const selectValue = (nextValue: string) => {\n setValue(nextValue)\n\n if (storageKey) {\n try {\n localStorage.setItem(storageKey, nextValue)\n } catch {\n // Storage can be unavailable in privacy modes; tab selection should still work.\n }\n }\n\n document.dispatchEvent(new CustomEvent('ui:tabs-change', {\n detail: { storageKey, value: nextValue }\n }))\n }\n\n return (\n <Tabs\n className={composeClassName('ui-code-tabs', className)}\n data-storage-key={storageKey}\n onValueChange={selectValue}\n value={value}\n {...props}\n >\n <TabsList aria-label={ariaLabel} className=\"ui-code-tabs__list\">\n {items.map(item => (\n <TabsTrigger className=\"ui-code-tabs__tab\" key={item.value} value={item.value}>\n {item.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {items.map(item => (\n <TabsPanel className=\"ui-code-tabs__panel\" key={item.value} value={item.value}>\n <Code\n code={item.code}\n copy={copy}\n {...(item.language === undefined ? {} : { language: item.language })}\n theme={theme}\n variant=\"block\"\n wrap={wrap}\n />\n </TabsPanel>\n ))}\n </Tabs>\n )\n}",
|
|
4440
4928
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
4441
4929
|
}
|
|
4442
4930
|
},
|
|
@@ -4445,80 +4933,46 @@
|
|
|
4445
4933
|
"elements": true,
|
|
4446
4934
|
"react": true
|
|
4447
4935
|
},
|
|
4448
|
-
"guidance":
|
|
4449
|
-
|
|
4450
|
-
"distinction": "Use Select for selection without text search or Autocomplete when free-form values are allowed."
|
|
4451
|
-
},
|
|
4452
|
-
"kebab": "combobox",
|
|
4936
|
+
"guidance": null,
|
|
4937
|
+
"kebab": "code-tabs",
|
|
4453
4938
|
"keyboardInteractions": [
|
|
4454
4939
|
{
|
|
4455
|
-
"action": "
|
|
4456
|
-
"key": "
|
|
4457
|
-
},
|
|
4458
|
-
{
|
|
4459
|
-
"action": "Open the listbox and move focus to the first or last visible option.",
|
|
4460
|
-
"key": "ArrowDown, ArrowUp in input"
|
|
4461
|
-
},
|
|
4462
|
-
{
|
|
4463
|
-
"action": "Select the first visible option.",
|
|
4464
|
-
"key": "Enter in input"
|
|
4465
|
-
},
|
|
4466
|
-
{
|
|
4467
|
-
"action": "Select the focused option.",
|
|
4468
|
-
"key": "Enter, Space on an option"
|
|
4940
|
+
"action": "Activate and focus the next code example, wrapping at the end.",
|
|
4941
|
+
"key": "ArrowRight"
|
|
4469
4942
|
},
|
|
4470
4943
|
{
|
|
4471
|
-
"action": "
|
|
4472
|
-
"key": "
|
|
4944
|
+
"action": "Activate and focus the previous code example, wrapping at the start.",
|
|
4945
|
+
"key": "ArrowLeft"
|
|
4473
4946
|
},
|
|
4474
4947
|
{
|
|
4475
|
-
"action": "
|
|
4476
|
-
"key": "Home, End
|
|
4948
|
+
"action": "Activate and focus the first or last code example.",
|
|
4949
|
+
"key": "Home, End"
|
|
4477
4950
|
}
|
|
4478
4951
|
],
|
|
4479
4952
|
"keywords": [
|
|
4480
|
-
"
|
|
4481
|
-
"
|
|
4482
|
-
"
|
|
4483
|
-
"
|
|
4484
|
-
"
|
|
4485
|
-
"
|
|
4486
|
-
"
|
|
4487
|
-
"
|
|
4488
|
-
"
|
|
4489
|
-
"
|
|
4490
|
-
"
|
|
4491
|
-
"custom",
|
|
4492
|
-
"entry",
|
|
4493
|
-
"for",
|
|
4494
|
-
"form",
|
|
4495
|
-
"forms",
|
|
4496
|
-
"free",
|
|
4497
|
-
"from",
|
|
4498
|
-
"grouped",
|
|
4499
|
-
"hierarchical",
|
|
4500
|
-
"list",
|
|
4501
|
-
"native",
|
|
4502
|
-
"need",
|
|
4503
|
-
"option",
|
|
4504
|
-
"options",
|
|
4505
|
-
"patterns",
|
|
4506
|
-
"people",
|
|
4507
|
-
"search",
|
|
4508
|
-
"select",
|
|
4509
|
-
"selection",
|
|
4510
|
-
"text",
|
|
4511
|
-
"use",
|
|
4512
|
-
"values",
|
|
4513
|
-
"when",
|
|
4514
|
-
"without"
|
|
4953
|
+
"accessible",
|
|
4954
|
+
"code",
|
|
4955
|
+
"codetabs",
|
|
4956
|
+
"data",
|
|
4957
|
+
"display",
|
|
4958
|
+
"examples",
|
|
4959
|
+
"groups",
|
|
4960
|
+
"into",
|
|
4961
|
+
"persistent",
|
|
4962
|
+
"related",
|
|
4963
|
+
"tabs"
|
|
4515
4964
|
],
|
|
4516
|
-
"name": "
|
|
4965
|
+
"name": "CodeTabs",
|
|
4517
4966
|
"props": [
|
|
4518
4967
|
{
|
|
4519
|
-
"name": "
|
|
4968
|
+
"name": "ariaLabel",
|
|
4520
4969
|
"optional": true,
|
|
4521
|
-
"type": "string
|
|
4970
|
+
"type": "string"
|
|
4971
|
+
},
|
|
4972
|
+
{
|
|
4973
|
+
"name": "class",
|
|
4974
|
+
"optional": true,
|
|
4975
|
+
"type": "string | null"
|
|
4522
4976
|
},
|
|
4523
4977
|
{
|
|
4524
4978
|
"name": "className",
|
|
@@ -4526,38 +4980,65 @@
|
|
|
4526
4980
|
"type": "string"
|
|
4527
4981
|
},
|
|
4528
4982
|
{
|
|
4529
|
-
"name": "
|
|
4983
|
+
"name": "copy",
|
|
4984
|
+
"optional": true,
|
|
4985
|
+
"type": "boolean"
|
|
4986
|
+
},
|
|
4987
|
+
{
|
|
4988
|
+
"name": "initialValue",
|
|
4530
4989
|
"optional": true,
|
|
4531
4990
|
"type": "string"
|
|
4532
4991
|
},
|
|
4533
4992
|
{
|
|
4534
|
-
"name": "
|
|
4993
|
+
"name": "items",
|
|
4535
4994
|
"optional": false,
|
|
4995
|
+
"type": "readonly CodeTabItem[]"
|
|
4996
|
+
},
|
|
4997
|
+
{
|
|
4998
|
+
"name": "storageKey",
|
|
4999
|
+
"optional": true,
|
|
4536
5000
|
"type": "string"
|
|
4537
5001
|
},
|
|
4538
5002
|
{
|
|
4539
|
-
"name": "
|
|
5003
|
+
"name": "theme",
|
|
4540
5004
|
"optional": true,
|
|
4541
|
-
"type": "
|
|
5005
|
+
"type": "CodeTheme"
|
|
5006
|
+
},
|
|
5007
|
+
{
|
|
5008
|
+
"name": "wrap",
|
|
5009
|
+
"optional": true,
|
|
5010
|
+
"type": "boolean"
|
|
4542
5011
|
}
|
|
4543
5012
|
],
|
|
4544
|
-
"propsExtends": "HTMLAttributes<'
|
|
5013
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
4545
5014
|
"recipes": [],
|
|
4546
5015
|
"runtimeEvents": []
|
|
4547
5016
|
},
|
|
4548
5017
|
{
|
|
4549
5018
|
"apiReference": [
|
|
4550
5019
|
{
|
|
4551
|
-
"attribute": "
|
|
4552
|
-
"defaultValue": "
|
|
4553
|
-
"description": "
|
|
4554
|
-
"values": "
|
|
5020
|
+
"attribute": "list",
|
|
5021
|
+
"defaultValue": "required",
|
|
5022
|
+
"description": "Sets the id for the generated listbox and connects it to the combobox input.",
|
|
5023
|
+
"values": "string"
|
|
4555
5024
|
},
|
|
4556
5025
|
{
|
|
4557
|
-
"attribute": "
|
|
5026
|
+
"attribute": "label",
|
|
4558
5027
|
"defaultValue": "-",
|
|
4559
|
-
"description": "
|
|
4560
|
-
"values": "
|
|
5028
|
+
"description": "Adds a visible label above the input.",
|
|
5029
|
+
"values": "string"
|
|
5030
|
+
},
|
|
5031
|
+
{
|
|
5032
|
+
"attribute": "options",
|
|
5033
|
+
"defaultValue": "[]",
|
|
5034
|
+
"description": "Creates selectable listbox options from strings or value/label objects.",
|
|
5035
|
+
"values": "Array<string | { label, value, disabled? }>"
|
|
5036
|
+
},
|
|
5037
|
+
{
|
|
5038
|
+
"attribute": "type",
|
|
5039
|
+
"defaultValue": "\"text\"",
|
|
5040
|
+
"description": "Sets the native input type.",
|
|
5041
|
+
"values": "HTML input type"
|
|
4561
5042
|
},
|
|
4562
5043
|
{
|
|
4563
5044
|
"attribute": "class, className",
|
|
@@ -4572,20 +5053,18 @@
|
|
|
4572
5053
|
"values": "HTML attributes"
|
|
4573
5054
|
}
|
|
4574
5055
|
],
|
|
4575
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'
|
|
4576
|
-
"category": "
|
|
5056
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'input'> {\n class?: string | null\n className?: string\n label?: string\n list: string\n options?: ComboboxOption[]\n}\n\ninterface Option {\n disabled?: boolean\n label: string\n value: string\n}\n\ntype ComboboxOption = Option | string\n\nconst {\n class: classProp = '',\n className = '',\n id,\n label,\n list,\n options = [],\n type = 'text',\n ...rest\n} = Astro.props\n\nconst inputId = id ?? `${list}-input`\nconst normalizedOptions = options.map(option =>\n typeof option === 'string' ? { label: option, value: option } : option\n)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, ['ui-combobox'\n], classProp, className)\n---\n\n<div class:list={classList} data-ui-combobox>\n {label && <label class=\"ui-label\" for={inputId}>{label}</label>}\n <input\n aria-autocomplete=\"list\"\n aria-controls={list}\n aria-expanded=\"false\"\n class=\"ui-input\"\n id={inputId}\n role=\"combobox\"\n type={type}\n {...passthrough}\n />\n <div class=\"ui-combobox__list\" hidden id={list} role=\"listbox\">\n {normalizedOptions.map(option => (\n <button\n aria-disabled={option.disabled ? 'true' : undefined}\n data-ui-combobox-option\n data-value={option.value}\n disabled={option.disabled}\n role=\"option\"\n type=\"button\"\n >\n {option.label}\n </button>\n ))}\n </div>\n</div>\n",
|
|
5057
|
+
"category": "Forms",
|
|
4577
5058
|
"collections": [
|
|
4578
|
-
"
|
|
5059
|
+
"Selection controls"
|
|
4579
5060
|
],
|
|
4580
5061
|
"dependencies": [
|
|
4581
|
-
"Input",
|
|
4582
5062
|
"styles",
|
|
4583
5063
|
"runtime"
|
|
4584
5064
|
],
|
|
4585
|
-
"description": "
|
|
5065
|
+
"description": "Combines text entry and option selection.",
|
|
4586
5066
|
"files": [
|
|
4587
|
-
"packages/astro/components/
|
|
4588
|
-
"packages/astro/components/Command.astro",
|
|
5067
|
+
"packages/astro/components/Combobox.astro",
|
|
4589
5068
|
"packages/astro/styles/lumen.css",
|
|
4590
5069
|
"packages/astro/runtime/UIPrimitives.astro"
|
|
4591
5070
|
],
|
|
@@ -4596,8 +5075,8 @@
|
|
|
4596
5075
|
"mode": "runtime",
|
|
4597
5076
|
"setup": "Mount UIPrimitives once in the application's root layout; do not mount it beside each component."
|
|
4598
5077
|
},
|
|
4599
|
-
"example": "<
|
|
4600
|
-
"importStatement": "import {
|
|
5078
|
+
"example": "<Combobox label=\"Framework\" list=\"framework-options\" options={[\"Astro\", { label: \"React\", value: \"react\" }, { label: \"Vue\", value: \"vue\", disabled: true }]} placeholder=\"Search package\" />",
|
|
5079
|
+
"importStatement": "import { Combobox } from '@santi020k/lumen-astro'",
|
|
4601
5080
|
"language": "astro",
|
|
4602
5081
|
"packageName": "@santi020k/lumen-astro",
|
|
4603
5082
|
"props": [
|
|
@@ -4612,20 +5091,32 @@
|
|
|
4612
5091
|
"type": "string"
|
|
4613
5092
|
},
|
|
4614
5093
|
{
|
|
4615
|
-
"name": "
|
|
5094
|
+
"name": "label",
|
|
4616
5095
|
"optional": true,
|
|
4617
|
-
"type": "
|
|
5096
|
+
"type": "string"
|
|
5097
|
+
},
|
|
5098
|
+
{
|
|
5099
|
+
"name": "list",
|
|
5100
|
+
"optional": false,
|
|
5101
|
+
"type": "string"
|
|
5102
|
+
},
|
|
5103
|
+
{
|
|
5104
|
+
"name": "options",
|
|
5105
|
+
"optional": true,
|
|
5106
|
+
"type": "ComboboxOption[]"
|
|
4618
5107
|
}
|
|
4619
5108
|
],
|
|
4620
|
-
"propsExtends": "HTMLAttributes<'
|
|
4621
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'
|
|
5109
|
+
"propsExtends": "HTMLAttributes<'input'>",
|
|
5110
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'input'> {\n class?: string | null\n className?: string\n label?: string\n list: string\n options?: ComboboxOption[]\n}\n\ninterface Option {\n disabled?: boolean\n label: string\n value: string\n}\n\ntype ComboboxOption = Option | string\n\nconst {\n class: classProp = '',\n className = '',\n id,\n label,\n list,\n options = [],\n type = 'text',\n ...rest\n} = Astro.props\n\nconst inputId = id ?? `${list}-input`\nconst normalizedOptions = options.map(option =>\n typeof option === 'string' ? { label: option, value: option } : option\n)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, ['ui-combobox'\n], classProp, className)\n---\n\n<div class:list={classList} data-ui-combobox>\n {label && <label class=\"ui-label\" for={inputId}>{label}</label>}\n <input\n aria-autocomplete=\"list\"\n aria-controls={list}\n aria-expanded=\"false\"\n class=\"ui-input\"\n id={inputId}\n role=\"combobox\"\n type={type}\n {...passthrough}\n />\n <div class=\"ui-combobox__list\" hidden id={list} role=\"listbox\">\n {normalizedOptions.map(option => (\n <button\n aria-disabled={option.disabled ? 'true' : undefined}\n data-ui-combobox-option\n data-value={option.value}\n disabled={option.disabled}\n role=\"option\"\n type=\"button\"\n >\n {option.label}\n </button>\n ))}\n </div>\n</div>\n",
|
|
4622
5111
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
4623
5112
|
},
|
|
4624
5113
|
"elements": {
|
|
4625
5114
|
"attributes": [
|
|
4626
|
-
"data-ui-
|
|
4627
|
-
"
|
|
4628
|
-
"
|
|
5115
|
+
"data-ui-combobox",
|
|
5116
|
+
"list",
|
|
5117
|
+
"label",
|
|
5118
|
+
"options",
|
|
5119
|
+
"type",
|
|
4629
5120
|
"class, className",
|
|
4630
5121
|
"...native attributes"
|
|
4631
5122
|
],
|
|
@@ -4634,36 +5125,51 @@
|
|
|
4634
5125
|
"mode": "registration",
|
|
4635
5126
|
"setup": "Call defineLumenElements() once before rendering Lumen custom elements. Registration includes this component’s interactive behavior."
|
|
4636
5127
|
},
|
|
4637
|
-
"example": "<lumen-
|
|
5128
|
+
"example": "<lumen-combobox></lumen-combobox>",
|
|
4638
5129
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
4639
5130
|
"language": "html",
|
|
4640
5131
|
"packageName": "@santi020k/lumen-elements",
|
|
4641
5132
|
"props": [],
|
|
4642
5133
|
"propsExtends": "HTMLElement attributes",
|
|
4643
5134
|
"registration": "defineLumenElements()",
|
|
4644
|
-
"source": "
|
|
5135
|
+
"source": "Combobox: { baseClassName: 'ui-combobox', defaults: { 'data-ui-combobox': '' }, tagName: 'lumen-combobox' }",
|
|
4645
5136
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
4646
|
-
"tagName": "lumen-
|
|
5137
|
+
"tagName": "lumen-combobox"
|
|
4647
5138
|
},
|
|
4648
5139
|
"react": {
|
|
4649
5140
|
"available": true,
|
|
4650
5141
|
"behavior": {
|
|
4651
|
-
"mode": "
|
|
4652
|
-
"setup": "
|
|
5142
|
+
"mode": "built-in",
|
|
5143
|
+
"setup": "Interactive behavior is implemented by the React component; do not mount Astro UIPrimitives."
|
|
4653
5144
|
},
|
|
4654
|
-
"example": "<
|
|
4655
|
-
"importStatement": "import {
|
|
5145
|
+
"example": "<Combobox label=\"Framework\" list=\"framework-options\" options={[\"Astro\", \"React\", \"Vue\"]} placeholder=\"Search package\" />",
|
|
5146
|
+
"importStatement": "import { Combobox } from '@santi020k/lumen-react'",
|
|
4656
5147
|
"language": "tsx",
|
|
4657
5148
|
"packageName": "@santi020k/lumen-react",
|
|
4658
5149
|
"props": [
|
|
4659
5150
|
{
|
|
4660
|
-
"name": "
|
|
5151
|
+
"name": "label",
|
|
4661
5152
|
"optional": true,
|
|
4662
|
-
"type": "
|
|
5153
|
+
"type": "ReactNode"
|
|
5154
|
+
},
|
|
5155
|
+
{
|
|
5156
|
+
"name": "list",
|
|
5157
|
+
"optional": false,
|
|
5158
|
+
"type": "string"
|
|
5159
|
+
},
|
|
5160
|
+
{
|
|
5161
|
+
"name": "options",
|
|
5162
|
+
"optional": true,
|
|
5163
|
+
"type": "string[]"
|
|
5164
|
+
},
|
|
5165
|
+
{
|
|
5166
|
+
"name": "wrapperClassName",
|
|
5167
|
+
"optional": true,
|
|
5168
|
+
"type": "string"
|
|
4663
5169
|
}
|
|
4664
5170
|
],
|
|
4665
|
-
"propsExtends": "ComponentPropsWithoutRef<'
|
|
4666
|
-
"source": "export interface
|
|
5171
|
+
"propsExtends": "ComponentPropsWithoutRef<'input'>",
|
|
5172
|
+
"source": "export interface ComboboxProps extends ComponentPropsWithoutRef<'input'> {\n label?: ReactNode\n list: string\n options?: string[]\n wrapperClassName?: string\n}\n\nexport const Combobox = ({\n className,\n defaultValue,\n id,\n label,\n list,\n onBlur,\n onChange,\n onFocus,\n onKeyDown,\n options = emptyStringOptions,\n type = 'text',\n value: valueProp,\n wrapperClassName,\n ...props\n}: ComboboxProps) => {\n const inputId = id ?? `${list}-input`\n const [open, setOpen] = useState(false)\n const [value, setValue] = useState(() => String(defaultValue ?? ''))\n const renderedValue = valueProp ?? value\n const query = String(renderedValue).trim().toLowerCase()\n\n const visibleOptions = useMemo(\n () => options.filter(option => !query || option.toLowerCase().includes(query)),\n [options, query]\n )\n\n const selectOption = (option: string) => {\n if (valueProp === undefined) {\n setValue(option)\n }\n\n setOpen(false)\n }\n\n return (\n <div\n className={composeClassName('ui-combobox', wrapperClassName)}\n data-ui-combobox\n onBlur={event => {\n const nextTarget = event.relatedTarget\n\n if (!nextTarget || !event.currentTarget.contains(nextTarget)) {\n setOpen(false)\n }\n }}\n >\n {label && <label className=\"ui-label\" htmlFor={inputId}>{label}</label>}\n <input\n aria-autocomplete=\"list\"\n aria-controls={list}\n aria-expanded={open}\n className={composeClassName('ui-input', className)}\n id={inputId}\n role=\"combobox\"\n type={type}\n value={renderedValue}\n onBlur={onBlur}\n onChange={event => {\n if (valueProp === undefined) {\n setValue(event.currentTarget.value)\n }\n\n setOpen(true)\n\n onChange?.(event)\n }}\n onFocus={event => {\n setOpen(true)\n\n onFocus?.(event)\n }}\n onKeyDown={event => {\n if (event.key === 'Escape') {\n setOpen(false)\n }\n\n if (event.key === 'Enter' && visibleOptions[0]) {\n event.preventDefault()\n\n selectOption(visibleOptions[0])\n }\n\n onKeyDown?.(event)\n }}\n {...props}\n />\n <div className=\"ui-combobox__list\" hidden={!open} id={list} role=\"listbox\">\n {visibleOptions.map(option => (\n <button\n data-ui-combobox-option\n data-value={option}\n key={option}\n role=\"option\"\n type=\"button\"\n onClick={() => { selectOption(option); }}\n onMouseDown={event => { event.preventDefault(); }}\n >\n {option}\n </button>\n ))}\n </div>\n </div>\n )\n}",
|
|
4667
5173
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
4668
5174
|
}
|
|
4669
5175
|
},
|
|
@@ -4672,27 +5178,75 @@
|
|
|
4672
5178
|
"elements": true,
|
|
4673
5179
|
"react": true
|
|
4674
5180
|
},
|
|
4675
|
-
"guidance":
|
|
4676
|
-
|
|
4677
|
-
|
|
5181
|
+
"guidance": {
|
|
5182
|
+
"when": "Use when people need to search and choose from a controlled list of options.",
|
|
5183
|
+
"distinction": "Use Select for selection without text search or Autocomplete when free-form values are allowed."
|
|
5184
|
+
},
|
|
5185
|
+
"kebab": "combobox",
|
|
5186
|
+
"keyboardInteractions": [
|
|
5187
|
+
{
|
|
5188
|
+
"action": "Close the listbox. Escape on an option also returns focus to the input.",
|
|
5189
|
+
"key": "Escape in input or option"
|
|
5190
|
+
},
|
|
5191
|
+
{
|
|
5192
|
+
"action": "Open the listbox and move focus to the first or last visible option.",
|
|
5193
|
+
"key": "ArrowDown, ArrowUp in input"
|
|
5194
|
+
},
|
|
5195
|
+
{
|
|
5196
|
+
"action": "Select the first visible option.",
|
|
5197
|
+
"key": "Enter in input"
|
|
5198
|
+
},
|
|
5199
|
+
{
|
|
5200
|
+
"action": "Select the focused option.",
|
|
5201
|
+
"key": "Enter, Space on an option"
|
|
5202
|
+
},
|
|
5203
|
+
{
|
|
5204
|
+
"action": "Move focus through visible options, wrapping at the ends.",
|
|
5205
|
+
"key": "ArrowDown, ArrowUp on an option"
|
|
5206
|
+
},
|
|
5207
|
+
{
|
|
5208
|
+
"action": "Move focus to the first or last visible option.",
|
|
5209
|
+
"key": "Home, End on an option"
|
|
5210
|
+
}
|
|
5211
|
+
],
|
|
4678
5212
|
"keywords": [
|
|
4679
|
-
"
|
|
4680
|
-
"actions",
|
|
5213
|
+
"allowed",
|
|
4681
5214
|
"and",
|
|
4682
|
-
"
|
|
4683
|
-
"
|
|
4684
|
-
"
|
|
4685
|
-
"
|
|
4686
|
-
"
|
|
4687
|
-
"
|
|
4688
|
-
"
|
|
4689
|
-
"
|
|
4690
|
-
"
|
|
4691
|
-
"
|
|
4692
|
-
"
|
|
4693
|
-
"
|
|
5215
|
+
"are",
|
|
5216
|
+
"autocomplete",
|
|
5217
|
+
"binary",
|
|
5218
|
+
"choose",
|
|
5219
|
+
"combines",
|
|
5220
|
+
"combobox",
|
|
5221
|
+
"compare",
|
|
5222
|
+
"controlled",
|
|
5223
|
+
"controls",
|
|
5224
|
+
"custom",
|
|
5225
|
+
"entry",
|
|
5226
|
+
"for",
|
|
5227
|
+
"form",
|
|
5228
|
+
"forms",
|
|
5229
|
+
"free",
|
|
5230
|
+
"from",
|
|
5231
|
+
"grouped",
|
|
5232
|
+
"hierarchical",
|
|
5233
|
+
"list",
|
|
5234
|
+
"native",
|
|
5235
|
+
"need",
|
|
5236
|
+
"option",
|
|
5237
|
+
"options",
|
|
5238
|
+
"patterns",
|
|
5239
|
+
"people",
|
|
5240
|
+
"search",
|
|
5241
|
+
"select",
|
|
5242
|
+
"selection",
|
|
5243
|
+
"text",
|
|
5244
|
+
"use",
|
|
5245
|
+
"values",
|
|
5246
|
+
"when",
|
|
5247
|
+
"without"
|
|
4694
5248
|
],
|
|
4695
|
-
"name": "
|
|
5249
|
+
"name": "Combobox",
|
|
4696
5250
|
"props": [
|
|
4697
5251
|
{
|
|
4698
5252
|
"name": "class",
|
|
@@ -4705,18 +5259,23 @@
|
|
|
4705
5259
|
"type": "string"
|
|
4706
5260
|
},
|
|
4707
5261
|
{
|
|
4708
|
-
"name": "
|
|
5262
|
+
"name": "label",
|
|
4709
5263
|
"optional": true,
|
|
4710
|
-
"type": "
|
|
4711
|
-
}
|
|
4712
|
-
],
|
|
4713
|
-
"propsExtends": "HTMLAttributes<'div'>",
|
|
4714
|
-
"recipes": [
|
|
5264
|
+
"type": "string"
|
|
5265
|
+
},
|
|
4715
5266
|
{
|
|
4716
|
-
"name": "
|
|
4717
|
-
"
|
|
5267
|
+
"name": "list",
|
|
5268
|
+
"optional": false,
|
|
5269
|
+
"type": "string"
|
|
5270
|
+
},
|
|
5271
|
+
{
|
|
5272
|
+
"name": "options",
|
|
5273
|
+
"optional": true,
|
|
5274
|
+
"type": "ComboboxOption[]"
|
|
4718
5275
|
}
|
|
4719
5276
|
],
|
|
5277
|
+
"propsExtends": "HTMLAttributes<'input'>",
|
|
5278
|
+
"recipes": [],
|
|
4720
5279
|
"runtimeEvents": []
|
|
4721
5280
|
},
|
|
4722
5281
|
{
|
|
@@ -4728,10 +5287,10 @@
|
|
|
4728
5287
|
"values": "boolean | \"subtle\" | \"strong\""
|
|
4729
5288
|
},
|
|
4730
5289
|
{
|
|
4731
|
-
"attribute": "
|
|
4732
|
-
"defaultValue": "
|
|
4733
|
-
"description": "
|
|
4734
|
-
"values": "
|
|
5290
|
+
"attribute": "data-ui-command-item",
|
|
5291
|
+
"defaultValue": "-",
|
|
5292
|
+
"description": "Marks filterable command items for the runtime.",
|
|
5293
|
+
"values": "boolean attribute"
|
|
4735
5294
|
},
|
|
4736
5295
|
{
|
|
4737
5296
|
"attribute": "class, className",
|
|
@@ -4746,19 +5305,193 @@
|
|
|
4746
5305
|
"values": "HTML attributes"
|
|
4747
5306
|
}
|
|
4748
5307
|
],
|
|
4749
|
-
"astroSource": "---\nimport { resolveLumenAstroProps
|
|
4750
|
-
"category": "
|
|
5308
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-command',\n glass && 'ui-command--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<div\n data-ui-command\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
5309
|
+
"category": "Navigation",
|
|
4751
5310
|
"collections": [
|
|
4752
5311
|
"Menus and commands"
|
|
4753
5312
|
],
|
|
4754
5313
|
"dependencies": [
|
|
5314
|
+
"Input",
|
|
4755
5315
|
"styles",
|
|
4756
5316
|
"runtime"
|
|
4757
5317
|
],
|
|
4758
|
-
"description": "
|
|
5318
|
+
"description": "Builds command palettes and filterable action lists.",
|
|
4759
5319
|
"files": [
|
|
4760
|
-
"packages/astro/components/
|
|
4761
|
-
"packages/astro/
|
|
5320
|
+
"packages/astro/components/Input.astro",
|
|
5321
|
+
"packages/astro/components/Command.astro",
|
|
5322
|
+
"packages/astro/styles/lumen.css",
|
|
5323
|
+
"packages/astro/runtime/UIPrimitives.astro"
|
|
5324
|
+
],
|
|
5325
|
+
"frameworkDetails": {
|
|
5326
|
+
"astro": {
|
|
5327
|
+
"available": true,
|
|
5328
|
+
"behavior": {
|
|
5329
|
+
"mode": "runtime",
|
|
5330
|
+
"setup": "Mount UIPrimitives once in the application's root layout; do not mount it beside each component."
|
|
5331
|
+
},
|
|
5332
|
+
"example": "<Command><Input placeholder=\"Type a command...\" /><button data-ui-command-item>Open docs</button></Command>",
|
|
5333
|
+
"importStatement": "import { Command, Input } from '@santi020k/lumen-astro'",
|
|
5334
|
+
"language": "astro",
|
|
5335
|
+
"packageName": "@santi020k/lumen-astro",
|
|
5336
|
+
"props": [
|
|
5337
|
+
{
|
|
5338
|
+
"name": "class",
|
|
5339
|
+
"optional": true,
|
|
5340
|
+
"type": "string | null"
|
|
5341
|
+
},
|
|
5342
|
+
{
|
|
5343
|
+
"name": "className",
|
|
5344
|
+
"optional": true,
|
|
5345
|
+
"type": "string"
|
|
5346
|
+
},
|
|
5347
|
+
{
|
|
5348
|
+
"name": "glass",
|
|
5349
|
+
"optional": true,
|
|
5350
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
5351
|
+
}
|
|
5352
|
+
],
|
|
5353
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
5354
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-command',\n glass && 'ui-command--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<div\n data-ui-command\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
5355
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
5356
|
+
},
|
|
5357
|
+
"elements": {
|
|
5358
|
+
"attributes": [
|
|
5359
|
+
"data-ui-command",
|
|
5360
|
+
"glass",
|
|
5361
|
+
"data-ui-command-item",
|
|
5362
|
+
"class, className",
|
|
5363
|
+
"...native attributes"
|
|
5364
|
+
],
|
|
5365
|
+
"available": true,
|
|
5366
|
+
"behavior": {
|
|
5367
|
+
"mode": "registration",
|
|
5368
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements. Registration includes this component’s interactive behavior."
|
|
5369
|
+
},
|
|
5370
|
+
"example": "<lumen-command><lumen-input placeholder=\"Type a command...\"></lumen-input><button data-ui-command-item>Open docs</button></lumen-command>",
|
|
5371
|
+
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
5372
|
+
"language": "html",
|
|
5373
|
+
"packageName": "@santi020k/lumen-elements",
|
|
5374
|
+
"props": [],
|
|
5375
|
+
"propsExtends": "HTMLElement attributes",
|
|
5376
|
+
"registration": "defineLumenElements()",
|
|
5377
|
+
"source": "Command: { attributeClasses: glassAttributeClasses('ui-command--glass'), baseClassName: 'ui-command', defaults: { 'data-ui-command': '' }, tagName: 'lumen-command' }",
|
|
5378
|
+
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
5379
|
+
"tagName": "lumen-command"
|
|
5380
|
+
},
|
|
5381
|
+
"react": {
|
|
5382
|
+
"available": true,
|
|
5383
|
+
"behavior": {
|
|
5384
|
+
"mode": "adapter",
|
|
5385
|
+
"setup": "The React component exposes the documented data attributes; app-level state must implement the documented interactive and event behavior. Do not mount Astro UIPrimitives."
|
|
5386
|
+
},
|
|
5387
|
+
"example": "<Command><Input placeholder=\"Type a command...\" /><button data-ui-command-item>Open docs</button></Command>",
|
|
5388
|
+
"importStatement": "import { Command, Input } from '@santi020k/lumen-react'",
|
|
5389
|
+
"language": "tsx",
|
|
5390
|
+
"packageName": "@santi020k/lumen-react",
|
|
5391
|
+
"props": [
|
|
5392
|
+
{
|
|
5393
|
+
"name": "glass",
|
|
5394
|
+
"optional": true,
|
|
5395
|
+
"type": "LumenGlassProp"
|
|
5396
|
+
}
|
|
5397
|
+
],
|
|
5398
|
+
"propsExtends": "ComponentPropsWithoutRef<'div'>",
|
|
5399
|
+
"source": "export interface CommandProps extends ComponentPropsWithoutRef<'div'> {\n glass?: LumenGlassProp\n}\n\nexport const Command = ({ className, glass = false, ...props }: CommandProps) => (\n <div className={composeClassName('ui-command', glassClass('ui-command', glass), className)} data-ui-command {...props} />\n)",
|
|
5400
|
+
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
5401
|
+
}
|
|
5402
|
+
},
|
|
5403
|
+
"frameworks": {
|
|
5404
|
+
"astro": true,
|
|
5405
|
+
"elements": true,
|
|
5406
|
+
"react": true
|
|
5407
|
+
},
|
|
5408
|
+
"guidance": null,
|
|
5409
|
+
"kebab": "command",
|
|
5410
|
+
"keyboardInteractions": [],
|
|
5411
|
+
"keywords": [
|
|
5412
|
+
"action",
|
|
5413
|
+
"actions",
|
|
5414
|
+
"and",
|
|
5415
|
+
"application",
|
|
5416
|
+
"builds",
|
|
5417
|
+
"command",
|
|
5418
|
+
"commands",
|
|
5419
|
+
"contextual",
|
|
5420
|
+
"filterable",
|
|
5421
|
+
"lists",
|
|
5422
|
+
"menus",
|
|
5423
|
+
"navigation",
|
|
5424
|
+
"palettes",
|
|
5425
|
+
"searchable",
|
|
5426
|
+
"use"
|
|
5427
|
+
],
|
|
5428
|
+
"name": "Command",
|
|
5429
|
+
"props": [
|
|
5430
|
+
{
|
|
5431
|
+
"name": "class",
|
|
5432
|
+
"optional": true,
|
|
5433
|
+
"type": "string | null"
|
|
5434
|
+
},
|
|
5435
|
+
{
|
|
5436
|
+
"name": "className",
|
|
5437
|
+
"optional": true,
|
|
5438
|
+
"type": "string"
|
|
5439
|
+
},
|
|
5440
|
+
{
|
|
5441
|
+
"name": "glass",
|
|
5442
|
+
"optional": true,
|
|
5443
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
5444
|
+
}
|
|
5445
|
+
],
|
|
5446
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
5447
|
+
"recipes": [
|
|
5448
|
+
{
|
|
5449
|
+
"name": "data-collections",
|
|
5450
|
+
"type": "recipe"
|
|
5451
|
+
}
|
|
5452
|
+
],
|
|
5453
|
+
"runtimeEvents": []
|
|
5454
|
+
},
|
|
5455
|
+
{
|
|
5456
|
+
"apiReference": [
|
|
5457
|
+
{
|
|
5458
|
+
"attribute": "glass",
|
|
5459
|
+
"defaultValue": "false",
|
|
5460
|
+
"description": "Applies the tokenized liquid-glass surface treatment with backdrop-filter fallbacks; \"subtle\" and \"strong\" adjust the fill intensity.",
|
|
5461
|
+
"values": "boolean | \"subtle\" | \"strong\""
|
|
5462
|
+
},
|
|
5463
|
+
{
|
|
5464
|
+
"attribute": "surface",
|
|
5465
|
+
"defaultValue": "\"default\"",
|
|
5466
|
+
"description": "Deprecated alias for glass; surface=\"glass\" maps to glass={true}.",
|
|
5467
|
+
"values": "\"default\" | \"glass\""
|
|
5468
|
+
},
|
|
5469
|
+
{
|
|
5470
|
+
"attribute": "class, className",
|
|
5471
|
+
"defaultValue": "\"\"",
|
|
5472
|
+
"description": "Merges custom classes with the generated ui-* root classes.",
|
|
5473
|
+
"values": "string"
|
|
5474
|
+
},
|
|
5475
|
+
{
|
|
5476
|
+
"attribute": "...native attributes",
|
|
5477
|
+
"defaultValue": "-",
|
|
5478
|
+
"description": "Forwards standard attributes to the root element unless the component consumes them.",
|
|
5479
|
+
"values": "HTML attributes"
|
|
5480
|
+
}
|
|
5481
|
+
],
|
|
5482
|
+
"astroSource": "---\nimport { resolveLumenAstroProps, resolveLumenGlass } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'menu'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n /**\n * @deprecated Use `glass` instead. `surface=\"glass\"` maps to `glass={true}`.\n */\n surface?: 'default' | 'glass'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n surface = 'default',\n ...rest\n} = Astro.props\n\nconst resolvedGlass = resolveLumenGlass(glass, surface)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-menu',\n resolvedGlass && 'ui-menu--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n{/* Point an element at this menu with data-ui-context-menu-trigger=\"<menu id>\"\n to get right-click / Shift+F10 open behavior from the runtime. Without a\n trigger the menu renders statically. */}\n<menu\n data-surface={resolvedGlass ? 'glass' : 'default'}\n data-ui-context-menu\n role=\"menu\"\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</menu>\n",
|
|
5483
|
+
"category": "Overlays",
|
|
5484
|
+
"collections": [
|
|
5485
|
+
"Menus and commands"
|
|
5486
|
+
],
|
|
5487
|
+
"dependencies": [
|
|
5488
|
+
"styles",
|
|
5489
|
+
"runtime"
|
|
5490
|
+
],
|
|
5491
|
+
"description": "Provides contextual actions for a selected object.",
|
|
5492
|
+
"files": [
|
|
5493
|
+
"packages/astro/components/ContextMenu.astro",
|
|
5494
|
+
"packages/astro/styles/lumen.css",
|
|
4762
5495
|
"packages/astro/runtime/UIPrimitives.astro"
|
|
4763
5496
|
],
|
|
4764
5497
|
"frameworkDetails": {
|
|
@@ -5877,6 +6610,12 @@
|
|
|
5877
6610
|
"description": "Deprecated alias for glass; surface=\"glass\" maps to glass={true}.",
|
|
5878
6611
|
"values": "\"default\" | \"glass\""
|
|
5879
6612
|
},
|
|
6613
|
+
{
|
|
6614
|
+
"attribute": "layout",
|
|
6615
|
+
"defaultValue": "\"centered\"",
|
|
6616
|
+
"description": "Uses the standard centered panel or a viewport-filling native dialog shell.",
|
|
6617
|
+
"values": "\"centered\" | \"fullscreen\""
|
|
6618
|
+
},
|
|
5880
6619
|
{
|
|
5881
6620
|
"attribute": "id",
|
|
5882
6621
|
"defaultValue": "-",
|
|
@@ -5908,7 +6647,7 @@
|
|
|
5908
6647
|
"values": "HTML attributes"
|
|
5909
6648
|
}
|
|
5910
6649
|
],
|
|
5911
|
-
"astroSource": "---\nimport { resolveLumenAstroProps, resolveLumenGlass } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'dialog'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n /**\n * @deprecated Use `glass` instead. `surface=\"glass\"` maps to `glass={true}`.\n */\n surface?: 'default' | 'glass'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n surface = 'default',\n ...rest\n} = Astro.props\n\nconst resolvedGlass = resolveLumenGlass(glass, surface)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-dialog',\n resolvedGlass && 'ui-dialog--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<dialog\n data-surface={resolvedGlass ? 'glass' : 'default'}\n data-ui-dialog\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</dialog>\n",
|
|
6650
|
+
"astroSource": "---\nimport { resolveLumenAstroProps, resolveLumenGlass } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'dialog'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n layout?: 'centered' | 'fullscreen'\n /**\n * @deprecated Use `glass` instead. `surface=\"glass\"` maps to `glass={true}`.\n */\n surface?: 'default' | 'glass'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n layout = 'centered',\n surface = 'default',\n ...rest\n} = Astro.props\n\nconst resolvedGlass = resolveLumenGlass(glass, surface)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-dialog',\n layout === 'fullscreen' && 'ui-dialog--fullscreen',\n resolvedGlass && 'ui-dialog--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<dialog\n data-surface={resolvedGlass ? 'glass' : 'default'}\n data-layout={layout}\n data-ui-dialog\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</dialog>\n",
|
|
5912
6651
|
"category": "Overlays",
|
|
5913
6652
|
"collections": [
|
|
5914
6653
|
"Dialogs and contextual layers"
|
|
@@ -5952,6 +6691,11 @@
|
|
|
5952
6691
|
"optional": true,
|
|
5953
6692
|
"type": "boolean | 'subtle' | 'strong'"
|
|
5954
6693
|
},
|
|
6694
|
+
{
|
|
6695
|
+
"name": "layout",
|
|
6696
|
+
"optional": true,
|
|
6697
|
+
"type": "'centered' | 'fullscreen'"
|
|
6698
|
+
},
|
|
5955
6699
|
{
|
|
5956
6700
|
"name": "surface",
|
|
5957
6701
|
"optional": true,
|
|
@@ -5959,13 +6703,14 @@
|
|
|
5959
6703
|
}
|
|
5960
6704
|
],
|
|
5961
6705
|
"propsExtends": "HTMLAttributes<'dialog'>",
|
|
5962
|
-
"source": "---\nimport { resolveLumenAstroProps, resolveLumenGlass } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'dialog'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n /**\n * @deprecated Use `glass` instead. `surface=\"glass\"` maps to `glass={true}`.\n */\n surface?: 'default' | 'glass'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n surface = 'default',\n ...rest\n} = Astro.props\n\nconst resolvedGlass = resolveLumenGlass(glass, surface)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-dialog',\n resolvedGlass && 'ui-dialog--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<dialog\n data-surface={resolvedGlass ? 'glass' : 'default'}\n data-ui-dialog\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</dialog>\n",
|
|
6706
|
+
"source": "---\nimport { resolveLumenAstroProps, resolveLumenGlass } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'dialog'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n layout?: 'centered' | 'fullscreen'\n /**\n * @deprecated Use `glass` instead. `surface=\"glass\"` maps to `glass={true}`.\n */\n surface?: 'default' | 'glass'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n layout = 'centered',\n surface = 'default',\n ...rest\n} = Astro.props\n\nconst resolvedGlass = resolveLumenGlass(glass, surface)\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-dialog',\n layout === 'fullscreen' && 'ui-dialog--fullscreen',\n resolvedGlass && 'ui-dialog--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<dialog\n data-surface={resolvedGlass ? 'glass' : 'default'}\n data-layout={layout}\n data-ui-dialog\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</dialog>\n",
|
|
5963
6707
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
5964
6708
|
},
|
|
5965
6709
|
"elements": {
|
|
5966
6710
|
"attributes": [
|
|
5967
6711
|
"data-ui-dialog",
|
|
5968
6712
|
"glass",
|
|
6713
|
+
"layout",
|
|
5969
6714
|
"surface",
|
|
5970
6715
|
"id",
|
|
5971
6716
|
"data-ui-dialog-trigger",
|
|
@@ -5985,7 +6730,7 @@
|
|
|
5985
6730
|
"props": [],
|
|
5986
6731
|
"propsExtends": "HTMLElement attributes",
|
|
5987
6732
|
"registration": "defineLumenElements()",
|
|
5988
|
-
"source": "Dialog: {\n attributeClasses: {\n glass: { strong: 'ui-dialog--glass ui-glass-strong', subtle: 'ui-dialog--glass ui-glass-subtle', true: 'ui-dialog--glass' },\n surface: { glass: 'ui-dialog--glass' }\n },\n baseClassName: 'ui-dialog',\n defaults: { 'data-ui-dialog': '', surface: 'default' },\n tagName: 'lumen-dialog'\n }",
|
|
6733
|
+
"source": "Dialog: {\n attributeClasses: {\n glass: { strong: 'ui-dialog--glass ui-glass-strong', subtle: 'ui-dialog--glass ui-glass-subtle', true: 'ui-dialog--glass' },\n layout: { fullscreen: 'ui-dialog--fullscreen' },\n surface: { glass: 'ui-dialog--glass' }\n },\n baseClassName: 'ui-dialog',\n defaults: { 'data-ui-dialog': '', layout: 'centered', surface: 'default' },\n tagName: 'lumen-dialog'\n }",
|
|
5989
6734
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
5990
6735
|
"tagName": "lumen-dialog"
|
|
5991
6736
|
},
|
|
@@ -6083,9 +6828,15 @@
|
|
|
6083
6828
|
"importStatement": "import { Button, Dialog, Card } from '@santi020k/lumen-react'\nimport { useDialog } from '@santi020k/lumen-react'",
|
|
6084
6829
|
"language": "tsx",
|
|
6085
6830
|
"packageName": "@santi020k/lumen-react",
|
|
6086
|
-
"props": [
|
|
6831
|
+
"props": [
|
|
6832
|
+
{
|
|
6833
|
+
"name": "layout",
|
|
6834
|
+
"optional": true,
|
|
6835
|
+
"type": "'centered' | 'fullscreen'"
|
|
6836
|
+
}
|
|
6837
|
+
],
|
|
6087
6838
|
"propsExtends": "Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> & SurfaceProps & Omit<DialogOptions, 'id'>",
|
|
6088
|
-
"source": "export type DialogProps = Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> & SurfaceProps & Omit<DialogOptions, 'id'
|
|
6839
|
+
"source": "export type DialogProps = Omit<ComponentPropsWithoutRef<'dialog'>, 'open'> & SurfaceProps & Omit<DialogOptions, 'id'> & {\n layout?: 'centered' | 'fullscreen'\n}\n\nexport const Dialog = ({\n className,\n defaultOpen,\n glass = false,\n layout = 'centered',\n onClick,\n onClose,\n onOpenChange,\n open,\n surface = 'default',\n ...props\n}: DialogProps) => {\n const dialog = useDialog({ defaultOpen, onOpenChange, open })\n\n return (\n <dialog\n {...dialog.dialogProps}\n {...props}\n className={composeClassName(\n 'ui-dialog',\n layout === 'fullscreen' && 'ui-dialog--fullscreen',\n glassSurfaceClass('ui-dialog', surface, glass),\n className\n )}\n data-layout={layout}\n data-surface={resolveSurface(surface, glass)}\n onClick={composeHandlers(onClick, dialog.dialogProps.onClick)}\n onClose={composeHandlers(onClose, dialog.dialogProps.onClose)}\n />\n )\n}",
|
|
6089
6840
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
6090
6841
|
}
|
|
6091
6842
|
},
|
|
@@ -6156,6 +6907,11 @@
|
|
|
6156
6907
|
"optional": true,
|
|
6157
6908
|
"type": "boolean | 'subtle' | 'strong'"
|
|
6158
6909
|
},
|
|
6910
|
+
{
|
|
6911
|
+
"name": "layout",
|
|
6912
|
+
"optional": true,
|
|
6913
|
+
"type": "'centered' | 'fullscreen'"
|
|
6914
|
+
},
|
|
6159
6915
|
{
|
|
6160
6916
|
"name": "surface",
|
|
6161
6917
|
"optional": true,
|
|
@@ -8011,7 +8767,7 @@
|
|
|
8011
8767
|
"values": "HTML attributes"
|
|
8012
8768
|
}
|
|
8013
8769
|
],
|
|
8014
|
-
"astroSource": "---\nimport {\n renderLumenIconSvg,\n resolveLumenAstroProps,\n type LumenIconName\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype IconSize = 'default' | 'lg' | 'sm' | 'xl'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n decorative?: boolean\n label?: string\n name?: LumenIconName\n size?: IconSize\n}\n\nconst {\n class: classProp = '',\n className = '',\n decorative,\n label,\n name,\n size = 'default',\n ...rest\n} = Astro.props\n\nconst isDecorative = decorative ?? !label\nconst iconSvg = name ? renderLumenIconSvg(name) : ''\n\nif (name && !iconSvg && import.meta.env.DEV) {\n console.warn(`[Lumen Icon] Unknown
|
|
8770
|
+
"astroSource": "---\nimport {\n renderLumenIconSvg,\n resolveLumenAstroProps,\n type LumenIconName\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype IconSize = 'default' | 'lg' | 'sm' | 'xl'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n decorative?: boolean\n label?: string\n name?: LumenIconName\n size?: IconSize\n}\n\nconst {\n class: classProp = '',\n className = '',\n decorative,\n label,\n name,\n size = 'default',\n ...rest\n} = Astro.props\n\nconst isDecorative = decorative ?? !label\nconst iconSvg = name ? renderLumenIconSvg(name) : ''\n\nif (name && !iconSvg && import.meta.env.DEV) {\n console.warn(`[Lumen Icon] Unknown icon \"${name}\". Register an icon pack or use the default slot for project-specific SVGs.`)\n}\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-icon',\n size === 'sm' && 'ui-icon--sm',\n size === 'lg' && 'ui-icon--lg',\n size === 'xl' && 'ui-icon--xl'\n], classProp, className)\n---\n\n<span\n aria-hidden={isDecorative ? 'true' : undefined}\n aria-label={!isDecorative ? label : undefined}\n class:list={classList}\n role={!isDecorative ? 'img' : undefined}\n {...passthrough}\n>\n {name ? <Fragment set:html={iconSvg} /> : <slot />}\n</span>\n",
|
|
8015
8771
|
"category": "Data display",
|
|
8016
8772
|
"collections": [],
|
|
8017
8773
|
"dependencies": [
|
|
@@ -8063,7 +8819,7 @@
|
|
|
8063
8819
|
}
|
|
8064
8820
|
],
|
|
8065
8821
|
"propsExtends": "HTMLAttributes<'span'>",
|
|
8066
|
-
"source": "---\nimport {\n renderLumenIconSvg,\n resolveLumenAstroProps,\n type LumenIconName\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype IconSize = 'default' | 'lg' | 'sm' | 'xl'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n decorative?: boolean\n label?: string\n name?: LumenIconName\n size?: IconSize\n}\n\nconst {\n class: classProp = '',\n className = '',\n decorative,\n label,\n name,\n size = 'default',\n ...rest\n} = Astro.props\n\nconst isDecorative = decorative ?? !label\nconst iconSvg = name ? renderLumenIconSvg(name) : ''\n\nif (name && !iconSvg && import.meta.env.DEV) {\n console.warn(`[Lumen Icon] Unknown
|
|
8822
|
+
"source": "---\nimport {\n renderLumenIconSvg,\n resolveLumenAstroProps,\n type LumenIconName\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype IconSize = 'default' | 'lg' | 'sm' | 'xl'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n decorative?: boolean\n label?: string\n name?: LumenIconName\n size?: IconSize\n}\n\nconst {\n class: classProp = '',\n className = '',\n decorative,\n label,\n name,\n size = 'default',\n ...rest\n} = Astro.props\n\nconst isDecorative = decorative ?? !label\nconst iconSvg = name ? renderLumenIconSvg(name) : ''\n\nif (name && !iconSvg && import.meta.env.DEV) {\n console.warn(`[Lumen Icon] Unknown icon \"${name}\". Register an icon pack or use the default slot for project-specific SVGs.`)\n}\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-icon',\n size === 'sm' && 'ui-icon--sm',\n size === 'lg' && 'ui-icon--lg',\n size === 'xl' && 'ui-icon--xl'\n], classProp, className)\n---\n\n<span\n aria-hidden={isDecorative ? 'true' : undefined}\n aria-label={!isDecorative ? label : undefined}\n class:list={classList}\n role={!isDecorative ? 'img' : undefined}\n {...passthrough}\n>\n {name ? <Fragment set:html={iconSvg} /> : <slot />}\n</span>\n",
|
|
8067
8823
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
8068
8824
|
},
|
|
8069
8825
|
"elements": {
|
|
@@ -9644,10 +10400,46 @@
|
|
|
9644
10400
|
{
|
|
9645
10401
|
"apiReference": [
|
|
9646
10402
|
{
|
|
9647
|
-
"attribute": "
|
|
9648
|
-
"defaultValue": "
|
|
9649
|
-
"description": "
|
|
9650
|
-
"values": "
|
|
10403
|
+
"attribute": "glass",
|
|
10404
|
+
"defaultValue": "false",
|
|
10405
|
+
"description": "Applies the tokenized liquid-glass surface treatment with backdrop-filter fallbacks; \"subtle\" and \"strong\" adjust the fill intensity.",
|
|
10406
|
+
"values": "boolean | \"subtle\" | \"strong\""
|
|
10407
|
+
},
|
|
10408
|
+
{
|
|
10409
|
+
"attribute": "series",
|
|
10410
|
+
"defaultValue": "required",
|
|
10411
|
+
"description": "Provides ordered, already-aggregated points; null y values create visible gaps.",
|
|
10412
|
+
"values": "LumenChartSeries[]"
|
|
10413
|
+
},
|
|
10414
|
+
{
|
|
10415
|
+
"attribute": "area",
|
|
10416
|
+
"defaultValue": "false",
|
|
10417
|
+
"description": "Adds a tokenized fill between each line segment and the zero or domain baseline.",
|
|
10418
|
+
"values": "boolean"
|
|
10419
|
+
},
|
|
10420
|
+
{
|
|
10421
|
+
"attribute": "markers",
|
|
10422
|
+
"defaultValue": "true",
|
|
10423
|
+
"description": "Shows point markers as a second visual cue and exposes per-point SVG titles.",
|
|
10424
|
+
"values": "boolean"
|
|
10425
|
+
},
|
|
10426
|
+
{
|
|
10427
|
+
"attribute": "referenceValue",
|
|
10428
|
+
"defaultValue": "-",
|
|
10429
|
+
"description": "Draws a dashed threshold or comparison line across the plot.",
|
|
10430
|
+
"values": "number"
|
|
10431
|
+
},
|
|
10432
|
+
{
|
|
10433
|
+
"attribute": "showLegend",
|
|
10434
|
+
"defaultValue": "true for multiple series",
|
|
10435
|
+
"description": "Shows the color-independent series key.",
|
|
10436
|
+
"values": "boolean"
|
|
10437
|
+
},
|
|
10438
|
+
{
|
|
10439
|
+
"attribute": "showTable",
|
|
10440
|
+
"defaultValue": "true",
|
|
10441
|
+
"description": "Provides a revealable semantic table containing every plotted value.",
|
|
10442
|
+
"values": "boolean"
|
|
9651
10443
|
},
|
|
9652
10444
|
{
|
|
9653
10445
|
"attribute": "class, className",
|
|
@@ -9662,25 +10454,39 @@
|
|
|
9662
10454
|
"values": "HTML attributes"
|
|
9663
10455
|
}
|
|
9664
10456
|
],
|
|
9665
|
-
"astroSource": "---\nimport {
|
|
10457
|
+
"astroSource": "---\nimport {\n alignLumenChartSeries,\n createLumenLineGeometry,\n getLumenChartCategories,\n getLumenChartDomain,\n getLumenChartTicks,\n hasLumenChartData,\n type LumenChartSeries,\n resolveLumenChartTone,\n scaleLumenChartValue\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Chart from './Chart.astro'\n\ninterface Props extends HTMLAttributes<'figure'> {\n area?: boolean\n caption?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n markers?: boolean\n referenceValue?: number\n series: readonly LumenChartSeries[]\n showLegend?: boolean\n showTable?: boolean\n}\n\nconst {\n area = false,\n caption,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n markers = true,\n referenceValue,\n series,\n showLegend = series.length > 1,\n showTable = true,\n ...rest\n} = Astro.props\nconst width = 640\nconst height = 320\nconst padding = 44\nconst categories = getLumenChartCategories(series)\nconst hasData = hasLumenChartData(series)\nconst alignedSeries = series.map(item => alignLumenChartSeries(item, categories))\nconst domain = getLumenChartDomain([\n ...alignedSeries.flatMap(item => item.data.map(datum => datum.y)),\n referenceValue ?? null\n], false)\nconst geometries = alignedSeries.map(item =>\n createLumenLineGeometry(item.data, {\n domain,\n height,\n includeZero: false,\n padding,\n width\n })\n)\nconst ticks = getLumenChartTicks(domain)\nconst labelStep = Math.max(1, Math.ceil(categories.length / 8))\nconst valueFor = (item: LumenChartSeries, category: number | string) =>\n item.data.find(datum => datum.x === category)\nconst referenceY =\n referenceValue === undefined\n ? undefined\n : scaleLumenChartValue(referenceValue, domain, height - padding, padding)\n---\n\n<Chart\n class:list={['ui-line-chart', classProp, className]}\n {caption}\n {description}\n {glass}\n {heading}\n {...rest}\n>\n {\n showLegend && hasData && (\n <ul class=\"ui-chart__legend\" aria-label=\"Chart legend\">\n {series.map((item, index) => (\n <li class={`ui-chart-tone--${resolveLumenChartTone(item.tone, index)}`}>\n <span aria-hidden=\"true\" />\n {item.label}\n </li>\n ))}\n </ul>\n )\n }\n {!hasData && <p class=\"ui-chart__empty\" role=\"status\">No chart data available.</p>}\n <div class=\"ui-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${width} ${height}`}\n >\n <g class=\"ui-chart__grid\">\n {\n ticks.map((tick) => {\n const y = scaleLumenChartValue(\n tick,\n domain,\n height - padding,\n padding\n )\n\n return (\n <>\n <line x1={padding} x2={width - padding} y1={y} y2={y} />\n <text x={padding - 8} y={y}>\n {Number(tick.toPrecision(4))}\n </text>\n </>\n )\n })\n }\n </g>\n <g class=\"ui-chart__axis-labels\">\n {\n categories.map((category, index) => {\n if (\n index % labelStep !== 0 &&\n index !== categories.length - 1\n )\n return null\n\n const denominator = Math.max(1, categories.length - 1)\n const x =\n padding + (index / denominator) * (width - padding * 2)\n\n return (\n <text text-anchor=\"middle\" x={x} y={height - 14}>\n {String(category)}\n </text>\n )\n })\n }\n </g>\n {\n referenceY !== undefined && (\n <line\n class=\"ui-chart__reference\"\n x1={padding}\n x2={width - padding}\n y1={referenceY}\n y2={referenceY}\n />\n )\n }\n {\n geometries.map((geometry, index) => {\n const item = series[index]\n\n if (!item) return null\n\n const tone = resolveLumenChartTone(item.tone, index)\n\n return (\n <g class={`ui-line-chart__series ui-chart-tone--${tone}`}>\n {area &&\n geometry.areaPaths.map(path => (\n <path class=\"ui-line-chart__area\" d={path} />\n ))}\n <path class=\"ui-line-chart__line\" d={geometry.path} />\n {markers &&\n geometry.points.map(point => (\n <circle\n class=\"ui-line-chart__point\"\n cx={point.xCoordinate}\n cy={point.yCoordinate}\n r=\"3\"\n >\n <title>\n {`${point.label ?? String(point.x)} · ${item.label}: ${point.y}`}\n </title>\n </circle>\n ))}\n </g>\n )\n })\n }\n </svg>\n </div>\n {\n showTable && hasData && (\n <details class=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n {series.map(item => <th scope=\"col\">{item.label}</th>)}\n </tr>\n </thead>\n <tbody>\n {categories.map(category => (\n <tr>\n <th scope=\"row\">{String(category)}</th>\n {series.map(item => {\n const datum = valueFor(item, category)\n\n return (\n <td>\n {datum?.label ??\n (datum?.y === null || datum === undefined\n ? 'Not available'\n : String(datum.y))}\n </td>\n )\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )\n }\n</Chart>\n",
|
|
9666
10458
|
"category": "Data display",
|
|
9667
|
-
"collections": [
|
|
10459
|
+
"collections": [
|
|
10460
|
+
"Data visualization"
|
|
10461
|
+
],
|
|
9668
10462
|
"dependencies": [
|
|
10463
|
+
"Chart",
|
|
9669
10464
|
"styles"
|
|
9670
10465
|
],
|
|
9671
|
-
"description": "
|
|
10466
|
+
"description": "Shows ordered trends, multiple series, missing-value gaps, areas, markers, and reference values.",
|
|
9672
10467
|
"files": [
|
|
9673
|
-
"packages/astro/components/
|
|
10468
|
+
"packages/astro/components/LineChart.astro",
|
|
10469
|
+
"packages/astro/components/Chart.astro",
|
|
9674
10470
|
"packages/astro/styles/lumen.css"
|
|
9675
10471
|
],
|
|
9676
10472
|
"frameworkDetails": {
|
|
9677
10473
|
"astro": {
|
|
9678
10474
|
"available": true,
|
|
9679
|
-
"example": "<
|
|
9680
|
-
"importStatement": "import {
|
|
10475
|
+
"example": "<LineChart aria-label=\"Website traffic\" heading=\"Page views and visits\" series={[{ id: \"views\", label: \"Page views\", data: [{ x: \"Mon\", y: 120 }, { x: \"Tue\", y: 168 }] }, { id: \"visits\", label: \"Visits\", data: [{ x: \"Mon\", y: 82 }, { x: \"Tue\", y: 104 }] }]} />",
|
|
10476
|
+
"importStatement": "import { LineChart } from '@santi020k/lumen-astro'",
|
|
9681
10477
|
"language": "astro",
|
|
9682
10478
|
"packageName": "@santi020k/lumen-astro",
|
|
9683
10479
|
"props": [
|
|
10480
|
+
{
|
|
10481
|
+
"name": "area",
|
|
10482
|
+
"optional": true,
|
|
10483
|
+
"type": "boolean"
|
|
10484
|
+
},
|
|
10485
|
+
{
|
|
10486
|
+
"name": "caption",
|
|
10487
|
+
"optional": true,
|
|
10488
|
+
"type": "string"
|
|
10489
|
+
},
|
|
9684
10490
|
{
|
|
9685
10491
|
"name": "class",
|
|
9686
10492
|
"optional": true,
|
|
@@ -9692,25 +10498,322 @@
|
|
|
9692
10498
|
"type": "string"
|
|
9693
10499
|
},
|
|
9694
10500
|
{
|
|
9695
|
-
"name": "
|
|
10501
|
+
"name": "description",
|
|
9696
10502
|
"optional": true,
|
|
9697
|
-
"type": "
|
|
9698
|
-
}
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
10503
|
+
"type": "string"
|
|
10504
|
+
},
|
|
10505
|
+
{
|
|
10506
|
+
"name": "glass",
|
|
10507
|
+
"optional": true,
|
|
10508
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
10509
|
+
},
|
|
10510
|
+
{
|
|
10511
|
+
"name": "heading",
|
|
10512
|
+
"optional": true,
|
|
10513
|
+
"type": "string"
|
|
10514
|
+
},
|
|
10515
|
+
{
|
|
10516
|
+
"name": "markers",
|
|
10517
|
+
"optional": true,
|
|
10518
|
+
"type": "boolean"
|
|
10519
|
+
},
|
|
10520
|
+
{
|
|
10521
|
+
"name": "referenceValue",
|
|
10522
|
+
"optional": true,
|
|
10523
|
+
"type": "number"
|
|
10524
|
+
},
|
|
10525
|
+
{
|
|
10526
|
+
"name": "series",
|
|
10527
|
+
"optional": false,
|
|
10528
|
+
"type": "readonly LumenChartSeries[]"
|
|
10529
|
+
},
|
|
10530
|
+
{
|
|
10531
|
+
"name": "showLegend",
|
|
10532
|
+
"optional": true,
|
|
10533
|
+
"type": "boolean"
|
|
10534
|
+
},
|
|
10535
|
+
{
|
|
10536
|
+
"name": "showTable",
|
|
10537
|
+
"optional": true,
|
|
10538
|
+
"type": "boolean"
|
|
10539
|
+
}
|
|
10540
|
+
],
|
|
10541
|
+
"propsExtends": "HTMLAttributes<'figure'>",
|
|
10542
|
+
"source": "---\nimport {\n alignLumenChartSeries,\n createLumenLineGeometry,\n getLumenChartCategories,\n getLumenChartDomain,\n getLumenChartTicks,\n hasLumenChartData,\n type LumenChartSeries,\n resolveLumenChartTone,\n scaleLumenChartValue\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Chart from './Chart.astro'\n\ninterface Props extends HTMLAttributes<'figure'> {\n area?: boolean\n caption?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n markers?: boolean\n referenceValue?: number\n series: readonly LumenChartSeries[]\n showLegend?: boolean\n showTable?: boolean\n}\n\nconst {\n area = false,\n caption,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n markers = true,\n referenceValue,\n series,\n showLegend = series.length > 1,\n showTable = true,\n ...rest\n} = Astro.props\nconst width = 640\nconst height = 320\nconst padding = 44\nconst categories = getLumenChartCategories(series)\nconst hasData = hasLumenChartData(series)\nconst alignedSeries = series.map(item => alignLumenChartSeries(item, categories))\nconst domain = getLumenChartDomain([\n ...alignedSeries.flatMap(item => item.data.map(datum => datum.y)),\n referenceValue ?? null\n], false)\nconst geometries = alignedSeries.map(item =>\n createLumenLineGeometry(item.data, {\n domain,\n height,\n includeZero: false,\n padding,\n width\n })\n)\nconst ticks = getLumenChartTicks(domain)\nconst labelStep = Math.max(1, Math.ceil(categories.length / 8))\nconst valueFor = (item: LumenChartSeries, category: number | string) =>\n item.data.find(datum => datum.x === category)\nconst referenceY =\n referenceValue === undefined\n ? undefined\n : scaleLumenChartValue(referenceValue, domain, height - padding, padding)\n---\n\n<Chart\n class:list={['ui-line-chart', classProp, className]}\n {caption}\n {description}\n {glass}\n {heading}\n {...rest}\n>\n {\n showLegend && hasData && (\n <ul class=\"ui-chart__legend\" aria-label=\"Chart legend\">\n {series.map((item, index) => (\n <li class={`ui-chart-tone--${resolveLumenChartTone(item.tone, index)}`}>\n <span aria-hidden=\"true\" />\n {item.label}\n </li>\n ))}\n </ul>\n )\n }\n {!hasData && <p class=\"ui-chart__empty\" role=\"status\">No chart data available.</p>}\n <div class=\"ui-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${width} ${height}`}\n >\n <g class=\"ui-chart__grid\">\n {\n ticks.map((tick) => {\n const y = scaleLumenChartValue(\n tick,\n domain,\n height - padding,\n padding\n )\n\n return (\n <>\n <line x1={padding} x2={width - padding} y1={y} y2={y} />\n <text x={padding - 8} y={y}>\n {Number(tick.toPrecision(4))}\n </text>\n </>\n )\n })\n }\n </g>\n <g class=\"ui-chart__axis-labels\">\n {\n categories.map((category, index) => {\n if (\n index % labelStep !== 0 &&\n index !== categories.length - 1\n )\n return null\n\n const denominator = Math.max(1, categories.length - 1)\n const x =\n padding + (index / denominator) * (width - padding * 2)\n\n return (\n <text text-anchor=\"middle\" x={x} y={height - 14}>\n {String(category)}\n </text>\n )\n })\n }\n </g>\n {\n referenceY !== undefined && (\n <line\n class=\"ui-chart__reference\"\n x1={padding}\n x2={width - padding}\n y1={referenceY}\n y2={referenceY}\n />\n )\n }\n {\n geometries.map((geometry, index) => {\n const item = series[index]\n\n if (!item) return null\n\n const tone = resolveLumenChartTone(item.tone, index)\n\n return (\n <g class={`ui-line-chart__series ui-chart-tone--${tone}`}>\n {area &&\n geometry.areaPaths.map(path => (\n <path class=\"ui-line-chart__area\" d={path} />\n ))}\n <path class=\"ui-line-chart__line\" d={geometry.path} />\n {markers &&\n geometry.points.map(point => (\n <circle\n class=\"ui-line-chart__point\"\n cx={point.xCoordinate}\n cy={point.yCoordinate}\n r=\"3\"\n >\n <title>\n {`${point.label ?? String(point.x)} · ${item.label}: ${point.y}`}\n </title>\n </circle>\n ))}\n </g>\n )\n })\n }\n </svg>\n </div>\n {\n showTable && hasData && (\n <details class=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n {series.map(item => <th scope=\"col\">{item.label}</th>)}\n </tr>\n </thead>\n <tbody>\n {categories.map(category => (\n <tr>\n <th scope=\"row\">{String(category)}</th>\n {series.map(item => {\n const datum = valueFor(item, category)\n\n return (\n <td>\n {datum?.label ??\n (datum?.y === null || datum === undefined\n ? 'Not available'\n : String(datum.y))}\n </td>\n )\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )\n }\n</Chart>\n",
|
|
10543
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
10544
|
+
},
|
|
10545
|
+
"elements": {
|
|
10546
|
+
"attributes": [
|
|
10547
|
+
"glass",
|
|
10548
|
+
"series",
|
|
10549
|
+
"area",
|
|
10550
|
+
"markers",
|
|
10551
|
+
"referenceValue",
|
|
10552
|
+
"showLegend",
|
|
10553
|
+
"showTable",
|
|
10554
|
+
"class, className",
|
|
10555
|
+
"...native attributes"
|
|
10556
|
+
],
|
|
10557
|
+
"available": true,
|
|
10558
|
+
"behavior": {
|
|
10559
|
+
"mode": "registration",
|
|
10560
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
10561
|
+
},
|
|
10562
|
+
"example": "<lumen-line-chart></lumen-line-chart>",
|
|
10563
|
+
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
10564
|
+
"language": "html",
|
|
10565
|
+
"packageName": "@santi020k/lumen-elements",
|
|
10566
|
+
"props": [],
|
|
10567
|
+
"propsExtends": "HTMLElement attributes",
|
|
10568
|
+
"registration": "defineLumenElements()",
|
|
10569
|
+
"source": "LineChart: {\n attributeClasses: glassAttributeClasses('ui-chart--glass'),\n baseClassName: 'ui-chart ui-line-chart',\n role: 'figure',\n tagName: 'lumen-line-chart'\n }",
|
|
10570
|
+
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
10571
|
+
"tagName": "lumen-line-chart"
|
|
10572
|
+
},
|
|
10573
|
+
"react": {
|
|
10574
|
+
"available": true,
|
|
10575
|
+
"example": "<LineChart aria-label=\"Website traffic\" heading=\"Page views and visits\" series={[{ id: \"views\", label: \"Page views\", data: [{ x: \"Mon\", y: 120 }, { x: \"Tue\", y: 168 }] }, { id: \"visits\", label: \"Visits\", data: [{ x: \"Mon\", y: 82 }, { x: \"Tue\", y: 104 }] }]} />",
|
|
10576
|
+
"importStatement": "import { LineChart } from '@santi020k/lumen-react'",
|
|
10577
|
+
"language": "tsx",
|
|
10578
|
+
"packageName": "@santi020k/lumen-react",
|
|
10579
|
+
"props": [
|
|
10580
|
+
{
|
|
10581
|
+
"name": "area",
|
|
10582
|
+
"optional": true,
|
|
10583
|
+
"type": "boolean"
|
|
10584
|
+
},
|
|
10585
|
+
{
|
|
10586
|
+
"name": "markers",
|
|
10587
|
+
"optional": true,
|
|
10588
|
+
"type": "boolean"
|
|
10589
|
+
},
|
|
10590
|
+
{
|
|
10591
|
+
"name": "referenceValue",
|
|
10592
|
+
"optional": true,
|
|
10593
|
+
"type": "number"
|
|
10594
|
+
},
|
|
10595
|
+
{
|
|
10596
|
+
"name": "series",
|
|
10597
|
+
"optional": true,
|
|
10598
|
+
"type": "readonly LumenChartSeries[]"
|
|
10599
|
+
},
|
|
10600
|
+
{
|
|
10601
|
+
"name": "showLegend",
|
|
10602
|
+
"optional": true,
|
|
10603
|
+
"type": "boolean"
|
|
10604
|
+
},
|
|
10605
|
+
{
|
|
10606
|
+
"name": "showTable",
|
|
10607
|
+
"optional": true,
|
|
10608
|
+
"type": "boolean"
|
|
10609
|
+
}
|
|
10610
|
+
],
|
|
10611
|
+
"propsExtends": "Omit<ChartProps, 'children'>",
|
|
10612
|
+
"source": "export interface LineChartProps extends Omit<ChartProps, 'children'> {\n area?: boolean\n markers?: boolean\n referenceValue?: number\n series?: readonly LumenChartSeries[]\n showLegend?: boolean\n showTable?: boolean\n}\n\nexport const LineChart = ({\n area = false,\n className,\n markers = true,\n referenceValue,\n series = emptyChartSeries,\n showLegend = series.length > 1,\n showTable = true,\n ...props\n}: LineChartProps) => {\n const width = 640\n const height = 320\n const padding = 44\n const categories = getLumenChartCategories(series)\n const hasData = hasLumenChartData(series)\n const alignedSeries = series.map(item => alignLumenChartSeries(item, categories))\n\n const domain = getLumenChartDomain([\n ...alignedSeries.flatMap(item => item.data.map(datum => datum.y)),\n referenceValue ?? null\n ], false)\n\n const geometries = alignedSeries.map(item =>\n createLumenLineGeometry(item.data, {\n domain,\n height,\n includeZero: false,\n padding,\n width\n })\n )\n\n const ticks = getLumenChartTicks(domain)\n const labelStep = Math.max(1, Math.ceil(categories.length / 8))\n\n const referenceY = referenceValue === undefined\n ? undefined\n : scaleLumenChartValue(referenceValue, domain, height - padding, padding)\n\n return (\n <Chart className={composeClassName('ui-line-chart', className)} {...props}>\n {showLegend && hasData && <ChartLegend series={series} />}\n {!hasData && (\n <p className=\"ui-chart__empty\" role=\"status\">No chart data available.</p>\n )}\n <div className=\"ui-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${width} ${height}`}\n >\n <g className=\"ui-chart__grid\">\n {ticks.map(tick => {\n const y = scaleLumenChartValue(tick, domain, height - padding, padding)\n\n return (\n <Fragment key={tick}>\n <line x1={padding} x2={width - padding} y1={y} y2={y} />\n <text x={padding - 8} y={y}>{Number(tick.toPrecision(4))}</text>\n </Fragment>\n )\n })}\n </g>\n <g className=\"ui-chart__axis-labels\">\n {categories.map((category, index) => {\n if (index % labelStep !== 0 && index !== categories.length - 1) return null\n\n const denominator = Math.max(1, categories.length - 1)\n const x = padding + (index / denominator) * (width - padding * 2)\n\n return (\n <text\n key={`${typeof category}:${String(category)}`}\n textAnchor=\"middle\"\n x={x}\n y={height - 14}\n >\n {String(category)}\n </text>\n )\n })}\n </g>\n {referenceY !== undefined && (\n <line\n className=\"ui-chart__reference\"\n x1={padding}\n x2={width - padding}\n y1={referenceY}\n y2={referenceY}\n />\n )}\n {geometries.map((geometry, index) => {\n const item = series[index]\n\n if (!item) return null\n\n const tone = resolveLumenChartTone(item.tone, index)\n\n return (\n <g\n className={`ui-line-chart__series ui-chart-tone--${tone}`}\n key={item.id}\n >\n {area && geometry.areaPaths.map(path => (\n <path className=\"ui-line-chart__area\" d={path} key={path} />\n ))}\n <path className=\"ui-line-chart__line\" d={geometry.path} />\n {markers && geometry.points.map(point => (\n <circle\n className=\"ui-line-chart__point\"\n cx={point.xCoordinate}\n cy={point.yCoordinate}\n key={`${typeof point.x}:${String(point.x)}`}\n r=\"3\"\n >\n <title>\n {`${point.label ?? String(point.x)} · ${item.label}: ${String(point.y)}`}\n </title>\n </circle>\n ))}\n </g>\n )\n })}\n </svg>\n </div>\n {showTable && hasData && (\n <ChartDataTable categories={categories} series={series} />\n )}\n </Chart>\n )\n}",
|
|
10613
|
+
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
10614
|
+
}
|
|
10615
|
+
},
|
|
10616
|
+
"frameworks": {
|
|
10617
|
+
"astro": true,
|
|
10618
|
+
"elements": true,
|
|
10619
|
+
"react": true
|
|
10620
|
+
},
|
|
10621
|
+
"guidance": {
|
|
10622
|
+
"when": "Use to show how one or more ordered series change, including missing values and thresholds.",
|
|
10623
|
+
"distinction": "Use BarChart for categorical magnitude comparisons and Sparkline when axes and exact values are unnecessary."
|
|
10624
|
+
},
|
|
10625
|
+
"kebab": "line-chart",
|
|
10626
|
+
"keyboardInteractions": [],
|
|
10627
|
+
"keywords": [
|
|
10628
|
+
"and",
|
|
10629
|
+
"are",
|
|
10630
|
+
"areas",
|
|
10631
|
+
"axes",
|
|
10632
|
+
"barchart",
|
|
10633
|
+
"breakdowns",
|
|
10634
|
+
"categorical",
|
|
10635
|
+
"change",
|
|
10636
|
+
"compact",
|
|
10637
|
+
"comparisons",
|
|
10638
|
+
"custom",
|
|
10639
|
+
"data",
|
|
10640
|
+
"display",
|
|
10641
|
+
"exact",
|
|
10642
|
+
"for",
|
|
10643
|
+
"gaps",
|
|
10644
|
+
"how",
|
|
10645
|
+
"including",
|
|
10646
|
+
"linechart",
|
|
10647
|
+
"magnitude",
|
|
10648
|
+
"markers",
|
|
10649
|
+
"match",
|
|
10650
|
+
"metrics",
|
|
10651
|
+
"missing",
|
|
10652
|
+
"more",
|
|
10653
|
+
"multiple",
|
|
10654
|
+
"one",
|
|
10655
|
+
"ordered",
|
|
10656
|
+
"part",
|
|
10657
|
+
"plots",
|
|
10658
|
+
"question",
|
|
10659
|
+
"reference",
|
|
10660
|
+
"series",
|
|
10661
|
+
"show",
|
|
10662
|
+
"shows",
|
|
10663
|
+
"sparkline",
|
|
10664
|
+
"the",
|
|
10665
|
+
"thresholds",
|
|
10666
|
+
"trends",
|
|
10667
|
+
"unnecessary",
|
|
10668
|
+
"use",
|
|
10669
|
+
"value",
|
|
10670
|
+
"values",
|
|
10671
|
+
"visualization",
|
|
10672
|
+
"when",
|
|
10673
|
+
"whole"
|
|
10674
|
+
],
|
|
10675
|
+
"name": "LineChart",
|
|
10676
|
+
"props": [
|
|
10677
|
+
{
|
|
10678
|
+
"name": "area",
|
|
10679
|
+
"optional": true,
|
|
10680
|
+
"type": "boolean"
|
|
10681
|
+
},
|
|
10682
|
+
{
|
|
10683
|
+
"name": "caption",
|
|
10684
|
+
"optional": true,
|
|
10685
|
+
"type": "string"
|
|
10686
|
+
},
|
|
10687
|
+
{
|
|
10688
|
+
"name": "class",
|
|
10689
|
+
"optional": true,
|
|
10690
|
+
"type": "string | null"
|
|
10691
|
+
},
|
|
10692
|
+
{
|
|
10693
|
+
"name": "className",
|
|
10694
|
+
"optional": true,
|
|
10695
|
+
"type": "string"
|
|
10696
|
+
},
|
|
10697
|
+
{
|
|
10698
|
+
"name": "description",
|
|
10699
|
+
"optional": true,
|
|
10700
|
+
"type": "string"
|
|
10701
|
+
},
|
|
10702
|
+
{
|
|
10703
|
+
"name": "glass",
|
|
10704
|
+
"optional": true,
|
|
10705
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
10706
|
+
},
|
|
10707
|
+
{
|
|
10708
|
+
"name": "heading",
|
|
10709
|
+
"optional": true,
|
|
10710
|
+
"type": "string"
|
|
10711
|
+
},
|
|
10712
|
+
{
|
|
10713
|
+
"name": "markers",
|
|
10714
|
+
"optional": true,
|
|
10715
|
+
"type": "boolean"
|
|
10716
|
+
},
|
|
10717
|
+
{
|
|
10718
|
+
"name": "referenceValue",
|
|
10719
|
+
"optional": true,
|
|
10720
|
+
"type": "number"
|
|
10721
|
+
},
|
|
10722
|
+
{
|
|
10723
|
+
"name": "series",
|
|
10724
|
+
"optional": false,
|
|
10725
|
+
"type": "readonly LumenChartSeries[]"
|
|
10726
|
+
},
|
|
10727
|
+
{
|
|
10728
|
+
"name": "showLegend",
|
|
10729
|
+
"optional": true,
|
|
10730
|
+
"type": "boolean"
|
|
10731
|
+
},
|
|
10732
|
+
{
|
|
10733
|
+
"name": "showTable",
|
|
10734
|
+
"optional": true,
|
|
10735
|
+
"type": "boolean"
|
|
10736
|
+
}
|
|
10737
|
+
],
|
|
10738
|
+
"propsExtends": "HTMLAttributes<'figure'>",
|
|
10739
|
+
"recipes": [
|
|
10740
|
+
{
|
|
10741
|
+
"name": "data-visualization",
|
|
10742
|
+
"type": "recipe"
|
|
10743
|
+
}
|
|
10744
|
+
],
|
|
10745
|
+
"runtimeEvents": []
|
|
10746
|
+
},
|
|
10747
|
+
{
|
|
10748
|
+
"apiReference": [
|
|
10749
|
+
{
|
|
10750
|
+
"attribute": "variant",
|
|
10751
|
+
"defaultValue": "\"default\"",
|
|
10752
|
+
"description": "Controls the marker tone.",
|
|
10753
|
+
"values": "\"default\" | \"success\" | \"warning\" | \"danger\""
|
|
10754
|
+
},
|
|
10755
|
+
{
|
|
10756
|
+
"attribute": "class, className",
|
|
10757
|
+
"defaultValue": "\"\"",
|
|
10758
|
+
"description": "Merges custom classes with the generated ui-* root classes.",
|
|
10759
|
+
"values": "string"
|
|
10760
|
+
},
|
|
10761
|
+
{
|
|
10762
|
+
"attribute": "...native attributes",
|
|
10763
|
+
"defaultValue": "-",
|
|
10764
|
+
"description": "Forwards standard attributes to the root element unless the component consumes them.",
|
|
10765
|
+
"values": "HTML attributes"
|
|
10766
|
+
}
|
|
10767
|
+
],
|
|
10768
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n variant?: 'default' | 'success' | 'warning' | 'danger'\n}\n\nconst {\n class: classProp = '',\n className = '',\n variant = 'default',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-marker',\n variant === 'success' && 'ui-marker--success',\n variant === 'warning' && 'ui-marker--warning',\n variant === 'danger' && 'ui-marker--danger'\n], classProp, className)\n---\n\n<span\n data-variant={variant}\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</span>\n",
|
|
10769
|
+
"category": "Data display",
|
|
10770
|
+
"collections": [],
|
|
10771
|
+
"dependencies": [
|
|
10772
|
+
"styles"
|
|
10773
|
+
],
|
|
10774
|
+
"description": "Highlights status, position, or annotations.",
|
|
10775
|
+
"files": [
|
|
10776
|
+
"packages/astro/components/Marker.astro",
|
|
10777
|
+
"packages/astro/styles/lumen.css"
|
|
10778
|
+
],
|
|
10779
|
+
"frameworkDetails": {
|
|
10780
|
+
"astro": {
|
|
10781
|
+
"available": true,
|
|
10782
|
+
"example": "<Marker variant=\"success\">Live</Marker>",
|
|
10783
|
+
"importStatement": "import { Marker } from '@santi020k/lumen-astro'",
|
|
10784
|
+
"language": "astro",
|
|
10785
|
+
"packageName": "@santi020k/lumen-astro",
|
|
10786
|
+
"props": [
|
|
10787
|
+
{
|
|
10788
|
+
"name": "class",
|
|
10789
|
+
"optional": true,
|
|
10790
|
+
"type": "string | null"
|
|
10791
|
+
},
|
|
10792
|
+
{
|
|
10793
|
+
"name": "className",
|
|
10794
|
+
"optional": true,
|
|
10795
|
+
"type": "string"
|
|
10796
|
+
},
|
|
10797
|
+
{
|
|
10798
|
+
"name": "variant",
|
|
10799
|
+
"optional": true,
|
|
10800
|
+
"type": "'default' | 'success' | 'warning' | 'danger'"
|
|
10801
|
+
}
|
|
10802
|
+
],
|
|
10803
|
+
"propsExtends": "HTMLAttributes<'span'>",
|
|
10804
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n variant?: 'default' | 'success' | 'warning' | 'danger'\n}\n\nconst {\n class: classProp = '',\n className = '',\n variant = 'default',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-marker',\n variant === 'success' && 'ui-marker--success',\n variant === 'warning' && 'ui-marker--warning',\n variant === 'danger' && 'ui-marker--danger'\n], classProp, className)\n---\n\n<span\n data-variant={variant}\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</span>\n",
|
|
10805
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
10806
|
+
},
|
|
10807
|
+
"elements": {
|
|
10808
|
+
"attributes": [
|
|
10809
|
+
"variant",
|
|
10810
|
+
"class, className",
|
|
10811
|
+
"...native attributes"
|
|
10812
|
+
],
|
|
10813
|
+
"available": true,
|
|
10814
|
+
"behavior": {
|
|
10815
|
+
"mode": "registration",
|
|
10816
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
9714
10817
|
},
|
|
9715
10818
|
"example": "<lumen-marker variant=\"success\">Live</lumen-marker>",
|
|
9716
10819
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
@@ -11192,23 +12295,340 @@
|
|
|
11192
12295
|
"type": "string"
|
|
11193
12296
|
},
|
|
11194
12297
|
{
|
|
11195
|
-
"name": "name",
|
|
12298
|
+
"name": "name",
|
|
12299
|
+
"optional": true,
|
|
12300
|
+
"type": "string"
|
|
12301
|
+
},
|
|
12302
|
+
{
|
|
12303
|
+
"name": "placeholder",
|
|
12304
|
+
"optional": true,
|
|
12305
|
+
"type": "string"
|
|
12306
|
+
},
|
|
12307
|
+
{
|
|
12308
|
+
"name": "size",
|
|
12309
|
+
"optional": true,
|
|
12310
|
+
"type": "'default' | 'lg' | 'sm'"
|
|
12311
|
+
}
|
|
12312
|
+
],
|
|
12313
|
+
"propsExtends": "Omit<ComponentPropsWithoutRef<'div'>, 'defaultValue'>",
|
|
12314
|
+
"source": "export interface PhoneInputProps extends Omit<ComponentPropsWithoutRef<'div'>, 'defaultValue'> {\n countries?: SelectOption[]\n countryLabel?: string\n countryName?: string\n defaultCountryValue?: string\n defaultValue?: string\n name?: string\n placeholder?: string\n size?: 'default' | 'lg' | 'sm'\n}\n\nexport const PhoneInput = ({\n className,\n countries = emptyOptions,\n countryLabel = 'Country code',\n countryName = 'country',\n defaultCountryValue,\n defaultValue,\n name = 'phone',\n placeholder = 'Phone number',\n size = 'default',\n ...props\n}: PhoneInputProps) => {\n const { selectClass, inputClass } = phoneInputSizeModifiers(size)\n\n return (\n <div className={composeClassName('ui-phone-input ui-input-group', className)} {...props}>\n <select\n aria-label={countryLabel}\n className={composeClassName('ui-select ui-phone-input__country', selectClass)}\n defaultValue={defaultCountryValue}\n name={countryName}\n >\n {countries.map(normalizeOption).map(option => (\n <option disabled={option.disabled} key={option.value} value={option.value}>\n {option.label}\n </option>\n ))}\n </select>\n <input\n autoComplete=\"tel\"\n className={composeClassName('ui-input ui-phone-input__number', inputClass)}\n defaultValue={defaultValue}\n inputMode=\"tel\"\n name={name}\n placeholder={placeholder}\n type=\"tel\"\n />\n </div>\n )\n}",
|
|
12315
|
+
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
12316
|
+
}
|
|
12317
|
+
},
|
|
12318
|
+
"frameworks": {
|
|
12319
|
+
"astro": true,
|
|
12320
|
+
"elements": true,
|
|
12321
|
+
"react": true
|
|
12322
|
+
},
|
|
12323
|
+
"guidance": null,
|
|
12324
|
+
"kebab": "phone-input",
|
|
12325
|
+
"keyboardInteractions": [],
|
|
12326
|
+
"keywords": [
|
|
12327
|
+
"built",
|
|
12328
|
+
"choose",
|
|
12329
|
+
"code",
|
|
12330
|
+
"country",
|
|
12331
|
+
"data",
|
|
12332
|
+
"dial",
|
|
12333
|
+
"entry",
|
|
12334
|
+
"field",
|
|
12335
|
+
"forms",
|
|
12336
|
+
"input",
|
|
12337
|
+
"needs",
|
|
12338
|
+
"number",
|
|
12339
|
+
"only",
|
|
12340
|
+
"pairs",
|
|
12341
|
+
"phoneinput",
|
|
12342
|
+
"purpose",
|
|
12343
|
+
"select",
|
|
12344
|
+
"start",
|
|
12345
|
+
"telephone",
|
|
12346
|
+
"text",
|
|
12347
|
+
"the",
|
|
12348
|
+
"then",
|
|
12349
|
+
"when",
|
|
12350
|
+
"with"
|
|
12351
|
+
],
|
|
12352
|
+
"name": "PhoneInput",
|
|
12353
|
+
"props": [
|
|
12354
|
+
{
|
|
12355
|
+
"name": "class",
|
|
12356
|
+
"optional": true,
|
|
12357
|
+
"type": "string | null"
|
|
12358
|
+
},
|
|
12359
|
+
{
|
|
12360
|
+
"name": "className",
|
|
12361
|
+
"optional": true,
|
|
12362
|
+
"type": "string"
|
|
12363
|
+
},
|
|
12364
|
+
{
|
|
12365
|
+
"name": "countries",
|
|
12366
|
+
"optional": true,
|
|
12367
|
+
"type": "Country[]"
|
|
12368
|
+
},
|
|
12369
|
+
{
|
|
12370
|
+
"name": "countryLabel",
|
|
12371
|
+
"optional": true,
|
|
12372
|
+
"type": "string"
|
|
12373
|
+
},
|
|
12374
|
+
{
|
|
12375
|
+
"name": "countryName",
|
|
12376
|
+
"optional": true,
|
|
12377
|
+
"type": "string"
|
|
12378
|
+
},
|
|
12379
|
+
{
|
|
12380
|
+
"name": "countryValue",
|
|
12381
|
+
"optional": true,
|
|
12382
|
+
"type": "string"
|
|
12383
|
+
},
|
|
12384
|
+
{
|
|
12385
|
+
"name": "name",
|
|
12386
|
+
"optional": true,
|
|
12387
|
+
"type": "string"
|
|
12388
|
+
},
|
|
12389
|
+
{
|
|
12390
|
+
"name": "placeholder",
|
|
12391
|
+
"optional": true,
|
|
12392
|
+
"type": "string"
|
|
12393
|
+
},
|
|
12394
|
+
{
|
|
12395
|
+
"name": "size",
|
|
12396
|
+
"optional": true,
|
|
12397
|
+
"type": "'default' | 'lg' | 'sm'"
|
|
12398
|
+
},
|
|
12399
|
+
{
|
|
12400
|
+
"name": "value",
|
|
12401
|
+
"optional": true,
|
|
12402
|
+
"type": "string"
|
|
12403
|
+
}
|
|
12404
|
+
],
|
|
12405
|
+
"propsExtends": "Omit<HTMLAttributes<'div'>, 'size'>",
|
|
12406
|
+
"recipes": [],
|
|
12407
|
+
"runtimeEvents": []
|
|
12408
|
+
},
|
|
12409
|
+
{
|
|
12410
|
+
"apiReference": [
|
|
12411
|
+
{
|
|
12412
|
+
"attribute": "glass",
|
|
12413
|
+
"defaultValue": "false",
|
|
12414
|
+
"description": "Applies the tokenized liquid-glass surface treatment with backdrop-filter fallbacks; \"subtle\" and \"strong\" adjust the fill intensity.",
|
|
12415
|
+
"values": "boolean | \"subtle\" | \"strong\""
|
|
12416
|
+
},
|
|
12417
|
+
{
|
|
12418
|
+
"attribute": "series",
|
|
12419
|
+
"defaultValue": "required",
|
|
12420
|
+
"description": "Provides one already-aggregated series whose positive finite data points become slices.",
|
|
12421
|
+
"values": "LumenChartSeries"
|
|
12422
|
+
},
|
|
12423
|
+
{
|
|
12424
|
+
"attribute": "variant",
|
|
12425
|
+
"defaultValue": "\"donut\"",
|
|
12426
|
+
"description": "Uses a center opening by default or renders a traditional pie.",
|
|
12427
|
+
"values": "\"donut\" | \"pie\""
|
|
12428
|
+
},
|
|
12429
|
+
{
|
|
12430
|
+
"attribute": "centerLabel, centerValue",
|
|
12431
|
+
"defaultValue": "-",
|
|
12432
|
+
"description": "Adds optional visual summary content in the donut center.",
|
|
12433
|
+
"values": "string | ReactNode"
|
|
12434
|
+
},
|
|
12435
|
+
{
|
|
12436
|
+
"attribute": "showLegend",
|
|
12437
|
+
"defaultValue": "true",
|
|
12438
|
+
"description": "Shows the color-independent category key.",
|
|
12439
|
+
"values": "boolean"
|
|
12440
|
+
},
|
|
12441
|
+
{
|
|
12442
|
+
"attribute": "showTable",
|
|
12443
|
+
"defaultValue": "true",
|
|
12444
|
+
"description": "Provides a revealable semantic table with category, value, and share columns.",
|
|
12445
|
+
"values": "boolean"
|
|
12446
|
+
},
|
|
12447
|
+
{
|
|
12448
|
+
"attribute": "valueFormatter",
|
|
12449
|
+
"defaultValue": "String",
|
|
12450
|
+
"description": "Formats values in SVG titles and the semantic table for Astro and React; Web Components expose the equivalent JavaScript property.",
|
|
12451
|
+
"values": "(value: number) => string"
|
|
12452
|
+
},
|
|
12453
|
+
{
|
|
12454
|
+
"attribute": "class, className",
|
|
12455
|
+
"defaultValue": "\"\"",
|
|
12456
|
+
"description": "Merges custom classes with the generated ui-* root classes.",
|
|
12457
|
+
"values": "string"
|
|
12458
|
+
},
|
|
12459
|
+
{
|
|
12460
|
+
"attribute": "...native attributes",
|
|
12461
|
+
"defaultValue": "-",
|
|
12462
|
+
"description": "Forwards standard attributes to the root element unless the component consumes them.",
|
|
12463
|
+
"values": "HTML attributes"
|
|
12464
|
+
}
|
|
12465
|
+
],
|
|
12466
|
+
"astroSource": "---\nimport {\n createLumenPieGeometry,\n hasLumenPieData,\n type LumenChartSeries,\n type LumenPieChartVariant\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Chart from './Chart.astro'\n\ninterface Props extends HTMLAttributes<'figure'> {\n caption?: string\n centerLabel?: string\n centerValue?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n series: LumenChartSeries\n showLegend?: boolean\n showTable?: boolean\n valueFormatter?: (value: number) => string\n variant?: LumenPieChartVariant\n}\n\nconst {\n caption,\n centerLabel,\n centerValue,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n series,\n showLegend = true,\n showTable = true,\n valueFormatter = String,\n variant = 'donut',\n ...rest\n} = Astro.props\nconst geometry = createLumenPieGeometry(series.data, { variant })\nconst hasData = hasLumenPieData(series.data)\nconst percentageFor = (percentage: number) =>\n new Intl.NumberFormat(undefined, {\n maximumFractionDigits: percentage < 0.01 ? 1 : 0,\n style: 'percent'\n }).format(percentage)\n---\n\n<Chart\n class:list={['ui-pie-chart', `ui-pie-chart--${variant}`, classProp, className]}\n {caption}\n {description}\n {glass}\n {heading}\n {...rest}\n>\n {\n showLegend && hasData && (\n <ul class=\"ui-chart__legend\" aria-label=\"Chart legend\">\n {geometry.slices.map(slice => (\n <li class={`ui-chart-tone--${slice.tone}`}>\n <span aria-hidden=\"true\" />\n {slice.label}\n </li>\n ))}\n </ul>\n )\n }\n {!hasData && <p class=\"ui-chart__empty\" role=\"status\">No chart data available.</p>}\n <div class=\"ui-chart__plot ui-pie-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${geometry.size} ${geometry.size}`}\n >\n <g class=\"ui-pie-chart__slices\">\n {\n geometry.slices.map(slice => (\n <path\n class={`ui-chart-tone--${slice.tone}`}\n d={slice.path}\n fill-rule=\"evenodd\"\n >\n <title>\n {`${slice.label}: ${valueFormatter(slice.value)} (${percentageFor(slice.percentage)})`}\n </title>\n </path>\n ))\n }\n </g>\n </svg>\n {\n variant === 'donut' && (centerLabel != null || centerValue != null) && (\n <>\n <div class=\"ui-pie-chart__center\" aria-hidden=\"true\">\n {centerValue != null && <strong>{centerValue}</strong>}\n {centerLabel != null && <span>{centerLabel}</span>}\n </div>\n <div class=\"ui-sr-only\">\n {centerValue} {centerLabel}\n </div>\n </>\n )\n }\n </div>\n {\n showTable && hasData && (\n <details class=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n <th scope=\"col\">Value</th>\n <th scope=\"col\">Share</th>\n </tr>\n </thead>\n <tbody>\n {geometry.slices.map(slice => (\n <tr>\n <th scope=\"row\">{slice.label}</th>\n <td>{valueFormatter(slice.value)}</td>\n <td>{percentageFor(slice.percentage)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )\n }\n</Chart>\n",
|
|
12467
|
+
"category": "Data display",
|
|
12468
|
+
"collections": [
|
|
12469
|
+
"Data visualization"
|
|
12470
|
+
],
|
|
12471
|
+
"dependencies": [
|
|
12472
|
+
"Chart",
|
|
12473
|
+
"styles"
|
|
12474
|
+
],
|
|
12475
|
+
"description": "Shows part-to-whole relationships as an accessible donut or pie chart.",
|
|
12476
|
+
"files": [
|
|
12477
|
+
"packages/astro/components/PieChart.astro",
|
|
12478
|
+
"packages/astro/components/Chart.astro",
|
|
12479
|
+
"packages/astro/styles/lumen.css"
|
|
12480
|
+
],
|
|
12481
|
+
"frameworkDetails": {
|
|
12482
|
+
"astro": {
|
|
12483
|
+
"available": true,
|
|
12484
|
+
"example": "<PieChart aria-label=\"Framework share\" centerLabel=\"Projects\" centerValue=\"2,480\" heading=\"Framework usage\" series={{ id: \"frameworks\", label: \"Framework share\", data: [{ label: \"Astro\", x: \"astro\", y: 46 }, { label: \"React\", x: \"react\", y: 31 }, { label: \"Web Components\", x: \"elements\", y: 23 }] }} />",
|
|
12485
|
+
"importStatement": "import { PieChart } from '@santi020k/lumen-astro'",
|
|
12486
|
+
"language": "astro",
|
|
12487
|
+
"packageName": "@santi020k/lumen-astro",
|
|
12488
|
+
"props": [
|
|
12489
|
+
{
|
|
12490
|
+
"name": "caption",
|
|
12491
|
+
"optional": true,
|
|
12492
|
+
"type": "string"
|
|
12493
|
+
},
|
|
12494
|
+
{
|
|
12495
|
+
"name": "centerLabel",
|
|
12496
|
+
"optional": true,
|
|
12497
|
+
"type": "string"
|
|
12498
|
+
},
|
|
12499
|
+
{
|
|
12500
|
+
"name": "centerValue",
|
|
12501
|
+
"optional": true,
|
|
12502
|
+
"type": "string"
|
|
12503
|
+
},
|
|
12504
|
+
{
|
|
12505
|
+
"name": "class",
|
|
12506
|
+
"optional": true,
|
|
12507
|
+
"type": "string | null"
|
|
12508
|
+
},
|
|
12509
|
+
{
|
|
12510
|
+
"name": "className",
|
|
12511
|
+
"optional": true,
|
|
12512
|
+
"type": "string"
|
|
12513
|
+
},
|
|
12514
|
+
{
|
|
12515
|
+
"name": "description",
|
|
12516
|
+
"optional": true,
|
|
12517
|
+
"type": "string"
|
|
12518
|
+
},
|
|
12519
|
+
{
|
|
12520
|
+
"name": "glass",
|
|
12521
|
+
"optional": true,
|
|
12522
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
12523
|
+
},
|
|
12524
|
+
{
|
|
12525
|
+
"name": "heading",
|
|
12526
|
+
"optional": true,
|
|
12527
|
+
"type": "string"
|
|
12528
|
+
},
|
|
12529
|
+
{
|
|
12530
|
+
"name": "series",
|
|
12531
|
+
"optional": false,
|
|
12532
|
+
"type": "LumenChartSeries"
|
|
12533
|
+
},
|
|
12534
|
+
{
|
|
12535
|
+
"name": "showLegend",
|
|
12536
|
+
"optional": true,
|
|
12537
|
+
"type": "boolean"
|
|
12538
|
+
},
|
|
12539
|
+
{
|
|
12540
|
+
"name": "showTable",
|
|
12541
|
+
"optional": true,
|
|
12542
|
+
"type": "boolean"
|
|
12543
|
+
},
|
|
12544
|
+
{
|
|
12545
|
+
"name": "valueFormatter",
|
|
12546
|
+
"optional": true,
|
|
12547
|
+
"type": "(value: number) => string"
|
|
12548
|
+
},
|
|
12549
|
+
{
|
|
12550
|
+
"name": "variant",
|
|
12551
|
+
"optional": true,
|
|
12552
|
+
"type": "LumenPieChartVariant"
|
|
12553
|
+
}
|
|
12554
|
+
],
|
|
12555
|
+
"propsExtends": "HTMLAttributes<'figure'>",
|
|
12556
|
+
"source": "---\nimport {\n createLumenPieGeometry,\n hasLumenPieData,\n type LumenChartSeries,\n type LumenPieChartVariant\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\nimport Chart from './Chart.astro'\n\ninterface Props extends HTMLAttributes<'figure'> {\n caption?: string\n centerLabel?: string\n centerValue?: string\n class?: string | null\n className?: string\n description?: string\n glass?: boolean | 'subtle' | 'strong'\n heading?: string\n series: LumenChartSeries\n showLegend?: boolean\n showTable?: boolean\n valueFormatter?: (value: number) => string\n variant?: LumenPieChartVariant\n}\n\nconst {\n caption,\n centerLabel,\n centerValue,\n class: classProp = '',\n className = '',\n description,\n glass = false,\n heading,\n series,\n showLegend = true,\n showTable = true,\n valueFormatter = String,\n variant = 'donut',\n ...rest\n} = Astro.props\nconst geometry = createLumenPieGeometry(series.data, { variant })\nconst hasData = hasLumenPieData(series.data)\nconst percentageFor = (percentage: number) =>\n new Intl.NumberFormat(undefined, {\n maximumFractionDigits: percentage < 0.01 ? 1 : 0,\n style: 'percent'\n }).format(percentage)\n---\n\n<Chart\n class:list={['ui-pie-chart', `ui-pie-chart--${variant}`, classProp, className]}\n {caption}\n {description}\n {glass}\n {heading}\n {...rest}\n>\n {\n showLegend && hasData && (\n <ul class=\"ui-chart__legend\" aria-label=\"Chart legend\">\n {geometry.slices.map(slice => (\n <li class={`ui-chart-tone--${slice.tone}`}>\n <span aria-hidden=\"true\" />\n {slice.label}\n </li>\n ))}\n </ul>\n )\n }\n {!hasData && <p class=\"ui-chart__empty\" role=\"status\">No chart data available.</p>}\n <div class=\"ui-chart__plot ui-pie-chart__plot\" hidden={!hasData}>\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${geometry.size} ${geometry.size}`}\n >\n <g class=\"ui-pie-chart__slices\">\n {\n geometry.slices.map(slice => (\n <path\n class={`ui-chart-tone--${slice.tone}`}\n d={slice.path}\n fill-rule=\"evenodd\"\n >\n <title>\n {`${slice.label}: ${valueFormatter(slice.value)} (${percentageFor(slice.percentage)})`}\n </title>\n </path>\n ))\n }\n </g>\n </svg>\n {\n variant === 'donut' && (centerLabel != null || centerValue != null) && (\n <>\n <div class=\"ui-pie-chart__center\" aria-hidden=\"true\">\n {centerValue != null && <strong>{centerValue}</strong>}\n {centerLabel != null && <span>{centerLabel}</span>}\n </div>\n <div class=\"ui-sr-only\">\n {centerValue} {centerLabel}\n </div>\n </>\n )\n }\n </div>\n {\n showTable && hasData && (\n <details class=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n <th scope=\"col\">Value</th>\n <th scope=\"col\">Share</th>\n </tr>\n </thead>\n <tbody>\n {geometry.slices.map(slice => (\n <tr>\n <th scope=\"row\">{slice.label}</th>\n <td>{valueFormatter(slice.value)}</td>\n <td>{percentageFor(slice.percentage)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )\n }\n</Chart>\n",
|
|
12557
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
12558
|
+
},
|
|
12559
|
+
"elements": {
|
|
12560
|
+
"attributes": [
|
|
12561
|
+
"variant",
|
|
12562
|
+
"glass",
|
|
12563
|
+
"series",
|
|
12564
|
+
"centerLabel, centerValue",
|
|
12565
|
+
"showLegend",
|
|
12566
|
+
"showTable",
|
|
12567
|
+
"valueFormatter",
|
|
12568
|
+
"class, className",
|
|
12569
|
+
"...native attributes"
|
|
12570
|
+
],
|
|
12571
|
+
"available": true,
|
|
12572
|
+
"behavior": {
|
|
12573
|
+
"mode": "registration",
|
|
12574
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
12575
|
+
},
|
|
12576
|
+
"example": "<lumen-pie-chart></lumen-pie-chart>",
|
|
12577
|
+
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
12578
|
+
"language": "html",
|
|
12579
|
+
"packageName": "@santi020k/lumen-elements",
|
|
12580
|
+
"props": [],
|
|
12581
|
+
"propsExtends": "HTMLElement attributes",
|
|
12582
|
+
"registration": "defineLumenElements()",
|
|
12583
|
+
"source": "PieChart: {\n attributeClasses: {\n ...glassAttributeClasses('ui-chart--glass'),\n variant: {\n donut: 'ui-pie-chart--donut',\n pie: 'ui-pie-chart--pie'\n }\n },\n baseClassName: 'ui-chart ui-pie-chart',\n defaults: { variant: 'donut' },\n role: 'figure',\n tagName: 'lumen-pie-chart'\n }",
|
|
12584
|
+
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
12585
|
+
"tagName": "lumen-pie-chart"
|
|
12586
|
+
},
|
|
12587
|
+
"react": {
|
|
12588
|
+
"available": true,
|
|
12589
|
+
"example": "<PieChart aria-label=\"Framework share\" centerLabel=\"Projects\" centerValue=\"2,480\" heading=\"Framework usage\" series={{ id: \"frameworks\", label: \"Framework share\", data: [{ label: \"Astro\", x: \"astro\", y: 46 }, { label: \"React\", x: \"react\", y: 31 }, { label: \"Web Components\", x: \"elements\", y: 23 }] }} />",
|
|
12590
|
+
"importStatement": "import { PieChart } from '@santi020k/lumen-react'",
|
|
12591
|
+
"language": "tsx",
|
|
12592
|
+
"packageName": "@santi020k/lumen-react",
|
|
12593
|
+
"props": [
|
|
12594
|
+
{
|
|
12595
|
+
"name": "centerLabel",
|
|
12596
|
+
"optional": true,
|
|
12597
|
+
"type": "ReactNode"
|
|
12598
|
+
},
|
|
12599
|
+
{
|
|
12600
|
+
"name": "centerValue",
|
|
12601
|
+
"optional": true,
|
|
12602
|
+
"type": "ReactNode"
|
|
12603
|
+
},
|
|
12604
|
+
{
|
|
12605
|
+
"name": "series",
|
|
12606
|
+
"optional": true,
|
|
12607
|
+
"type": "LumenChartSeries"
|
|
12608
|
+
},
|
|
12609
|
+
{
|
|
12610
|
+
"name": "showLegend",
|
|
12611
|
+
"optional": true,
|
|
12612
|
+
"type": "boolean"
|
|
12613
|
+
},
|
|
12614
|
+
{
|
|
12615
|
+
"name": "showTable",
|
|
11196
12616
|
"optional": true,
|
|
11197
|
-
"type": "
|
|
12617
|
+
"type": "boolean"
|
|
11198
12618
|
},
|
|
11199
12619
|
{
|
|
11200
|
-
"name": "
|
|
12620
|
+
"name": "valueFormatter",
|
|
11201
12621
|
"optional": true,
|
|
11202
|
-
"type": "string"
|
|
12622
|
+
"type": "(value: number) => string"
|
|
11203
12623
|
},
|
|
11204
12624
|
{
|
|
11205
|
-
"name": "
|
|
12625
|
+
"name": "variant",
|
|
11206
12626
|
"optional": true,
|
|
11207
|
-
"type": "
|
|
12627
|
+
"type": "LumenPieChartVariant"
|
|
11208
12628
|
}
|
|
11209
12629
|
],
|
|
11210
|
-
"propsExtends": "Omit<
|
|
11211
|
-
"source": "export interface
|
|
12630
|
+
"propsExtends": "Omit<ChartProps, 'children'>",
|
|
12631
|
+
"source": "export interface PieChartProps extends Omit<ChartProps, 'children'> {\n centerLabel?: ReactNode\n centerValue?: ReactNode\n series?: LumenChartSeries\n showLegend?: boolean\n showTable?: boolean\n valueFormatter?: (value: number) => string\n variant?: LumenPieChartVariant\n}\n\nexport const PieChart = ({\n centerLabel,\n centerValue,\n className,\n series = emptyPieSeries,\n showLegend = true,\n showTable = true,\n valueFormatter = String,\n variant = 'donut',\n ...props\n}: PieChartProps) => {\n const geometry = createLumenPieGeometry(series.data, { variant })\n const hasData = hasLumenPieData(series.data)\n\n return (\n <Chart\n className={composeClassName('ui-pie-chart', `ui-pie-chart--${variant}`, className)}\n {...props}\n >\n {showLegend && hasData && (\n <ul aria-label=\"Chart legend\" className=\"ui-chart__legend\">\n {geometry.slices.map(slice => (\n <li\n className={`ui-chart-tone--${slice.tone}`}\n key={`${typeof slice.x}:${String(slice.x)}`}\n >\n <span aria-hidden=\"true\" />\n {slice.label}\n </li>\n ))}\n </ul>\n )}\n {!hasData && (\n <p className=\"ui-chart__empty\" role=\"status\">No chart data available.</p>\n )}\n <div\n className=\"ui-chart__plot ui-pie-chart__plot\"\n hidden={!hasData}\n >\n <svg\n aria-hidden=\"true\"\n preserveAspectRatio=\"xMidYMid meet\"\n viewBox={`0 0 ${geometry.size} ${geometry.size}`}\n >\n <g className=\"ui-pie-chart__slices\">\n {geometry.slices.map(slice => (\n <path\n className={`ui-chart-tone--${slice.tone}`}\n d={slice.path}\n fillRule=\"evenodd\"\n key={`${typeof slice.x}:${String(slice.x)}`}\n >\n <title>\n {`${slice.label}: ${valueFormatter(slice.value)} (${formatChartPercentage(slice.percentage)})`}\n </title>\n </path>\n ))}\n </g>\n </svg>\n {variant === 'donut' && (centerLabel != null || centerValue != null) && (\n <>\n <div aria-hidden=\"true\" className=\"ui-pie-chart__center\">\n {centerValue != null && <strong>{centerValue}</strong>}\n {centerLabel != null && <span>{centerLabel}</span>}\n </div>\n <div className=\"ui-sr-only\">\n {centerValue} {centerLabel}\n </div>\n </>\n )}\n </div>\n {showTable && hasData && (\n <details className=\"ui-chart__data\">\n <summary>View chart data</summary>\n <div>\n <table>\n <thead>\n <tr>\n <th scope=\"col\">Category</th>\n <th scope=\"col\">Value</th>\n <th scope=\"col\">Share</th>\n </tr>\n </thead>\n <tbody>\n {geometry.slices.map(slice => (\n <tr key={`${typeof slice.x}:${String(slice.x)}`}>\n <th scope=\"row\">{slice.label}</th>\n <td>{valueFormatter(slice.value)}</td>\n <td>{formatChartPercentage(slice.percentage)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n </details>\n )}\n </Chart>\n )\n}",
|
|
11212
12632
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
11213
12633
|
}
|
|
11214
12634
|
},
|
|
@@ -11217,90 +12637,144 @@
|
|
|
11217
12637
|
"elements": true,
|
|
11218
12638
|
"react": true
|
|
11219
12639
|
},
|
|
11220
|
-
"guidance":
|
|
11221
|
-
|
|
12640
|
+
"guidance": {
|
|
12641
|
+
"when": "Use for a part-to-whole breakdown with one series, non-negative values, and a small number of meaningful categories.",
|
|
12642
|
+
"distinction": "Prefer the default donut for a center total. Use BarChart when precise comparison or more than roughly seven categories matters, and do not use PieChart for negative values or change over time."
|
|
12643
|
+
},
|
|
12644
|
+
"kebab": "pie-chart",
|
|
11222
12645
|
"keyboardInteractions": [],
|
|
11223
12646
|
"keywords": [
|
|
11224
|
-
"
|
|
11225
|
-
"
|
|
11226
|
-
"
|
|
11227
|
-
"
|
|
12647
|
+
"accessible",
|
|
12648
|
+
"and",
|
|
12649
|
+
"barchart",
|
|
12650
|
+
"breakdown",
|
|
12651
|
+
"breakdowns",
|
|
12652
|
+
"categorical",
|
|
12653
|
+
"categories",
|
|
12654
|
+
"center",
|
|
12655
|
+
"change",
|
|
12656
|
+
"chart",
|
|
12657
|
+
"compact",
|
|
12658
|
+
"comparison",
|
|
12659
|
+
"comparisons",
|
|
12660
|
+
"custom",
|
|
11228
12661
|
"data",
|
|
11229
|
-
"
|
|
11230
|
-
"
|
|
11231
|
-
"
|
|
11232
|
-
"
|
|
11233
|
-
"
|
|
11234
|
-
"
|
|
12662
|
+
"default",
|
|
12663
|
+
"display",
|
|
12664
|
+
"donut",
|
|
12665
|
+
"for",
|
|
12666
|
+
"match",
|
|
12667
|
+
"matters",
|
|
12668
|
+
"meaningful",
|
|
12669
|
+
"metrics",
|
|
12670
|
+
"more",
|
|
12671
|
+
"negative",
|
|
12672
|
+
"non",
|
|
12673
|
+
"not",
|
|
11235
12674
|
"number",
|
|
11236
|
-
"
|
|
11237
|
-
"
|
|
11238
|
-
"
|
|
11239
|
-
"
|
|
11240
|
-
"
|
|
11241
|
-
"
|
|
11242
|
-
"
|
|
11243
|
-
"
|
|
12675
|
+
"one",
|
|
12676
|
+
"ordered",
|
|
12677
|
+
"over",
|
|
12678
|
+
"part",
|
|
12679
|
+
"pie",
|
|
12680
|
+
"piechart",
|
|
12681
|
+
"plots",
|
|
12682
|
+
"precise",
|
|
12683
|
+
"prefer",
|
|
12684
|
+
"question",
|
|
12685
|
+
"relationships",
|
|
12686
|
+
"roughly",
|
|
12687
|
+
"series",
|
|
12688
|
+
"seven",
|
|
12689
|
+
"shows",
|
|
12690
|
+
"small",
|
|
12691
|
+
"than",
|
|
11244
12692
|
"the",
|
|
11245
|
-
"
|
|
12693
|
+
"time",
|
|
12694
|
+
"total",
|
|
12695
|
+
"trends",
|
|
12696
|
+
"use",
|
|
12697
|
+
"values",
|
|
12698
|
+
"visualization",
|
|
11246
12699
|
"when",
|
|
12700
|
+
"whole",
|
|
11247
12701
|
"with"
|
|
11248
12702
|
],
|
|
11249
|
-
"name": "
|
|
12703
|
+
"name": "PieChart",
|
|
11250
12704
|
"props": [
|
|
11251
12705
|
{
|
|
11252
|
-
"name": "
|
|
12706
|
+
"name": "caption",
|
|
11253
12707
|
"optional": true,
|
|
11254
|
-
"type": "string
|
|
12708
|
+
"type": "string"
|
|
11255
12709
|
},
|
|
11256
12710
|
{
|
|
11257
|
-
"name": "
|
|
12711
|
+
"name": "centerLabel",
|
|
11258
12712
|
"optional": true,
|
|
11259
12713
|
"type": "string"
|
|
11260
12714
|
},
|
|
11261
12715
|
{
|
|
11262
|
-
"name": "
|
|
12716
|
+
"name": "centerValue",
|
|
11263
12717
|
"optional": true,
|
|
11264
|
-
"type": "
|
|
12718
|
+
"type": "string"
|
|
11265
12719
|
},
|
|
11266
12720
|
{
|
|
11267
|
-
"name": "
|
|
12721
|
+
"name": "class",
|
|
11268
12722
|
"optional": true,
|
|
11269
|
-
"type": "string"
|
|
12723
|
+
"type": "string | null"
|
|
11270
12724
|
},
|
|
11271
12725
|
{
|
|
11272
|
-
"name": "
|
|
12726
|
+
"name": "className",
|
|
11273
12727
|
"optional": true,
|
|
11274
12728
|
"type": "string"
|
|
11275
12729
|
},
|
|
11276
12730
|
{
|
|
11277
|
-
"name": "
|
|
12731
|
+
"name": "description",
|
|
11278
12732
|
"optional": true,
|
|
11279
12733
|
"type": "string"
|
|
11280
12734
|
},
|
|
11281
12735
|
{
|
|
11282
|
-
"name": "
|
|
12736
|
+
"name": "glass",
|
|
11283
12737
|
"optional": true,
|
|
11284
|
-
"type": "
|
|
12738
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
11285
12739
|
},
|
|
11286
12740
|
{
|
|
11287
|
-
"name": "
|
|
12741
|
+
"name": "heading",
|
|
11288
12742
|
"optional": true,
|
|
11289
12743
|
"type": "string"
|
|
11290
12744
|
},
|
|
11291
12745
|
{
|
|
11292
|
-
"name": "
|
|
12746
|
+
"name": "series",
|
|
12747
|
+
"optional": false,
|
|
12748
|
+
"type": "LumenChartSeries"
|
|
12749
|
+
},
|
|
12750
|
+
{
|
|
12751
|
+
"name": "showLegend",
|
|
11293
12752
|
"optional": true,
|
|
11294
|
-
"type": "
|
|
12753
|
+
"type": "boolean"
|
|
11295
12754
|
},
|
|
11296
12755
|
{
|
|
11297
|
-
"name": "
|
|
12756
|
+
"name": "showTable",
|
|
11298
12757
|
"optional": true,
|
|
11299
|
-
"type": "
|
|
12758
|
+
"type": "boolean"
|
|
12759
|
+
},
|
|
12760
|
+
{
|
|
12761
|
+
"name": "valueFormatter",
|
|
12762
|
+
"optional": true,
|
|
12763
|
+
"type": "(value: number) => string"
|
|
12764
|
+
},
|
|
12765
|
+
{
|
|
12766
|
+
"name": "variant",
|
|
12767
|
+
"optional": true,
|
|
12768
|
+
"type": "LumenPieChartVariant"
|
|
12769
|
+
}
|
|
12770
|
+
],
|
|
12771
|
+
"propsExtends": "HTMLAttributes<'figure'>",
|
|
12772
|
+
"recipes": [
|
|
12773
|
+
{
|
|
12774
|
+
"name": "data-visualization",
|
|
12775
|
+
"type": "recipe"
|
|
11300
12776
|
}
|
|
11301
12777
|
],
|
|
11302
|
-
"propsExtends": "Omit<HTMLAttributes<'div'>, 'size'>",
|
|
11303
|
-
"recipes": [],
|
|
11304
12778
|
"runtimeEvents": []
|
|
11305
12779
|
},
|
|
11306
12780
|
{
|
|
@@ -11317,6 +12791,12 @@
|
|
|
11317
12791
|
"description": "Renders the pill as a focusable anchor when it represents a destination.",
|
|
11318
12792
|
"values": "string"
|
|
11319
12793
|
},
|
|
12794
|
+
{
|
|
12795
|
+
"attribute": "variant",
|
|
12796
|
+
"defaultValue": "\"neutral\"",
|
|
12797
|
+
"description": "Controls the pill emphasis without changing its metadata semantics.",
|
|
12798
|
+
"values": "\"neutral\" | \"brand\" | \"outline\""
|
|
12799
|
+
},
|
|
11320
12800
|
{
|
|
11321
12801
|
"attribute": "class, className",
|
|
11322
12802
|
"defaultValue": "\"\"",
|
|
@@ -11330,7 +12810,7 @@
|
|
|
11330
12810
|
"values": "HTML attributes"
|
|
11331
12811
|
}
|
|
11332
12812
|
],
|
|
11333
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n count?: number | string\n href?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n count,\n href,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-pill'
|
|
12813
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n count?: number | string\n href?: string\n variant?: 'brand' | 'neutral' | 'outline'\n}\n\nconst {\n class: classProp = '',\n className = '',\n count,\n href,\n variant = 'neutral',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-pill',\n variant !== 'neutral' && `ui-pill--${variant}`\n], classProp, className)\n---\n\n{href\n ? <a class:list={classList} data-variant={variant} href={href} {...passthrough}>\n <slot />\n {count != null && <span class=\"ui-pill__count\">{count}</span>}\n </a>\n : <span class:list={classList} data-variant={variant} {...passthrough}>\n <slot />\n {count != null && <span class=\"ui-pill__count\">{count}</span>}\n </span>\n}\n",
|
|
11334
12814
|
"category": "Data display",
|
|
11335
12815
|
"collections": [],
|
|
11336
12816
|
"dependencies": [
|
|
@@ -11344,7 +12824,7 @@
|
|
|
11344
12824
|
"frameworkDetails": {
|
|
11345
12825
|
"astro": {
|
|
11346
12826
|
"available": true,
|
|
11347
|
-
"example": "<Pill count={12}>Notifications</Pill>",
|
|
12827
|
+
"example": "<Pill count={12} variant=\"brand\">Notifications</Pill>",
|
|
11348
12828
|
"importStatement": "import { Pill } from '@santi020k/lumen-astro'",
|
|
11349
12829
|
"language": "astro",
|
|
11350
12830
|
"packageName": "@santi020k/lumen-astro",
|
|
@@ -11368,14 +12848,20 @@
|
|
|
11368
12848
|
"name": "href",
|
|
11369
12849
|
"optional": true,
|
|
11370
12850
|
"type": "string"
|
|
12851
|
+
},
|
|
12852
|
+
{
|
|
12853
|
+
"name": "variant",
|
|
12854
|
+
"optional": true,
|
|
12855
|
+
"type": "'brand' | 'neutral' | 'outline'"
|
|
11371
12856
|
}
|
|
11372
12857
|
],
|
|
11373
12858
|
"propsExtends": "HTMLAttributes<'span'>",
|
|
11374
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n count?: number | string\n href?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n count,\n href,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-pill'
|
|
12859
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n class?: string | null\n className?: string\n count?: number | string\n href?: string\n variant?: 'brand' | 'neutral' | 'outline'\n}\n\nconst {\n class: classProp = '',\n className = '',\n count,\n href,\n variant = 'neutral',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-pill',\n variant !== 'neutral' && `ui-pill--${variant}`\n], classProp, className)\n---\n\n{href\n ? <a class:list={classList} data-variant={variant} href={href} {...passthrough}>\n <slot />\n {count != null && <span class=\"ui-pill__count\">{count}</span>}\n </a>\n : <span class:list={classList} data-variant={variant} {...passthrough}>\n <slot />\n {count != null && <span class=\"ui-pill__count\">{count}</span>}\n </span>\n}\n",
|
|
11375
12860
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
11376
12861
|
},
|
|
11377
12862
|
"elements": {
|
|
11378
12863
|
"attributes": [
|
|
12864
|
+
"variant",
|
|
11379
12865
|
"count",
|
|
11380
12866
|
"href",
|
|
11381
12867
|
"class, className",
|
|
@@ -11386,20 +12872,20 @@
|
|
|
11386
12872
|
"mode": "registration",
|
|
11387
12873
|
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
11388
12874
|
},
|
|
11389
|
-
"example": "<lumen-pill count=\"12\">Notifications</lumen-pill>",
|
|
12875
|
+
"example": "<lumen-pill count=\"12\" variant=\"brand\">Notifications</lumen-pill>",
|
|
11390
12876
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
11391
12877
|
"language": "html",
|
|
11392
12878
|
"packageName": "@santi020k/lumen-elements",
|
|
11393
12879
|
"props": [],
|
|
11394
12880
|
"propsExtends": "HTMLElement attributes",
|
|
11395
12881
|
"registration": "defineLumenElements()",
|
|
11396
|
-
"source": "Pill: { baseClassName: 'ui-pill'
|
|
12882
|
+
"source": "Pill: {\n attributeClasses: {\n variant: {\n brand: 'ui-pill--brand',\n outline: 'ui-pill--outline'\n }\n },\n baseClassName: 'ui-pill',\n defaults: { variant: 'neutral' },\n tagName: 'lumen-pill'\n }",
|
|
11397
12883
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
11398
12884
|
"tagName": "lumen-pill"
|
|
11399
12885
|
},
|
|
11400
12886
|
"react": {
|
|
11401
12887
|
"available": true,
|
|
11402
|
-
"example": "<Pill count={12}>Notifications</Pill>",
|
|
12888
|
+
"example": "<Pill count={12} variant=\"brand\">Notifications</Pill>",
|
|
11403
12889
|
"importStatement": "import { Pill } from '@santi020k/lumen-react'",
|
|
11404
12890
|
"language": "tsx",
|
|
11405
12891
|
"packageName": "@santi020k/lumen-react",
|
|
@@ -11413,10 +12899,15 @@
|
|
|
11413
12899
|
"name": "href",
|
|
11414
12900
|
"optional": true,
|
|
11415
12901
|
"type": "string"
|
|
12902
|
+
},
|
|
12903
|
+
{
|
|
12904
|
+
"name": "variant",
|
|
12905
|
+
"optional": true,
|
|
12906
|
+
"type": "'brand' | 'neutral' | 'outline'"
|
|
11416
12907
|
}
|
|
11417
12908
|
],
|
|
11418
12909
|
"propsExtends": "ComponentPropsWithoutRef<'span'>",
|
|
11419
|
-
"source": "export type PillProps = ComponentPropsWithoutRef<'span'> & {\n count?: number | string\n href?: string\n}\n\nexport const Pill = ({
|
|
12910
|
+
"source": "export type PillProps = ComponentPropsWithoutRef<'span'> & {\n count?: number | string\n href?: string\n variant?: 'brand' | 'neutral' | 'outline'\n}\n\nexport const Pill = ({\n className,\n count,\n children,\n href,\n variant = 'neutral',\n ...props\n}: PillProps) => {\n const content = (\n <>\n {children}\n {count !== undefined && <span className=\"ui-pill__count\">{count}</span>}\n </>\n )\n\n return href\n ? (\n <a\n className={composeClassName('ui-pill', variantClass('ui-pill', variant, 'neutral'), className)}\n data-variant={variant}\n href={href}\n {...props}\n >\n {content}\n </a>\n )\n : (\n <span\n className={composeClassName('ui-pill', variantClass('ui-pill', variant, 'neutral'), className)}\n data-variant={variant}\n {...props}\n >\n {content}\n </span>\n )\n}",
|
|
11420
12911
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
11421
12912
|
}
|
|
11422
12913
|
},
|
|
@@ -11481,6 +12972,11 @@
|
|
|
11481
12972
|
"name": "href",
|
|
11482
12973
|
"optional": true,
|
|
11483
12974
|
"type": "string"
|
|
12975
|
+
},
|
|
12976
|
+
{
|
|
12977
|
+
"name": "variant",
|
|
12978
|
+
"optional": true,
|
|
12979
|
+
"type": "'brand' | 'neutral' | 'outline'"
|
|
11484
12980
|
}
|
|
11485
12981
|
],
|
|
11486
12982
|
"propsExtends": "HTMLAttributes<'span'>",
|
|
@@ -11906,7 +13402,7 @@
|
|
|
11906
13402
|
},
|
|
11907
13403
|
"guidance": {
|
|
11908
13404
|
"when": "Use to communicate how much of a task, upload, or process has completed.",
|
|
11909
|
-
"distinction": "Use Meter for a stable measurement, Spinner for indeterminate short waits, or Skeleton while page structure is loading."
|
|
13405
|
+
"distinction": "Use ScrollProgress for document position, Meter for a stable measurement, Spinner for indeterminate short waits, or Skeleton while page structure is loading."
|
|
11910
13406
|
},
|
|
11911
13407
|
"kebab": "progress",
|
|
11912
13408
|
"keyboardInteractions": [],
|
|
@@ -11914,6 +13410,7 @@
|
|
|
11914
13410
|
"communicate",
|
|
11915
13411
|
"completed",
|
|
11916
13412
|
"completion",
|
|
13413
|
+
"document",
|
|
11917
13414
|
"feedback",
|
|
11918
13415
|
"for",
|
|
11919
13416
|
"has",
|
|
@@ -11924,9 +13421,11 @@
|
|
|
11924
13421
|
"meter",
|
|
11925
13422
|
"much",
|
|
11926
13423
|
"page",
|
|
13424
|
+
"position",
|
|
11927
13425
|
"process",
|
|
11928
13426
|
"progress",
|
|
11929
13427
|
"quota",
|
|
13428
|
+
"scrollprogress",
|
|
11930
13429
|
"short",
|
|
11931
13430
|
"shows",
|
|
11932
13431
|
"skeleton",
|
|
@@ -12888,22 +14387,175 @@
|
|
|
12888
14387
|
"values": "HTML attributes"
|
|
12889
14388
|
}
|
|
12890
14389
|
],
|
|
12891
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-scroll-area',\n glass && 'ui-scroll-area--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<div\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
12892
|
-
"category": "Layout",
|
|
12893
|
-
"collections": [],
|
|
14390
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-scroll-area',\n glass && 'ui-scroll-area--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<div\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
14391
|
+
"category": "Layout",
|
|
14392
|
+
"collections": [],
|
|
14393
|
+
"dependencies": [
|
|
14394
|
+
"styles"
|
|
14395
|
+
],
|
|
14396
|
+
"description": "Provides a styled scroll container.",
|
|
14397
|
+
"files": [
|
|
14398
|
+
"packages/astro/components/ScrollArea.astro",
|
|
14399
|
+
"packages/astro/styles/lumen.css"
|
|
14400
|
+
],
|
|
14401
|
+
"frameworkDetails": {
|
|
14402
|
+
"astro": {
|
|
14403
|
+
"available": true,
|
|
14404
|
+
"example": "<ScrollArea style=\"max-height: 18rem\"><p>Long release notes...</p></ScrollArea>",
|
|
14405
|
+
"importStatement": "import { ScrollArea } from '@santi020k/lumen-astro'",
|
|
14406
|
+
"language": "astro",
|
|
14407
|
+
"packageName": "@santi020k/lumen-astro",
|
|
14408
|
+
"props": [
|
|
14409
|
+
{
|
|
14410
|
+
"name": "class",
|
|
14411
|
+
"optional": true,
|
|
14412
|
+
"type": "string | null"
|
|
14413
|
+
},
|
|
14414
|
+
{
|
|
14415
|
+
"name": "className",
|
|
14416
|
+
"optional": true,
|
|
14417
|
+
"type": "string"
|
|
14418
|
+
},
|
|
14419
|
+
{
|
|
14420
|
+
"name": "glass",
|
|
14421
|
+
"optional": true,
|
|
14422
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
14423
|
+
}
|
|
14424
|
+
],
|
|
14425
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
14426
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n glass?: boolean | 'subtle' | 'strong'\n}\n\nconst {\n class: classProp = '',\n className = '',\n glass = false,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-scroll-area',\n glass && 'ui-scroll-area--glass',\n glass === 'subtle' && 'ui-glass-subtle',\n glass === 'strong' && 'ui-glass-strong'\n], classProp, className)\n---\n\n<div\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
14427
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
14428
|
+
},
|
|
14429
|
+
"elements": {
|
|
14430
|
+
"attributes": [
|
|
14431
|
+
"glass",
|
|
14432
|
+
"children",
|
|
14433
|
+
"class, className",
|
|
14434
|
+
"...native attributes"
|
|
14435
|
+
],
|
|
14436
|
+
"available": true,
|
|
14437
|
+
"behavior": {
|
|
14438
|
+
"mode": "registration",
|
|
14439
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
14440
|
+
},
|
|
14441
|
+
"example": "<lumen-scroll-area style=\"max-height: 18rem\"><p>Long release notes...</p></lumen-scroll-area>",
|
|
14442
|
+
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
14443
|
+
"language": "html",
|
|
14444
|
+
"packageName": "@santi020k/lumen-elements",
|
|
14445
|
+
"props": [],
|
|
14446
|
+
"propsExtends": "HTMLElement attributes",
|
|
14447
|
+
"registration": "defineLumenElements()",
|
|
14448
|
+
"source": "ScrollArea: { attributeClasses: glassAttributeClasses('ui-scroll-area--glass'), baseClassName: 'ui-scroll-area', tagName: 'lumen-scroll-area' }",
|
|
14449
|
+
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
14450
|
+
"tagName": "lumen-scroll-area"
|
|
14451
|
+
},
|
|
14452
|
+
"react": {
|
|
14453
|
+
"available": true,
|
|
14454
|
+
"example": "<ScrollArea style={{ maxHeight: '18rem' }}><p>Long release notes...</p></ScrollArea>",
|
|
14455
|
+
"importStatement": "import { ScrollArea } from '@santi020k/lumen-react'",
|
|
14456
|
+
"language": "tsx",
|
|
14457
|
+
"packageName": "@santi020k/lumen-react",
|
|
14458
|
+
"props": [
|
|
14459
|
+
{
|
|
14460
|
+
"name": "glass",
|
|
14461
|
+
"optional": true,
|
|
14462
|
+
"type": "LumenGlassProp"
|
|
14463
|
+
}
|
|
14464
|
+
],
|
|
14465
|
+
"propsExtends": "ComponentPropsWithoutRef<'div'>",
|
|
14466
|
+
"source": "export interface ScrollAreaProps extends ComponentPropsWithoutRef<'div'> {\n glass?: LumenGlassProp\n}\n\nexport const ScrollArea = ({ className, glass = false, ...props }: ScrollAreaProps) => (\n <div className={composeClassName('ui-scroll-area', glassClass('ui-scroll-area', glass), className)} {...props} />\n)",
|
|
14467
|
+
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
14468
|
+
}
|
|
14469
|
+
},
|
|
14470
|
+
"frameworks": {
|
|
14471
|
+
"astro": true,
|
|
14472
|
+
"elements": true,
|
|
14473
|
+
"react": true
|
|
14474
|
+
},
|
|
14475
|
+
"guidance": null,
|
|
14476
|
+
"kebab": "scroll-area",
|
|
14477
|
+
"keyboardInteractions": [],
|
|
14478
|
+
"keywords": [
|
|
14479
|
+
"container",
|
|
14480
|
+
"layout",
|
|
14481
|
+
"provides",
|
|
14482
|
+
"scroll",
|
|
14483
|
+
"scrollarea",
|
|
14484
|
+
"styled"
|
|
14485
|
+
],
|
|
14486
|
+
"name": "ScrollArea",
|
|
14487
|
+
"props": [
|
|
14488
|
+
{
|
|
14489
|
+
"name": "class",
|
|
14490
|
+
"optional": true,
|
|
14491
|
+
"type": "string | null"
|
|
14492
|
+
},
|
|
14493
|
+
{
|
|
14494
|
+
"name": "className",
|
|
14495
|
+
"optional": true,
|
|
14496
|
+
"type": "string"
|
|
14497
|
+
},
|
|
14498
|
+
{
|
|
14499
|
+
"name": "glass",
|
|
14500
|
+
"optional": true,
|
|
14501
|
+
"type": "boolean | 'subtle' | 'strong'"
|
|
14502
|
+
}
|
|
14503
|
+
],
|
|
14504
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
14505
|
+
"recipes": [],
|
|
14506
|
+
"runtimeEvents": []
|
|
14507
|
+
},
|
|
14508
|
+
{
|
|
14509
|
+
"apiReference": [
|
|
14510
|
+
{
|
|
14511
|
+
"attribute": "position",
|
|
14512
|
+
"defaultValue": "\"top\"",
|
|
14513
|
+
"description": "Pins the progress indicator to a viewport edge.",
|
|
14514
|
+
"values": "\"top\" | \"bottom\""
|
|
14515
|
+
},
|
|
14516
|
+
{
|
|
14517
|
+
"attribute": "aria-label",
|
|
14518
|
+
"defaultValue": "\"Reading progress\"",
|
|
14519
|
+
"description": "Names the live document-progress indicator for assistive technology.",
|
|
14520
|
+
"values": "string"
|
|
14521
|
+
},
|
|
14522
|
+
{
|
|
14523
|
+
"attribute": "class, className",
|
|
14524
|
+
"defaultValue": "\"\"",
|
|
14525
|
+
"description": "Merges custom classes with the generated ui-* root classes.",
|
|
14526
|
+
"values": "string"
|
|
14527
|
+
},
|
|
14528
|
+
{
|
|
14529
|
+
"attribute": "...native attributes",
|
|
14530
|
+
"defaultValue": "-",
|
|
14531
|
+
"description": "Forwards standard attributes to the root element unless the component consumes them.",
|
|
14532
|
+
"values": "HTML attributes"
|
|
14533
|
+
}
|
|
14534
|
+
],
|
|
14535
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n position?: 'bottom' | 'top'\n}\n\nconst {\n 'aria-label': ariaLabel = 'Reading progress',\n class: classProp = '',\n className = '',\n position = 'top',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-scroll-progress',\n position === 'bottom' && 'ui-scroll-progress--bottom'\n], classProp, className)\n---\n\n<div\n aria-label={ariaLabel}\n aria-valuemax=\"100\"\n aria-valuemin=\"0\"\n aria-valuenow=\"0\"\n class:list={classList}\n data-position={position}\n data-ui-scroll-progress\n role=\"progressbar\"\n {...passthrough}\n>\n <span class=\"ui-scroll-progress__bar\"></span>\n</div>\n",
|
|
14536
|
+
"category": "Feedback",
|
|
14537
|
+
"collections": [
|
|
14538
|
+
"Status and messaging"
|
|
14539
|
+
],
|
|
12894
14540
|
"dependencies": [
|
|
12895
|
-
"styles"
|
|
14541
|
+
"styles",
|
|
14542
|
+
"runtime"
|
|
12896
14543
|
],
|
|
12897
|
-
"description": "
|
|
14544
|
+
"description": "Shows the reader’s current position in a long document.",
|
|
12898
14545
|
"files": [
|
|
12899
|
-
"packages/astro/components/
|
|
12900
|
-
"packages/astro/styles/lumen.css"
|
|
14546
|
+
"packages/astro/components/ScrollProgress.astro",
|
|
14547
|
+
"packages/astro/styles/lumen.css",
|
|
14548
|
+
"packages/astro/runtime/UIPrimitives.astro"
|
|
12901
14549
|
],
|
|
12902
14550
|
"frameworkDetails": {
|
|
12903
14551
|
"astro": {
|
|
12904
14552
|
"available": true,
|
|
12905
|
-
"
|
|
12906
|
-
|
|
14553
|
+
"behavior": {
|
|
14554
|
+
"mode": "runtime",
|
|
14555
|
+
"setup": "Mount UIPrimitives once in the application's root layout; do not mount it beside each component."
|
|
14556
|
+
},
|
|
14557
|
+
"example": "<ScrollProgress aria-label=\"Article reading progress\" />",
|
|
14558
|
+
"importStatement": "import { ScrollProgress } from '@santi020k/lumen-astro'",
|
|
12907
14559
|
"language": "astro",
|
|
12908
14560
|
"packageName": "@santi020k/lumen-astro",
|
|
12909
14561
|
"props": [
|
|
@@ -12918,53 +14570,62 @@
|
|
|
12918
14570
|
"type": "string"
|
|
12919
14571
|
},
|
|
12920
14572
|
{
|
|
12921
|
-
"name": "
|
|
14573
|
+
"name": "position",
|
|
12922
14574
|
"optional": true,
|
|
12923
|
-
"type": "
|
|
14575
|
+
"type": "'bottom' | 'top'"
|
|
12924
14576
|
}
|
|
12925
14577
|
],
|
|
12926
14578
|
"propsExtends": "HTMLAttributes<'div'>",
|
|
12927
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n
|
|
14579
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n position?: 'bottom' | 'top'\n}\n\nconst {\n 'aria-label': ariaLabel = 'Reading progress',\n class: classProp = '',\n className = '',\n position = 'top',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-scroll-progress',\n position === 'bottom' && 'ui-scroll-progress--bottom'\n], classProp, className)\n---\n\n<div\n aria-label={ariaLabel}\n aria-valuemax=\"100\"\n aria-valuemin=\"0\"\n aria-valuenow=\"0\"\n class:list={classList}\n data-position={position}\n data-ui-scroll-progress\n role=\"progressbar\"\n {...passthrough}\n>\n <span class=\"ui-scroll-progress__bar\"></span>\n</div>\n",
|
|
12928
14580
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
12929
14581
|
},
|
|
12930
14582
|
"elements": {
|
|
12931
14583
|
"attributes": [
|
|
12932
|
-
"
|
|
12933
|
-
"
|
|
14584
|
+
"aria-label",
|
|
14585
|
+
"aria-valuemax",
|
|
14586
|
+
"aria-valuemin",
|
|
14587
|
+
"aria-valuenow",
|
|
14588
|
+
"data-ui-scroll-progress",
|
|
14589
|
+
"position",
|
|
14590
|
+
"role",
|
|
12934
14591
|
"class, className",
|
|
12935
14592
|
"...native attributes"
|
|
12936
14593
|
],
|
|
12937
14594
|
"available": true,
|
|
12938
14595
|
"behavior": {
|
|
12939
14596
|
"mode": "registration",
|
|
12940
|
-
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
14597
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements. Registration includes this component’s interactive behavior."
|
|
12941
14598
|
},
|
|
12942
|
-
"example": "<lumen-scroll-
|
|
14599
|
+
"example": "<lumen-scroll-progress aria-label=\"Article reading progress\"></lumen-scroll-progress>",
|
|
12943
14600
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
12944
14601
|
"language": "html",
|
|
12945
14602
|
"packageName": "@santi020k/lumen-elements",
|
|
12946
14603
|
"props": [],
|
|
12947
14604
|
"propsExtends": "HTMLElement attributes",
|
|
12948
14605
|
"registration": "defineLumenElements()",
|
|
12949
|
-
"source": "
|
|
14606
|
+
"source": "ScrollProgress: {\n attributeClasses: {\n position: { bottom: 'ui-scroll-progress--bottom' }\n },\n baseClassName: 'ui-scroll-progress',\n defaults: {\n 'aria-label': 'Reading progress',\n 'aria-valuemax': '100',\n 'aria-valuemin': '0',\n 'aria-valuenow': '0',\n 'data-ui-scroll-progress': '',\n position: 'top',\n role: 'progressbar'\n },\n tagName: 'lumen-scroll-progress'\n }",
|
|
12950
14607
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
12951
|
-
"tagName": "lumen-scroll-
|
|
14608
|
+
"tagName": "lumen-scroll-progress"
|
|
12952
14609
|
},
|
|
12953
14610
|
"react": {
|
|
12954
14611
|
"available": true,
|
|
12955
|
-
"
|
|
12956
|
-
|
|
14612
|
+
"behavior": {
|
|
14613
|
+
"mode": "built-in",
|
|
14614
|
+
"setup": "Interactive behavior is implemented by the React component; do not mount Astro UIPrimitives."
|
|
14615
|
+
},
|
|
14616
|
+
"example": "<ScrollProgress aria-label=\"Article reading progress\" />",
|
|
14617
|
+
"importStatement": "import { ScrollProgress } from '@santi020k/lumen-react'",
|
|
12957
14618
|
"language": "tsx",
|
|
12958
14619
|
"packageName": "@santi020k/lumen-react",
|
|
12959
14620
|
"props": [
|
|
12960
14621
|
{
|
|
12961
|
-
"name": "
|
|
14622
|
+
"name": "position",
|
|
12962
14623
|
"optional": true,
|
|
12963
|
-
"type": "
|
|
14624
|
+
"type": "'bottom' | 'top'"
|
|
12964
14625
|
}
|
|
12965
14626
|
],
|
|
12966
14627
|
"propsExtends": "ComponentPropsWithoutRef<'div'>",
|
|
12967
|
-
"source": "export interface
|
|
14628
|
+
"source": "export interface ScrollProgressProps extends ComponentPropsWithoutRef<'div'> {\n position?: 'bottom' | 'top'\n}\n\nexport const ScrollProgress = ({\n 'aria-label': ariaLabel = 'Reading progress',\n className,\n position = 'top',\n ...props\n}: ScrollProgressProps) => {\n const rootRef = useRef<HTMLDivElement>(null)\n\n useEffect(() => {\n const root = rootRef.current\n\n if (!root) return\n\n let frame = 0\n\n const update = () => {\n frame = 0\n\n const scrollingElement = document.scrollingElement ?? document.documentElement\n const maximum = scrollingElement.scrollHeight - scrollingElement.clientHeight\n\n const percentage = maximum > 0\n ? Math.min(100, Math.max(0, (scrollingElement.scrollTop / maximum) * 100))\n : 0\n\n const bar = root.querySelector<HTMLElement>('.ui-scroll-progress__bar')\n\n root.setAttribute('aria-valuenow', `${Math.round(percentage)}`)\n\n if (bar) bar.style.transform = `scaleX(${percentage / 100})`\n }\n\n const scheduleUpdate = () => {\n if (frame) return\n\n frame = window.requestAnimationFrame(update)\n }\n\n scheduleUpdate()\n\n window.addEventListener('resize', scheduleUpdate, { passive: true })\n\n window.addEventListener('scroll', scheduleUpdate, { passive: true })\n\n return () => {\n if (frame) window.cancelAnimationFrame(frame)\n\n window.removeEventListener('resize', scheduleUpdate)\n\n window.removeEventListener('scroll', scheduleUpdate)\n }\n }, [])\n\n return (\n <div\n aria-label={ariaLabel}\n aria-valuemax={100}\n aria-valuemin={0}\n aria-valuenow={0}\n className={composeClassName(\n 'ui-scroll-progress',\n position === 'bottom' && 'ui-scroll-progress--bottom',\n className\n )}\n data-position={position}\n data-ui-scroll-progress\n ref={rootRef}\n role=\"progressbar\"\n {...props}\n >\n <span className=\"ui-scroll-progress__bar\" />\n </div>\n )\n}",
|
|
12968
14629
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
12969
14630
|
}
|
|
12970
14631
|
},
|
|
@@ -12973,18 +14634,60 @@
|
|
|
12973
14634
|
"elements": true,
|
|
12974
14635
|
"react": true
|
|
12975
14636
|
},
|
|
12976
|
-
"guidance":
|
|
12977
|
-
|
|
14637
|
+
"guidance": {
|
|
14638
|
+
"when": "Use on long reading surfaces when readers benefit from knowing how far they have moved through the current document.",
|
|
14639
|
+
"distinction": "Use Progress for task completion supplied by application state. ScrollProgress derives its value from the document scroll position."
|
|
14640
|
+
},
|
|
14641
|
+
"kebab": "scroll-progress",
|
|
12978
14642
|
"keyboardInteractions": [],
|
|
12979
14643
|
"keywords": [
|
|
12980
|
-
"
|
|
12981
|
-
"
|
|
12982
|
-
"
|
|
14644
|
+
"and",
|
|
14645
|
+
"application",
|
|
14646
|
+
"benefit",
|
|
14647
|
+
"completion",
|
|
14648
|
+
"current",
|
|
14649
|
+
"derives",
|
|
14650
|
+
"document",
|
|
14651
|
+
"empty",
|
|
14652
|
+
"far",
|
|
14653
|
+
"feedback",
|
|
14654
|
+
"for",
|
|
14655
|
+
"from",
|
|
14656
|
+
"guidance",
|
|
14657
|
+
"have",
|
|
14658
|
+
"how",
|
|
14659
|
+
"inline",
|
|
14660
|
+
"its",
|
|
14661
|
+
"knowing",
|
|
14662
|
+
"long",
|
|
14663
|
+
"messaging",
|
|
14664
|
+
"moved",
|
|
14665
|
+
"notifications",
|
|
14666
|
+
"persistent",
|
|
14667
|
+
"position",
|
|
14668
|
+
"progress",
|
|
14669
|
+
"reader",
|
|
14670
|
+
"readers",
|
|
14671
|
+
"reading",
|
|
12983
14672
|
"scroll",
|
|
12984
|
-
"
|
|
12985
|
-
"
|
|
14673
|
+
"scrollprogress",
|
|
14674
|
+
"separate",
|
|
14675
|
+
"shows",
|
|
14676
|
+
"state",
|
|
14677
|
+
"states",
|
|
14678
|
+
"status",
|
|
14679
|
+
"supplied",
|
|
14680
|
+
"surfaces",
|
|
14681
|
+
"task",
|
|
14682
|
+
"the",
|
|
14683
|
+
"they",
|
|
14684
|
+
"through",
|
|
14685
|
+
"transient",
|
|
14686
|
+
"use",
|
|
14687
|
+
"value",
|
|
14688
|
+
"when"
|
|
12986
14689
|
],
|
|
12987
|
-
"name": "
|
|
14690
|
+
"name": "ScrollProgress",
|
|
12988
14691
|
"props": [
|
|
12989
14692
|
{
|
|
12990
14693
|
"name": "class",
|
|
@@ -12997,9 +14700,9 @@
|
|
|
12997
14700
|
"type": "string"
|
|
12998
14701
|
},
|
|
12999
14702
|
{
|
|
13000
|
-
"name": "
|
|
14703
|
+
"name": "position",
|
|
13001
14704
|
"optional": true,
|
|
13002
|
-
"type": "
|
|
14705
|
+
"type": "'bottom' | 'top'"
|
|
13003
14706
|
}
|
|
13004
14707
|
],
|
|
13005
14708
|
"propsExtends": "HTMLAttributes<'div'>",
|
|
@@ -14872,47 +16575,224 @@
|
|
|
14872
16575
|
"name": "Slider",
|
|
14873
16576
|
"props": [
|
|
14874
16577
|
{
|
|
14875
|
-
"name": "class",
|
|
14876
|
-
"optional": true,
|
|
14877
|
-
"type": "string | null"
|
|
16578
|
+
"name": "class",
|
|
16579
|
+
"optional": true,
|
|
16580
|
+
"type": "string | null"
|
|
16581
|
+
},
|
|
16582
|
+
{
|
|
16583
|
+
"name": "className",
|
|
16584
|
+
"optional": true,
|
|
16585
|
+
"type": "string"
|
|
16586
|
+
}
|
|
16587
|
+
],
|
|
16588
|
+
"propsExtends": "HTMLAttributes<'input'>",
|
|
16589
|
+
"recipes": [],
|
|
16590
|
+
"runtimeEvents": []
|
|
16591
|
+
},
|
|
16592
|
+
{
|
|
16593
|
+
"apiReference": [],
|
|
16594
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n maxCount?: number\n placement?: 'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right'\n}\n\nconst {\n 'aria-atomic': ariaAtomic = 'false',\n 'aria-live': ariaLive = 'polite',\n class: classProp = '',\n className = '',\n maxCount,\n placement = 'bottom-right',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-sonner'\n], classProp, className)\n---\n\n<div\n aria-atomic={ariaAtomic}\n aria-live={ariaLive}\n data-ui-sonner\n data-ui-toast-max={maxCount}\n data-placement={placement}\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
16595
|
+
"category": "Feedback",
|
|
16596
|
+
"collections": [],
|
|
16597
|
+
"dependencies": [
|
|
16598
|
+
"styles",
|
|
16599
|
+
"runtime"
|
|
16600
|
+
],
|
|
16601
|
+
"description": "Provides the toast viewport for notifications.",
|
|
16602
|
+
"files": [
|
|
16603
|
+
"packages/astro/components/Sonner.astro",
|
|
16604
|
+
"packages/astro/styles/lumen.css",
|
|
16605
|
+
"packages/astro/runtime/UIPrimitives.astro"
|
|
16606
|
+
],
|
|
16607
|
+
"frameworkDetails": {
|
|
16608
|
+
"astro": {
|
|
16609
|
+
"available": true,
|
|
16610
|
+
"behavior": {
|
|
16611
|
+
"mode": "runtime",
|
|
16612
|
+
"setup": "Mount UIPrimitives once in the application's root layout; do not mount it beside each component."
|
|
16613
|
+
},
|
|
16614
|
+
"example": "<Sonner />",
|
|
16615
|
+
"importStatement": "import { Sonner } from '@santi020k/lumen-astro'",
|
|
16616
|
+
"language": "astro",
|
|
16617
|
+
"packageName": "@santi020k/lumen-astro",
|
|
16618
|
+
"props": [
|
|
16619
|
+
{
|
|
16620
|
+
"name": "class",
|
|
16621
|
+
"optional": true,
|
|
16622
|
+
"type": "string | null"
|
|
16623
|
+
},
|
|
16624
|
+
{
|
|
16625
|
+
"name": "className",
|
|
16626
|
+
"optional": true,
|
|
16627
|
+
"type": "string"
|
|
16628
|
+
},
|
|
16629
|
+
{
|
|
16630
|
+
"name": "maxCount",
|
|
16631
|
+
"optional": true,
|
|
16632
|
+
"type": "number"
|
|
16633
|
+
},
|
|
16634
|
+
{
|
|
16635
|
+
"name": "placement",
|
|
16636
|
+
"optional": true,
|
|
16637
|
+
"type": "'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right'"
|
|
16638
|
+
}
|
|
16639
|
+
],
|
|
16640
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
16641
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n maxCount?: number\n placement?: 'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right'\n}\n\nconst {\n 'aria-atomic': ariaAtomic = 'false',\n 'aria-live': ariaLive = 'polite',\n class: classProp = '',\n className = '',\n maxCount,\n placement = 'bottom-right',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-sonner'\n], classProp, className)\n---\n\n<div\n aria-atomic={ariaAtomic}\n aria-live={ariaLive}\n data-ui-sonner\n data-ui-toast-max={maxCount}\n data-placement={placement}\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
16642
|
+
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
16643
|
+
},
|
|
16644
|
+
"elements": {
|
|
16645
|
+
"attributes": [
|
|
16646
|
+
"data-ui-sonner"
|
|
16647
|
+
],
|
|
16648
|
+
"available": true,
|
|
16649
|
+
"behavior": {
|
|
16650
|
+
"mode": "registration",
|
|
16651
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements. Registration includes this component’s interactive behavior."
|
|
16652
|
+
},
|
|
16653
|
+
"example": "<lumen-sonner></lumen-sonner>",
|
|
16654
|
+
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
16655
|
+
"language": "html",
|
|
16656
|
+
"packageName": "@santi020k/lumen-elements",
|
|
16657
|
+
"props": [],
|
|
16658
|
+
"propsExtends": "HTMLElement attributes",
|
|
16659
|
+
"registration": "defineLumenElements()",
|
|
16660
|
+
"source": "Sonner: { baseClassName: 'ui-sonner', defaults: { 'data-ui-sonner': '' }, tagName: 'lumen-sonner' }",
|
|
16661
|
+
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
16662
|
+
"tagName": "lumen-sonner"
|
|
16663
|
+
},
|
|
16664
|
+
"react": {
|
|
16665
|
+
"available": true,
|
|
16666
|
+
"behavior": {
|
|
16667
|
+
"mode": "adapter",
|
|
16668
|
+
"setup": "The React component exposes the documented data attributes; app-level state must implement the documented interactive and event behavior. Do not mount Astro UIPrimitives."
|
|
16669
|
+
},
|
|
16670
|
+
"example": "<Sonner />",
|
|
16671
|
+
"importStatement": "import { Sonner } from '@santi020k/lumen-react'",
|
|
16672
|
+
"language": "tsx",
|
|
16673
|
+
"packageName": "@santi020k/lumen-react",
|
|
16674
|
+
"props": [],
|
|
16675
|
+
"propsExtends": "ComponentPropsWithoutRef<'div'>",
|
|
16676
|
+
"source": "export type SonnerProps = ComponentPropsWithoutRef<'div'>\n\nexport const Sonner = ({ className, ...props }: SonnerProps) => (\n <div className={composeClassName('ui-sonner', className)} data-ui-sonner {...props} />\n)",
|
|
16677
|
+
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
16678
|
+
}
|
|
16679
|
+
},
|
|
16680
|
+
"frameworks": {
|
|
16681
|
+
"astro": true,
|
|
16682
|
+
"elements": true,
|
|
16683
|
+
"react": true
|
|
16684
|
+
},
|
|
16685
|
+
"guidance": null,
|
|
16686
|
+
"kebab": "sonner",
|
|
16687
|
+
"keyboardInteractions": [],
|
|
16688
|
+
"keywords": [
|
|
16689
|
+
"feedback",
|
|
16690
|
+
"for",
|
|
16691
|
+
"notifications",
|
|
16692
|
+
"provides",
|
|
16693
|
+
"sonner",
|
|
16694
|
+
"the",
|
|
16695
|
+
"toast",
|
|
16696
|
+
"viewport"
|
|
16697
|
+
],
|
|
16698
|
+
"name": "Sonner",
|
|
16699
|
+
"props": [
|
|
16700
|
+
{
|
|
16701
|
+
"name": "class",
|
|
16702
|
+
"optional": true,
|
|
16703
|
+
"type": "string | null"
|
|
16704
|
+
},
|
|
16705
|
+
{
|
|
16706
|
+
"name": "className",
|
|
16707
|
+
"optional": true,
|
|
16708
|
+
"type": "string"
|
|
16709
|
+
},
|
|
16710
|
+
{
|
|
16711
|
+
"name": "maxCount",
|
|
16712
|
+
"optional": true,
|
|
16713
|
+
"type": "number"
|
|
16714
|
+
},
|
|
16715
|
+
{
|
|
16716
|
+
"name": "placement",
|
|
16717
|
+
"optional": true,
|
|
16718
|
+
"type": "'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right'"
|
|
16719
|
+
}
|
|
16720
|
+
],
|
|
16721
|
+
"propsExtends": "HTMLAttributes<'div'>",
|
|
16722
|
+
"recipes": [],
|
|
16723
|
+
"runtimeEvents": []
|
|
16724
|
+
},
|
|
16725
|
+
{
|
|
16726
|
+
"apiReference": [
|
|
16727
|
+
{
|
|
16728
|
+
"attribute": "values",
|
|
16729
|
+
"defaultValue": "required",
|
|
16730
|
+
"description": "Provides ordered values for the compact trend.",
|
|
16731
|
+
"values": "number[]"
|
|
16732
|
+
},
|
|
16733
|
+
{
|
|
16734
|
+
"attribute": "label",
|
|
16735
|
+
"defaultValue": "required",
|
|
16736
|
+
"description": "Communicates the trend in text because the SVG is intentionally decorative.",
|
|
16737
|
+
"values": "string"
|
|
16738
|
+
},
|
|
16739
|
+
{
|
|
16740
|
+
"attribute": "area",
|
|
16741
|
+
"defaultValue": "false",
|
|
16742
|
+
"description": "Adds a subtle tokenized fill below the line.",
|
|
16743
|
+
"values": "boolean"
|
|
14878
16744
|
},
|
|
14879
16745
|
{
|
|
14880
|
-
"
|
|
14881
|
-
"
|
|
14882
|
-
"
|
|
16746
|
+
"attribute": "showEndpoint",
|
|
16747
|
+
"defaultValue": "true",
|
|
16748
|
+
"description": "Marks the latest value with a color-independent endpoint.",
|
|
16749
|
+
"values": "boolean"
|
|
16750
|
+
},
|
|
16751
|
+
{
|
|
16752
|
+
"attribute": "tone",
|
|
16753
|
+
"defaultValue": "\"series-1\"",
|
|
16754
|
+
"description": "Selects a categorical or explicitly semantic chart tone.",
|
|
16755
|
+
"values": "LumenChartTone"
|
|
16756
|
+
},
|
|
16757
|
+
{
|
|
16758
|
+
"attribute": "class, className",
|
|
16759
|
+
"defaultValue": "\"\"",
|
|
16760
|
+
"description": "Merges custom classes with the generated ui-* root classes.",
|
|
16761
|
+
"values": "string"
|
|
16762
|
+
},
|
|
16763
|
+
{
|
|
16764
|
+
"attribute": "...native attributes",
|
|
16765
|
+
"defaultValue": "-",
|
|
16766
|
+
"description": "Forwards standard attributes to the root element unless the component consumes them.",
|
|
16767
|
+
"values": "HTML attributes"
|
|
14883
16768
|
}
|
|
14884
16769
|
],
|
|
14885
|
-
"
|
|
14886
|
-
"
|
|
14887
|
-
"
|
|
14888
|
-
|
|
14889
|
-
|
|
14890
|
-
"apiReference": [],
|
|
14891
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n maxCount?: number\n placement?: 'bottom-center' | 'bottom-left' | 'bottom-right' | 'top-center' | 'top-left' | 'top-right'\n}\n\nconst {\n 'aria-atomic': ariaAtomic = 'false',\n 'aria-live': ariaLive = 'polite',\n class: classProp = '',\n className = '',\n maxCount,\n placement = 'bottom-right',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-sonner'\n], classProp, className)\n---\n\n<div\n aria-atomic={ariaAtomic}\n aria-live={ariaLive}\n data-ui-sonner\n data-ui-toast-max={maxCount}\n data-placement={placement}\n class:list={classList}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
14892
|
-
"category": "Feedback",
|
|
14893
|
-
"collections": [],
|
|
16770
|
+
"astroSource": "---\nimport {\n composeClassName,\n createLumenLineGeometry,\n type LumenChartTone,\n resolveLumenChartTone\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n area?: boolean\n class?: string | null\n className?: string\n label: string\n showEndpoint?: boolean\n tone?: LumenChartTone\n values: readonly number[]\n}\n\nconst {\n area = false,\n class: classProp = '',\n className = '',\n label,\n showEndpoint = true,\n tone,\n values,\n ...rest\n} = Astro.props\nconst data = values.map((value, index) => ({ x: index, y: value }))\nconst geometry = createLumenLineGeometry(data, {\n height: 40,\n padding: 3,\n width: 120\n})\nconst resolvedTone = resolveLumenChartTone(tone)\nconst endpoint = geometry.points[geometry.points.length - 1]\n---\n\n<span\n aria-label={label}\n class={composeClassName(\n 'ui-sparkline',\n `ui-chart-tone--${resolvedTone}`,\n classProp,\n className\n )}\n role=\"img\"\n {...rest}\n>\n <svg aria-hidden=\"true\" preserveAspectRatio=\"none\" viewBox=\"0 0 120 40\">\n {\n area &&\n geometry.areaPaths.map((path) => (\n <path class=\"ui-sparkline__area\" d={path} />\n ))\n }\n <path class=\"ui-sparkline__line\" d={geometry.path} />\n {\n showEndpoint && endpoint && (\n <circle\n class=\"ui-sparkline__endpoint\"\n cx={endpoint.xCoordinate}\n cy={endpoint.yCoordinate}\n r=\"2.5\"\n />\n )\n }\n </svg>\n <span class=\"ui-sr-only\">{label}</span>\n</span>\n",
|
|
16771
|
+
"category": "Data display",
|
|
16772
|
+
"collections": [
|
|
16773
|
+
"Data visualization"
|
|
16774
|
+
],
|
|
14894
16775
|
"dependencies": [
|
|
14895
|
-
"styles"
|
|
14896
|
-
"runtime"
|
|
16776
|
+
"styles"
|
|
14897
16777
|
],
|
|
14898
|
-
"description": "
|
|
16778
|
+
"description": "Shows a compact, text-labelled trend beside an existing metric.",
|
|
14899
16779
|
"files": [
|
|
14900
|
-
"packages/astro/components/
|
|
14901
|
-
"packages/astro/styles/lumen.css"
|
|
14902
|
-
"packages/astro/runtime/UIPrimitives.astro"
|
|
16780
|
+
"packages/astro/components/Sparkline.astro",
|
|
16781
|
+
"packages/astro/styles/lumen.css"
|
|
14903
16782
|
],
|
|
14904
16783
|
"frameworkDetails": {
|
|
14905
16784
|
"astro": {
|
|
14906
16785
|
"available": true,
|
|
14907
|
-
"
|
|
14908
|
-
|
|
14909
|
-
"setup": "Mount UIPrimitives once in the application's root layout; do not mount it beside each component."
|
|
14910
|
-
},
|
|
14911
|
-
"example": "<Sonner />",
|
|
14912
|
-
"importStatement": "import { Sonner } from '@santi020k/lumen-astro'",
|
|
16786
|
+
"example": "<Sparkline label=\"Downloads increased from 42 to 91\" values={[42, 48, 63, 58, 74, 91]} area />",
|
|
16787
|
+
"importStatement": "import { Sparkline } from '@santi020k/lumen-astro'",
|
|
14913
16788
|
"language": "astro",
|
|
14914
16789
|
"packageName": "@santi020k/lumen-astro",
|
|
14915
16790
|
"props": [
|
|
16791
|
+
{
|
|
16792
|
+
"name": "area",
|
|
16793
|
+
"optional": true,
|
|
16794
|
+
"type": "boolean"
|
|
16795
|
+
},
|
|
14916
16796
|
{
|
|
14917
16797
|
"name": "class",
|
|
14918
16798
|
"optional": true,
|
|
@@ -14924,53 +16804,91 @@
|
|
|
14924
16804
|
"type": "string"
|
|
14925
16805
|
},
|
|
14926
16806
|
{
|
|
14927
|
-
"name": "
|
|
16807
|
+
"name": "label",
|
|
16808
|
+
"optional": false,
|
|
16809
|
+
"type": "string"
|
|
16810
|
+
},
|
|
16811
|
+
{
|
|
16812
|
+
"name": "showEndpoint",
|
|
14928
16813
|
"optional": true,
|
|
14929
|
-
"type": "
|
|
16814
|
+
"type": "boolean"
|
|
14930
16815
|
},
|
|
14931
16816
|
{
|
|
14932
|
-
"name": "
|
|
16817
|
+
"name": "tone",
|
|
14933
16818
|
"optional": true,
|
|
14934
|
-
"type": "
|
|
16819
|
+
"type": "LumenChartTone"
|
|
16820
|
+
},
|
|
16821
|
+
{
|
|
16822
|
+
"name": "values",
|
|
16823
|
+
"optional": false,
|
|
16824
|
+
"type": "readonly number[]"
|
|
14935
16825
|
}
|
|
14936
16826
|
],
|
|
14937
|
-
"propsExtends": "HTMLAttributes<'
|
|
14938
|
-
"source": "---\nimport {
|
|
16827
|
+
"propsExtends": "HTMLAttributes<'span'>",
|
|
16828
|
+
"source": "---\nimport {\n composeClassName,\n createLumenLineGeometry,\n type LumenChartTone,\n resolveLumenChartTone\n} from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'span'> {\n area?: boolean\n class?: string | null\n className?: string\n label: string\n showEndpoint?: boolean\n tone?: LumenChartTone\n values: readonly number[]\n}\n\nconst {\n area = false,\n class: classProp = '',\n className = '',\n label,\n showEndpoint = true,\n tone,\n values,\n ...rest\n} = Astro.props\nconst data = values.map((value, index) => ({ x: index, y: value }))\nconst geometry = createLumenLineGeometry(data, {\n height: 40,\n padding: 3,\n width: 120\n})\nconst resolvedTone = resolveLumenChartTone(tone)\nconst endpoint = geometry.points[geometry.points.length - 1]\n---\n\n<span\n aria-label={label}\n class={composeClassName(\n 'ui-sparkline',\n `ui-chart-tone--${resolvedTone}`,\n classProp,\n className\n )}\n role=\"img\"\n {...rest}\n>\n <svg aria-hidden=\"true\" preserveAspectRatio=\"none\" viewBox=\"0 0 120 40\">\n {\n area &&\n geometry.areaPaths.map((path) => (\n <path class=\"ui-sparkline__area\" d={path} />\n ))\n }\n <path class=\"ui-sparkline__line\" d={geometry.path} />\n {\n showEndpoint && endpoint && (\n <circle\n class=\"ui-sparkline__endpoint\"\n cx={endpoint.xCoordinate}\n cy={endpoint.yCoordinate}\n r=\"2.5\"\n />\n )\n }\n </svg>\n <span class=\"ui-sr-only\">{label}</span>\n</span>\n",
|
|
14939
16829
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
14940
16830
|
},
|
|
14941
16831
|
"elements": {
|
|
14942
16832
|
"attributes": [
|
|
14943
|
-
"
|
|
16833
|
+
"values",
|
|
16834
|
+
"label",
|
|
16835
|
+
"area",
|
|
16836
|
+
"showEndpoint",
|
|
16837
|
+
"tone",
|
|
16838
|
+
"class, className",
|
|
16839
|
+
"...native attributes"
|
|
14944
16840
|
],
|
|
14945
16841
|
"available": true,
|
|
14946
16842
|
"behavior": {
|
|
14947
16843
|
"mode": "registration",
|
|
14948
|
-
"setup": "Call defineLumenElements() once before rendering Lumen custom elements.
|
|
16844
|
+
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
14949
16845
|
},
|
|
14950
|
-
"example": "<lumen-
|
|
16846
|
+
"example": "<lumen-sparkline></lumen-sparkline>",
|
|
14951
16847
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
14952
16848
|
"language": "html",
|
|
14953
16849
|
"packageName": "@santi020k/lumen-elements",
|
|
14954
16850
|
"props": [],
|
|
14955
16851
|
"propsExtends": "HTMLElement attributes",
|
|
14956
16852
|
"registration": "defineLumenElements()",
|
|
14957
|
-
"source": "
|
|
16853
|
+
"source": "Sparkline: { baseClassName: 'ui-sparkline', tagName: 'lumen-sparkline' }",
|
|
14958
16854
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
14959
|
-
"tagName": "lumen-
|
|
16855
|
+
"tagName": "lumen-sparkline"
|
|
14960
16856
|
},
|
|
14961
16857
|
"react": {
|
|
14962
16858
|
"available": true,
|
|
14963
|
-
"
|
|
14964
|
-
|
|
14965
|
-
"setup": "The React component exposes the documented data attributes; app-level state must implement the documented interactive and event behavior. Do not mount Astro UIPrimitives."
|
|
14966
|
-
},
|
|
14967
|
-
"example": "<Sonner />",
|
|
14968
|
-
"importStatement": "import { Sonner } from '@santi020k/lumen-react'",
|
|
16859
|
+
"example": "<Sparkline label=\"Downloads increased from 42 to 91\" values={[42, 48, 63, 58, 74, 91]} area />",
|
|
16860
|
+
"importStatement": "import { Sparkline } from '@santi020k/lumen-react'",
|
|
14969
16861
|
"language": "tsx",
|
|
14970
16862
|
"packageName": "@santi020k/lumen-react",
|
|
14971
|
-
"props": [
|
|
14972
|
-
|
|
14973
|
-
|
|
16863
|
+
"props": [
|
|
16864
|
+
{
|
|
16865
|
+
"name": "area",
|
|
16866
|
+
"optional": true,
|
|
16867
|
+
"type": "boolean"
|
|
16868
|
+
},
|
|
16869
|
+
{
|
|
16870
|
+
"name": "label",
|
|
16871
|
+
"optional": true,
|
|
16872
|
+
"type": "string"
|
|
16873
|
+
},
|
|
16874
|
+
{
|
|
16875
|
+
"name": "showEndpoint",
|
|
16876
|
+
"optional": true,
|
|
16877
|
+
"type": "boolean"
|
|
16878
|
+
},
|
|
16879
|
+
{
|
|
16880
|
+
"name": "tone",
|
|
16881
|
+
"optional": true,
|
|
16882
|
+
"type": "LumenChartTone"
|
|
16883
|
+
},
|
|
16884
|
+
{
|
|
16885
|
+
"name": "values",
|
|
16886
|
+
"optional": true,
|
|
16887
|
+
"type": "readonly number[]"
|
|
16888
|
+
}
|
|
16889
|
+
],
|
|
16890
|
+
"propsExtends": "Omit<ComponentPropsWithoutRef<'span'>, 'children'>",
|
|
16891
|
+
"source": "export interface SparklineProps extends Omit<ComponentPropsWithoutRef<'span'>, 'children'> {\n area?: boolean\n label?: string\n showEndpoint?: boolean\n tone?: LumenChartTone\n values?: readonly number[]\n}\n\nexport const Sparkline = ({\n area = false,\n className,\n label = 'Trend',\n showEndpoint = true,\n tone,\n values = emptyChartValues,\n ...props\n}: SparklineProps) => {\n const geometry = createLumenLineGeometry(\n values.map((value, index) => ({ x: index, y: value })),\n { height: 40, padding: 3, width: 120 }\n )\n\n const resolvedTone = resolveLumenChartTone(tone)\n const endpoint = geometry.points.at(-1)\n\n return (\n <span\n aria-label={label}\n className={composeClassName('ui-sparkline', `ui-chart-tone--${resolvedTone}`, className)}\n role=\"img\"\n {...props}\n >\n <svg aria-hidden=\"true\" preserveAspectRatio=\"none\" viewBox=\"0 0 120 40\">\n {area && geometry.areaPaths.map(path => (\n <path className=\"ui-sparkline__area\" d={path} key={path} />\n ))}\n <path className=\"ui-sparkline__line\" d={geometry.path} />\n {showEndpoint && endpoint && (\n <circle\n className=\"ui-sparkline__endpoint\"\n cx={endpoint.xCoordinate}\n cy={endpoint.yCoordinate}\n r=\"2.5\"\n />\n )}\n </svg>\n <span className=\"ui-sr-only\">{label}</span>\n </span>\n )\n}",
|
|
14974
16892
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
14975
16893
|
}
|
|
14976
16894
|
},
|
|
@@ -14979,21 +16897,66 @@
|
|
|
14979
16897
|
"elements": true,
|
|
14980
16898
|
"react": true
|
|
14981
16899
|
},
|
|
14982
|
-
"guidance":
|
|
14983
|
-
|
|
16900
|
+
"guidance": {
|
|
16901
|
+
"when": "Use beside a metric when a compact trend adds meaning and at least two valid samples exist.",
|
|
16902
|
+
"distinction": "Use LineChart when axes, multiple series, thresholds, exact values, or a data table are important."
|
|
16903
|
+
},
|
|
16904
|
+
"kebab": "sparkline",
|
|
14984
16905
|
"keyboardInteractions": [],
|
|
14985
16906
|
"keywords": [
|
|
14986
|
-
"
|
|
14987
|
-
"
|
|
14988
|
-
"
|
|
14989
|
-
"
|
|
14990
|
-
"
|
|
16907
|
+
"adds",
|
|
16908
|
+
"and",
|
|
16909
|
+
"are",
|
|
16910
|
+
"axes",
|
|
16911
|
+
"beside",
|
|
16912
|
+
"breakdowns",
|
|
16913
|
+
"categorical",
|
|
16914
|
+
"compact",
|
|
16915
|
+
"comparisons",
|
|
16916
|
+
"custom",
|
|
16917
|
+
"data",
|
|
16918
|
+
"display",
|
|
16919
|
+
"exact",
|
|
16920
|
+
"exist",
|
|
16921
|
+
"existing",
|
|
16922
|
+
"important",
|
|
16923
|
+
"labelled",
|
|
16924
|
+
"least",
|
|
16925
|
+
"linechart",
|
|
16926
|
+
"match",
|
|
16927
|
+
"meaning",
|
|
16928
|
+
"metric",
|
|
16929
|
+
"metrics",
|
|
16930
|
+
"multiple",
|
|
16931
|
+
"ordered",
|
|
16932
|
+
"part",
|
|
16933
|
+
"plots",
|
|
16934
|
+
"question",
|
|
16935
|
+
"samples",
|
|
16936
|
+
"series",
|
|
16937
|
+
"shows",
|
|
16938
|
+
"sparkline",
|
|
16939
|
+
"table",
|
|
16940
|
+
"text",
|
|
14991
16941
|
"the",
|
|
14992
|
-
"
|
|
14993
|
-
"
|
|
16942
|
+
"thresholds",
|
|
16943
|
+
"trend",
|
|
16944
|
+
"trends",
|
|
16945
|
+
"two",
|
|
16946
|
+
"use",
|
|
16947
|
+
"valid",
|
|
16948
|
+
"values",
|
|
16949
|
+
"visualization",
|
|
16950
|
+
"when",
|
|
16951
|
+
"whole"
|
|
14994
16952
|
],
|
|
14995
|
-
"name": "
|
|
16953
|
+
"name": "Sparkline",
|
|
14996
16954
|
"props": [
|
|
16955
|
+
{
|
|
16956
|
+
"name": "area",
|
|
16957
|
+
"optional": true,
|
|
16958
|
+
"type": "boolean"
|
|
16959
|
+
},
|
|
14997
16960
|
{
|
|
14998
16961
|
"name": "class",
|
|
14999
16962
|
"optional": true,
|
|
@@ -15005,18 +16968,33 @@
|
|
|
15005
16968
|
"type": "string"
|
|
15006
16969
|
},
|
|
15007
16970
|
{
|
|
15008
|
-
"name": "
|
|
16971
|
+
"name": "label",
|
|
16972
|
+
"optional": false,
|
|
16973
|
+
"type": "string"
|
|
16974
|
+
},
|
|
16975
|
+
{
|
|
16976
|
+
"name": "showEndpoint",
|
|
15009
16977
|
"optional": true,
|
|
15010
|
-
"type": "
|
|
16978
|
+
"type": "boolean"
|
|
15011
16979
|
},
|
|
15012
16980
|
{
|
|
15013
|
-
"name": "
|
|
16981
|
+
"name": "tone",
|
|
15014
16982
|
"optional": true,
|
|
15015
|
-
"type": "
|
|
16983
|
+
"type": "LumenChartTone"
|
|
16984
|
+
},
|
|
16985
|
+
{
|
|
16986
|
+
"name": "values",
|
|
16987
|
+
"optional": false,
|
|
16988
|
+
"type": "readonly number[]"
|
|
16989
|
+
}
|
|
16990
|
+
],
|
|
16991
|
+
"propsExtends": "HTMLAttributes<'span'>",
|
|
16992
|
+
"recipes": [
|
|
16993
|
+
{
|
|
16994
|
+
"name": "data-visualization",
|
|
16995
|
+
"type": "recipe"
|
|
15016
16996
|
}
|
|
15017
16997
|
],
|
|
15018
|
-
"propsExtends": "HTMLAttributes<'div'>",
|
|
15019
|
-
"recipes": [],
|
|
15020
16998
|
"runtimeEvents": []
|
|
15021
16999
|
},
|
|
15022
17000
|
{
|
|
@@ -18562,7 +20540,7 @@
|
|
|
18562
20540
|
"values": "HTML attributes"
|
|
18563
20541
|
}
|
|
18564
20542
|
],
|
|
18565
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n density?: 'low' | 'medium' | 'high'\n}\n\nconst {\n class: classProp = '',\n className = '',\n density = 'medium',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-particles'\n], classProp, className)\n---\n\n<div\n aria-hidden=\"true\"\n class:list={classList}\n data-ui-particles={density}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
20543
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n density?: 'low' | 'medium' | 'high'\n}\n\nconst {\n class: classProp = '',\n className = '',\n density = 'medium',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-particles'\n], classProp, className)\n---\n\n<div\n aria-hidden=\"true\"\n class:list={classList}\n data-ui-particles={density}\n {...passthrough}\n>\n <slot />\n</div>\n\n<script>\n type ParticleDensity = 'low' | 'medium' | 'high'\n\n const densityConfig: Record<ParticleDensity, number> = {\n low: 15,\n medium: 25,\n high: 40\n }\n\n const particleTones = [\n 'var(--brand)',\n 'var(--accent)',\n 'var(--glow, var(--brand))'\n ]\n\n const initParticles = (scope: ParentNode = document) => {\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n\n for (const container of scope.querySelectorAll<HTMLElement>('[data-ui-particles]')) {\n if (container.hasAttribute('data-ui-particles-initialized')) continue\n\n container.setAttribute('data-ui-particles-initialized', '')\n\n const density = (container.dataset.uiParticles || 'medium') as ParticleDensity\n const count = densityConfig[density]\n\n for (let index = 0; index < count; index++) {\n const particle = document.createElement('span')\n const size = Math.random() * 12 + 8\n\n particle.className = 'ui-particles__particle'\n particle.style.setProperty('--ui-particle-delay', `${Math.random() * 8}s`)\n particle.style.setProperty('--ui-particle-duration', `${20 + Math.random() * 15}s`)\n particle.style.setProperty('--ui-particle-left', `${Math.random() * 100}%`)\n particle.style.setProperty('--ui-particle-size', `${size}px`)\n particle.style.setProperty('--ui-particle-tone', particleTones[Math.floor(Math.random() * particleTones.length)])\n particle.style.setProperty('--ui-particle-top', `${Math.random() * 100}%`)\n container.appendChild(particle)\n }\n }\n }\n\n initParticles()\n document.addEventListener('astro:after-swap', () => initParticles())\n</script>\n",
|
|
18566
20544
|
"category": "Layout",
|
|
18567
20545
|
"collections": [],
|
|
18568
20546
|
"dependencies": [],
|
|
@@ -18596,7 +20574,7 @@
|
|
|
18596
20574
|
}
|
|
18597
20575
|
],
|
|
18598
20576
|
"propsExtends": "HTMLAttributes<'div'>",
|
|
18599
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n density?: 'low' | 'medium' | 'high'\n}\n\nconst {\n class: classProp = '',\n className = '',\n density = 'medium',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-particles'\n], classProp, className)\n---\n\n<div\n aria-hidden=\"true\"\n class:list={classList}\n data-ui-particles={density}\n {...passthrough}\n>\n <slot />\n</div>\n",
|
|
20577
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n density?: 'low' | 'medium' | 'high'\n}\n\nconst {\n class: classProp = '',\n className = '',\n density = 'medium',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-particles'\n], classProp, className)\n---\n\n<div\n aria-hidden=\"true\"\n class:list={classList}\n data-ui-particles={density}\n {...passthrough}\n>\n <slot />\n</div>\n\n<script>\n type ParticleDensity = 'low' | 'medium' | 'high'\n\n const densityConfig: Record<ParticleDensity, number> = {\n low: 15,\n medium: 25,\n high: 40\n }\n\n const particleTones = [\n 'var(--brand)',\n 'var(--accent)',\n 'var(--glow, var(--brand))'\n ]\n\n const initParticles = (scope: ParentNode = document) => {\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n\n for (const container of scope.querySelectorAll<HTMLElement>('[data-ui-particles]')) {\n if (container.hasAttribute('data-ui-particles-initialized')) continue\n\n container.setAttribute('data-ui-particles-initialized', '')\n\n const density = (container.dataset.uiParticles || 'medium') as ParticleDensity\n const count = densityConfig[density]\n\n for (let index = 0; index < count; index++) {\n const particle = document.createElement('span')\n const size = Math.random() * 12 + 8\n\n particle.className = 'ui-particles__particle'\n particle.style.setProperty('--ui-particle-delay', `${Math.random() * 8}s`)\n particle.style.setProperty('--ui-particle-duration', `${20 + Math.random() * 15}s`)\n particle.style.setProperty('--ui-particle-left', `${Math.random() * 100}%`)\n particle.style.setProperty('--ui-particle-size', `${size}px`)\n particle.style.setProperty('--ui-particle-tone', particleTones[Math.floor(Math.random() * particleTones.length)])\n particle.style.setProperty('--ui-particle-top', `${Math.random() * 100}%`)\n container.appendChild(particle)\n }\n }\n }\n\n initParticles()\n document.addEventListener('astro:after-swap', () => initParticles())\n</script>\n",
|
|
18600
20578
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
18601
20579
|
},
|
|
18602
20580
|
"elements": {
|
|
@@ -18635,7 +20613,7 @@
|
|
|
18635
20613
|
}
|
|
18636
20614
|
],
|
|
18637
20615
|
"propsExtends": "ComponentPropsWithoutRef<'div'>",
|
|
18638
|
-
"source": "export interface ParticlesProps extends ComponentPropsWithoutRef<'div'> {\n density?: 'low' | 'medium' | 'high'\n}\n\nexport const Particles = ({ className, density = 'medium', ...props }: ParticlesProps) => (\n <div aria-hidden=\"true\" className={composeClassName('ui-particles', className)} data-ui-particles={density} {...props}
|
|
20616
|
+
"source": "export interface ParticlesProps extends ComponentPropsWithoutRef<'div'> {\n density?: 'low' | 'medium' | 'high'\n}\n\nexport const Particles = ({ children, className, density = 'medium', ...props }: ParticlesProps) => {\n const [particles, setParticles] = useState<ParticleItem[]>([])\n\n useEffect(() => {\n if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return\n\n // Particle geometry is client-only to keep SSR output stable while retaining per-load variation.\n // eslint-disable-next-line @eslint-react/set-state-in-effect\n setParticles(createParticles(density))\n }, [density])\n\n return (\n <div aria-hidden=\"true\" className={composeClassName('ui-particles', className)} data-ui-particles={density} {...props}>\n {children}\n {particles.map(particle => <span className=\"ui-particles__particle\" key={particle.id} style={particle.style} />)}\n </div>\n )\n}",
|
|
18639
20617
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
18640
20618
|
}
|
|
18641
20619
|
},
|
|
@@ -19469,6 +21447,18 @@
|
|
|
19469
21447
|
},
|
|
19470
21448
|
{
|
|
19471
21449
|
"apiReference": [
|
|
21450
|
+
{
|
|
21451
|
+
"attribute": "as",
|
|
21452
|
+
"defaultValue": "\"div\"",
|
|
21453
|
+
"description": "Changes the root element when the statistic is a standalone semantic region.",
|
|
21454
|
+
"values": "\"article\" | \"div\" | \"section\""
|
|
21455
|
+
},
|
|
21456
|
+
{
|
|
21457
|
+
"attribute": "variant",
|
|
21458
|
+
"defaultValue": "\"default\"",
|
|
21459
|
+
"description": "Changes the surface treatment while preserving the same metric structure.",
|
|
21460
|
+
"values": "\"accent\" | \"default\" | \"glass\""
|
|
21461
|
+
},
|
|
19472
21462
|
{
|
|
19473
21463
|
"attribute": "label",
|
|
19474
21464
|
"defaultValue": "-",
|
|
@@ -19494,9 +21484,11 @@
|
|
|
19494
21484
|
"values": "HTML attributes"
|
|
19495
21485
|
}
|
|
19496
21486
|
],
|
|
19497
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n label?: string\n value?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n label,\n value,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-stat'
|
|
21487
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n as?: 'article' | 'div' | 'section'\n class?: string | null\n className?: string\n label?: string\n value?: string\n variant?: 'accent' | 'default' | 'glass'\n}\n\nconst {\n as: Tag = 'div',\n class: classProp = '',\n className = '',\n label,\n value,\n variant = 'default',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-stat',\n variant !== 'default' && `ui-stat--${variant}`\n], classProp, className)\n---\n\n<Tag\n class:list={classList}\n data-variant={variant}\n {...passthrough}\n>\n {label && <div class=\"ui-stat-label\">{label}</div>}\n {value && <div class=\"ui-stat-value\">{value}</div>}\n <slot />\n</Tag>\n",
|
|
19498
21488
|
"category": "Data display",
|
|
19499
|
-
"collections": [
|
|
21489
|
+
"collections": [
|
|
21490
|
+
"Data visualization"
|
|
21491
|
+
],
|
|
19500
21492
|
"dependencies": [],
|
|
19501
21493
|
"description": "Pairs one prominent metric with a concise descriptive label.",
|
|
19502
21494
|
"files": [
|
|
@@ -19506,11 +21498,16 @@
|
|
|
19506
21498
|
"frameworkDetails": {
|
|
19507
21499
|
"astro": {
|
|
19508
21500
|
"available": true,
|
|
19509
|
-
"example": "<Stat label=\"Active workspaces\" value=\"1,234\" />",
|
|
21501
|
+
"example": "<Stat label=\"Active workspaces\" value=\"1,234\" variant=\"accent\" />",
|
|
19510
21502
|
"importStatement": "import { Stat } from '@santi020k/lumen-astro'",
|
|
19511
21503
|
"language": "astro",
|
|
19512
21504
|
"packageName": "@santi020k/lumen-astro",
|
|
19513
21505
|
"props": [
|
|
21506
|
+
{
|
|
21507
|
+
"name": "as",
|
|
21508
|
+
"optional": true,
|
|
21509
|
+
"type": "'article' | 'div' | 'section'"
|
|
21510
|
+
},
|
|
19514
21511
|
{
|
|
19515
21512
|
"name": "class",
|
|
19516
21513
|
"optional": true,
|
|
@@ -19530,14 +21527,21 @@
|
|
|
19530
21527
|
"name": "value",
|
|
19531
21528
|
"optional": true,
|
|
19532
21529
|
"type": "string"
|
|
21530
|
+
},
|
|
21531
|
+
{
|
|
21532
|
+
"name": "variant",
|
|
21533
|
+
"optional": true,
|
|
21534
|
+
"type": "'accent' | 'default' | 'glass'"
|
|
19533
21535
|
}
|
|
19534
21536
|
],
|
|
19535
21537
|
"propsExtends": "HTMLAttributes<'div'>",
|
|
19536
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n label?: string\n value?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n label,\n value,\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-stat'
|
|
21538
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n as?: 'article' | 'div' | 'section'\n class?: string | null\n className?: string\n label?: string\n value?: string\n variant?: 'accent' | 'default' | 'glass'\n}\n\nconst {\n as: Tag = 'div',\n class: classProp = '',\n className = '',\n label,\n value,\n variant = 'default',\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-stat',\n variant !== 'default' && `ui-stat--${variant}`\n], classProp, className)\n---\n\n<Tag\n class:list={classList}\n data-variant={variant}\n {...passthrough}\n>\n {label && <div class=\"ui-stat-label\">{label}</div>}\n {value && <div class=\"ui-stat-value\">{value}</div>}\n <slot />\n</Tag>\n",
|
|
19537
21539
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
19538
21540
|
},
|
|
19539
21541
|
"elements": {
|
|
19540
21542
|
"attributes": [
|
|
21543
|
+
"variant",
|
|
21544
|
+
"as",
|
|
19541
21545
|
"label",
|
|
19542
21546
|
"value",
|
|
19543
21547
|
"class, className",
|
|
@@ -19548,24 +21552,29 @@
|
|
|
19548
21552
|
"mode": "registration",
|
|
19549
21553
|
"setup": "Call defineLumenElements() once before rendering Lumen custom elements."
|
|
19550
21554
|
},
|
|
19551
|
-
"example": "<lumen-stat label=\"Active workspaces\" value=\"1,234\"></lumen-stat>",
|
|
21555
|
+
"example": "<lumen-stat label=\"Active workspaces\" value=\"1,234\" variant=\"accent\"></lumen-stat>",
|
|
19552
21556
|
"importStatement": "import { defineLumenElements } from '@santi020k/lumen-elements/define'",
|
|
19553
21557
|
"language": "html",
|
|
19554
21558
|
"packageName": "@santi020k/lumen-elements",
|
|
19555
21559
|
"props": [],
|
|
19556
21560
|
"propsExtends": "HTMLElement attributes",
|
|
19557
21561
|
"registration": "defineLumenElements()",
|
|
19558
|
-
"source": "Stat: { baseClassName: 'ui-stat'
|
|
21562
|
+
"source": "Stat: {\n attributeClasses: {\n variant: {\n accent: 'ui-stat--accent',\n glass: 'ui-stat--glass'\n }\n },\n baseClassName: 'ui-stat',\n defaults: { variant: 'default' },\n tagName: 'lumen-stat'\n }",
|
|
19559
21563
|
"styleImport": "import '@santi020k/lumen-elements/styles.css'",
|
|
19560
21564
|
"tagName": "lumen-stat"
|
|
19561
21565
|
},
|
|
19562
21566
|
"react": {
|
|
19563
21567
|
"available": true,
|
|
19564
|
-
"example": "<Stat label=\"Active workspaces\" value=\"1,234\" />",
|
|
21568
|
+
"example": "<Stat label=\"Active workspaces\" value=\"1,234\" variant=\"accent\" />",
|
|
19565
21569
|
"importStatement": "import { Stat } from '@santi020k/lumen-react'",
|
|
19566
21570
|
"language": "tsx",
|
|
19567
21571
|
"packageName": "@santi020k/lumen-react",
|
|
19568
21572
|
"props": [
|
|
21573
|
+
{
|
|
21574
|
+
"name": "as",
|
|
21575
|
+
"optional": true,
|
|
21576
|
+
"type": "T"
|
|
21577
|
+
},
|
|
19569
21578
|
{
|
|
19570
21579
|
"name": "label",
|
|
19571
21580
|
"optional": true,
|
|
@@ -19575,10 +21584,15 @@
|
|
|
19575
21584
|
"name": "value",
|
|
19576
21585
|
"optional": true,
|
|
19577
21586
|
"type": "string"
|
|
21587
|
+
},
|
|
21588
|
+
{
|
|
21589
|
+
"name": "variant",
|
|
21590
|
+
"optional": true,
|
|
21591
|
+
"type": "'accent' | 'default' | 'glass'"
|
|
19578
21592
|
}
|
|
19579
21593
|
],
|
|
19580
|
-
"propsExtends": "
|
|
19581
|
-
"source": "export
|
|
21594
|
+
"propsExtends": "PrimitiveProps",
|
|
21595
|
+
"source": "export type StatProps<T extends ElementType = 'div'> = PrimitiveProps & {\n as?: T\n label?: string\n value?: string\n variant?: 'accent' | 'default' | 'glass'\n}\n\nexport const Stat = <T extends ElementType = 'div'>({\n as,\n className,\n label,\n value,\n variant = 'default',\n children,\n ...props\n}: StatProps<T>) => (\n <Primitive\n {...(as ? { as } : {})}\n className={composeClassName(variant !== 'default' && `ui-stat--${variant}`, className)}\n data-variant={variant}\n {...props}\n uiClassName=\"ui-stat\"\n >\n {label && <div className=\"ui-stat-label\">{label}</div>}\n {value && <div className=\"ui-stat-value\">{value}</div>}\n {children}\n </Primitive>\n)",
|
|
19582
21596
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
19583
21597
|
}
|
|
19584
21598
|
},
|
|
@@ -19589,42 +21603,74 @@
|
|
|
19589
21603
|
},
|
|
19590
21604
|
"guidance": {
|
|
19591
21605
|
"when": "Use to pair one prominent metric with its concise label.",
|
|
19592
|
-
"distinction": "Use Chart when the trend or relationship matters, or Descriptions for several equally weighted key–value facts."
|
|
21606
|
+
"distinction": "Use as=\"article\" when the metric and its supporting content stand alone. Use variant=\"accent\" for a featured metric and variant=\"glass\" on a selective translucent surface. Use Chart when the trend or relationship matters, or Descriptions for several equally weighted key–value facts."
|
|
19593
21607
|
},
|
|
19594
21608
|
"kebab": "stat",
|
|
19595
21609
|
"keyboardInteractions": [],
|
|
19596
21610
|
"keywords": [
|
|
21611
|
+
"accent",
|
|
21612
|
+
"alone",
|
|
21613
|
+
"and",
|
|
21614
|
+
"article",
|
|
21615
|
+
"breakdowns",
|
|
21616
|
+
"categorical",
|
|
19597
21617
|
"chart",
|
|
21618
|
+
"compact",
|
|
21619
|
+
"comparisons",
|
|
19598
21620
|
"concise",
|
|
21621
|
+
"content",
|
|
21622
|
+
"custom",
|
|
19599
21623
|
"data",
|
|
19600
21624
|
"descriptions",
|
|
19601
21625
|
"descriptive",
|
|
19602
21626
|
"display",
|
|
19603
21627
|
"equally",
|
|
19604
21628
|
"facts",
|
|
21629
|
+
"featured",
|
|
19605
21630
|
"for",
|
|
21631
|
+
"glass",
|
|
19606
21632
|
"its",
|
|
19607
21633
|
"key",
|
|
19608
21634
|
"label",
|
|
21635
|
+
"match",
|
|
19609
21636
|
"matters",
|
|
19610
21637
|
"metric",
|
|
21638
|
+
"metrics",
|
|
19611
21639
|
"one",
|
|
21640
|
+
"ordered",
|
|
19612
21641
|
"pair",
|
|
19613
21642
|
"pairs",
|
|
21643
|
+
"part",
|
|
21644
|
+
"plots",
|
|
19614
21645
|
"prominent",
|
|
21646
|
+
"question",
|
|
19615
21647
|
"relationship",
|
|
21648
|
+
"selective",
|
|
19616
21649
|
"several",
|
|
21650
|
+
"stand",
|
|
19617
21651
|
"stat",
|
|
21652
|
+
"supporting",
|
|
21653
|
+
"surface",
|
|
19618
21654
|
"the",
|
|
21655
|
+
"translucent",
|
|
19619
21656
|
"trend",
|
|
21657
|
+
"trends",
|
|
19620
21658
|
"use",
|
|
19621
21659
|
"value",
|
|
21660
|
+
"variant",
|
|
21661
|
+
"visualization",
|
|
19622
21662
|
"weighted",
|
|
19623
21663
|
"when",
|
|
21664
|
+
"whole",
|
|
19624
21665
|
"with"
|
|
19625
21666
|
],
|
|
19626
21667
|
"name": "Stat",
|
|
19627
21668
|
"props": [
|
|
21669
|
+
{
|
|
21670
|
+
"name": "as",
|
|
21671
|
+
"optional": true,
|
|
21672
|
+
"type": "'article' | 'div' | 'section'"
|
|
21673
|
+
},
|
|
19628
21674
|
{
|
|
19629
21675
|
"name": "class",
|
|
19630
21676
|
"optional": true,
|
|
@@ -19644,10 +21690,20 @@
|
|
|
19644
21690
|
"name": "value",
|
|
19645
21691
|
"optional": true,
|
|
19646
21692
|
"type": "string"
|
|
21693
|
+
},
|
|
21694
|
+
{
|
|
21695
|
+
"name": "variant",
|
|
21696
|
+
"optional": true,
|
|
21697
|
+
"type": "'accent' | 'default' | 'glass'"
|
|
19647
21698
|
}
|
|
19648
21699
|
],
|
|
19649
21700
|
"propsExtends": "HTMLAttributes<'div'>",
|
|
19650
|
-
"recipes": [
|
|
21701
|
+
"recipes": [
|
|
21702
|
+
{
|
|
21703
|
+
"name": "data-visualization",
|
|
21704
|
+
"type": "recipe"
|
|
21705
|
+
}
|
|
21706
|
+
],
|
|
19651
21707
|
"runtimeEvents": []
|
|
19652
21708
|
},
|
|
19653
21709
|
{
|
|
@@ -19685,7 +21741,9 @@
|
|
|
19685
21741
|
],
|
|
19686
21742
|
"astroSource": "---\nimport type { HTMLAttributes } from 'astro/types'\nimport { composeClassName } from '@santi020k/lumen-core'\n\nexport interface Props extends HTMLAttributes<'meter'> {\n value: number\n min?: number\n max?: number\n low?: number\n high?: number\n optimum?: number\n}\n\nconst {\n class: className,\n value,\n min = 0,\n max = 100,\n ...props\n} = Astro.props\n---\n\n<meter\n class={composeClassName('ui-meter', className)}\n value={value}\n min={min}\n max={max}\n {...props}\n>\n <slot>{value}</slot>\n</meter>\n",
|
|
19687
21743
|
"category": "Data display",
|
|
19688
|
-
"collections": [
|
|
21744
|
+
"collections": [
|
|
21745
|
+
"Data visualization"
|
|
21746
|
+
],
|
|
19689
21747
|
"dependencies": [],
|
|
19690
21748
|
"description": "Displays a scalar value within a known range.",
|
|
19691
21749
|
"files": [
|
|
@@ -19784,18 +21842,30 @@
|
|
|
19784
21842
|
"keyboardInteractions": [],
|
|
19785
21843
|
"keywords": [
|
|
19786
21844
|
"advancing",
|
|
21845
|
+
"and",
|
|
21846
|
+
"breakdowns",
|
|
21847
|
+
"categorical",
|
|
21848
|
+
"compact",
|
|
21849
|
+
"comparisons",
|
|
19787
21850
|
"completion",
|
|
19788
21851
|
"current",
|
|
21852
|
+
"custom",
|
|
19789
21853
|
"data",
|
|
19790
21854
|
"display",
|
|
19791
21855
|
"displays",
|
|
19792
21856
|
"for",
|
|
19793
21857
|
"known",
|
|
21858
|
+
"match",
|
|
19794
21859
|
"measurement",
|
|
19795
21860
|
"meter",
|
|
21861
|
+
"metrics",
|
|
19796
21862
|
"not",
|
|
21863
|
+
"ordered",
|
|
21864
|
+
"part",
|
|
21865
|
+
"plots",
|
|
19797
21866
|
"progress",
|
|
19798
21867
|
"quantity",
|
|
21868
|
+
"question",
|
|
19799
21869
|
"range",
|
|
19800
21870
|
"represents",
|
|
19801
21871
|
"scalar",
|
|
@@ -19805,9 +21875,13 @@
|
|
|
19805
21875
|
"storage",
|
|
19806
21876
|
"such",
|
|
19807
21877
|
"task",
|
|
21878
|
+
"the",
|
|
19808
21879
|
"toward",
|
|
21880
|
+
"trends",
|
|
19809
21881
|
"use",
|
|
19810
21882
|
"value",
|
|
21883
|
+
"visualization",
|
|
21884
|
+
"whole",
|
|
19811
21885
|
"within",
|
|
19812
21886
|
"work"
|
|
19813
21887
|
],
|
|
@@ -19845,7 +21919,12 @@
|
|
|
19845
21919
|
}
|
|
19846
21920
|
],
|
|
19847
21921
|
"propsExtends": "HTMLAttributes<'meter'>",
|
|
19848
|
-
"recipes": [
|
|
21922
|
+
"recipes": [
|
|
21923
|
+
{
|
|
21924
|
+
"name": "data-visualization",
|
|
21925
|
+
"type": "recipe"
|
|
21926
|
+
}
|
|
21927
|
+
],
|
|
19849
21928
|
"runtimeEvents": []
|
|
19850
21929
|
},
|
|
19851
21930
|
{
|
|
@@ -21968,8 +24047,8 @@
|
|
|
21968
24047
|
{
|
|
21969
24048
|
"attribute": "items",
|
|
21970
24049
|
"defaultValue": "[]",
|
|
21971
|
-
"description": "Defines the in-page navigation targets and
|
|
21972
|
-
"values": "Array<{ href, label }>"
|
|
24050
|
+
"description": "Defines the in-page navigation targets, labels, and optional heading depth from 1 through 6.",
|
|
24051
|
+
"values": "Array<{ href, label, depth? }>"
|
|
21973
24052
|
},
|
|
21974
24053
|
{
|
|
21975
24054
|
"attribute": "class, className",
|
|
@@ -21984,7 +24063,7 @@
|
|
|
21984
24063
|
"values": "HTML attributes"
|
|
21985
24064
|
}
|
|
21986
24065
|
],
|
|
21987
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype AnchorLink = { href: string
|
|
24066
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype AnchorDepth = 1 | 2 | 3 | 4 | 5 | 6\n\ntype AnchorLink = {\n depth?: AnchorDepth\n href: string\n label: string\n}\n\nexport interface Props extends HTMLAttributes<'nav'> {\n class?: string | null\n className?: string\n items?: AnchorLink[]\n}\n\nconst {\n 'aria-label': ariaLabel = 'On this page',\n class: classProp = '',\n className = '',\n items = [],\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-anchor'\n], classProp, className)\n---\n\n<nav\n aria-label={ariaLabel}\n class:list={classList}\n data-ui-anchor\n {...passthrough}\n>\n {items.length > 0 && (\n <ol>\n {items.map((item, index) => (\n <li>\n <a\n data-active={index === 0 ? 'true' : 'false'}\n data-depth={item.depth}\n href={item.href}\n >\n {item.label}\n </a>\n </li>\n ))}\n </ol>\n )}\n <slot />\n</nav>\n",
|
|
21988
24067
|
"category": "Navigation",
|
|
21989
24068
|
"collections": [
|
|
21990
24069
|
"Disclosure and navigation"
|
|
@@ -21998,7 +24077,7 @@
|
|
|
21998
24077
|
"frameworkDetails": {
|
|
21999
24078
|
"astro": {
|
|
22000
24079
|
"available": true,
|
|
22001
|
-
"example": "<Anchor items={[{ href: \"#installation\", label: \"Installation\" }, { href: \"#usage\", label: \"Usage\" }]} />",
|
|
24080
|
+
"example": "<Anchor items={[{ href: \"#installation\", label: \"Installation\", depth: 2 }, { href: \"#usage\", label: \"Usage\", depth: 3 }]} />",
|
|
22002
24081
|
"importStatement": "import { Anchor } from '@santi020k/lumen-astro'",
|
|
22003
24082
|
"language": "astro",
|
|
22004
24083
|
"packageName": "@santi020k/lumen-astro",
|
|
@@ -22020,7 +24099,7 @@
|
|
|
22020
24099
|
}
|
|
22021
24100
|
],
|
|
22022
24101
|
"propsExtends": "HTMLAttributes<'nav'>",
|
|
22023
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype AnchorLink = { href: string
|
|
24102
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ntype AnchorDepth = 1 | 2 | 3 | 4 | 5 | 6\n\ntype AnchorLink = {\n depth?: AnchorDepth\n href: string\n label: string\n}\n\nexport interface Props extends HTMLAttributes<'nav'> {\n class?: string | null\n className?: string\n items?: AnchorLink[]\n}\n\nconst {\n 'aria-label': ariaLabel = 'On this page',\n class: classProp = '',\n className = '',\n items = [],\n ...rest\n} = Astro.props\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-anchor'\n], classProp, className)\n---\n\n<nav\n aria-label={ariaLabel}\n class:list={classList}\n data-ui-anchor\n {...passthrough}\n>\n {items.length > 0 && (\n <ol>\n {items.map((item, index) => (\n <li>\n <a\n data-active={index === 0 ? 'true' : 'false'}\n data-depth={item.depth}\n href={item.href}\n >\n {item.label}\n </a>\n </li>\n ))}\n </ol>\n )}\n <slot />\n</nav>\n",
|
|
22024
24103
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
22025
24104
|
},
|
|
22026
24105
|
"elements": {
|
|
@@ -22049,7 +24128,7 @@
|
|
|
22049
24128
|
},
|
|
22050
24129
|
"react": {
|
|
22051
24130
|
"available": true,
|
|
22052
|
-
"example": "<Anchor items={[{ href: \"#installation\", label: \"Installation\" }, { href: \"#usage\", label: \"Usage\" }]} />",
|
|
24131
|
+
"example": "<Anchor items={[{ href: \"#installation\", label: \"Installation\", depth: 2 }, { href: \"#usage\", label: \"Usage\", depth: 3 }]} />",
|
|
22053
24132
|
"importStatement": "import { Anchor } from '@santi020k/lumen-react'",
|
|
22054
24133
|
"language": "tsx",
|
|
22055
24134
|
"packageName": "@santi020k/lumen-react",
|
|
@@ -22061,7 +24140,7 @@
|
|
|
22061
24140
|
}
|
|
22062
24141
|
],
|
|
22063
24142
|
"propsExtends": "ComponentPropsWithoutRef<'nav'>",
|
|
22064
|
-
"source": "export interface AnchorProps extends ComponentPropsWithoutRef<'nav'> {\n items?: AnchorLink[]\n}\n\nexport const Anchor = ({ 'aria-label': ariaLabel = 'On this page', children, className, items = emptyAnchorLinks, ...props }: AnchorProps) => (\n <nav aria-label={ariaLabel} className={composeClassName('ui-anchor', className)} data-ui-anchor {...props}>\n {items.length > 0 && (\n <ol>\n {items.map((item, index) => (\n <li key={item.href}>\n <a
|
|
24143
|
+
"source": "export interface AnchorProps extends ComponentPropsWithoutRef<'nav'> {\n items?: AnchorLink[]\n}\n\nexport const Anchor = ({ 'aria-label': ariaLabel = 'On this page', children, className, items = emptyAnchorLinks, ...props }: AnchorProps) => (\n <nav aria-label={ariaLabel} className={composeClassName('ui-anchor', className)} data-ui-anchor {...props}>\n {items.length > 0 && (\n <ol>\n {items.map((item, index) => (\n <li key={item.href}>\n <a\n data-active={index === 0 ? 'true' : 'false'}\n data-depth={item.depth}\n href={item.href}\n >\n {item.label}\n </a>\n </li>\n ))}\n </ol>\n )}\n {children}\n </nav>\n)",
|
|
22065
24144
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
22066
24145
|
}
|
|
22067
24146
|
},
|
|
@@ -23960,7 +26039,7 @@
|
|
|
23960
26039
|
"values": "HTML attributes"
|
|
23961
26040
|
}
|
|
23962
26041
|
],
|
|
23963
|
-
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n content?: string\n gap?: number\n rotate?: number\n text?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n content,\n gap = 120,\n rotate = -22,\n text = 'Confidential',\n ...rest\n} = Astro.props\n\nconst watermarkText = content ?? text\nconst tileSize = Math.max(1, gap)\nconst watermarkXmlEntities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst escapedWatermarkText = watermarkText.replaceAll(\n /[&<>\"']/g,\n character => watermarkXmlEntities[character] ?? character\n)\nconst watermarkSvg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileSize}\" height=\"${tileSize}\" viewBox=\"0 0 ${tileSize} ${tileSize}\">`,\n `<text x=\"${tileSize / 2}\" y=\"${tileSize / 2}\" dominant-baseline=\"middle\" text-anchor=\"middle\"`,\n ` transform=\"rotate(${rotate} ${tileSize / 2} ${tileSize / 2})\"`,\n ' fill=\"black\" font-family=\"
|
|
26042
|
+
"astroSource": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n content?: string\n gap?: number\n rotate?: number\n text?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n content,\n gap = 120,\n rotate = -22,\n text = 'Confidential',\n ...rest\n} = Astro.props\n\nconst watermarkText = content ?? text\nconst tileSize = Math.max(1, gap)\nconst watermarkXmlEntities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst escapedWatermarkText = watermarkText.replaceAll(\n /[&<>\"']/g,\n character => watermarkXmlEntities[character] ?? character\n)\nconst watermarkSvg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileSize}\" height=\"${tileSize}\" viewBox=\"0 0 ${tileSize} ${tileSize}\">`,\n `<text x=\"${tileSize / 2}\" y=\"${tileSize / 2}\" dominant-baseline=\"middle\" text-anchor=\"middle\"`,\n ` transform=\"rotate(${rotate} ${tileSize / 2} ${tileSize / 2})\"`,\n ' fill=\"black\" font-family=\"Montserrat, Avenir Next, Segoe UI, sans-serif\" font-size=\"16\" font-weight=\"500\" letter-spacing=\"1.6\">',\n `${escapedWatermarkText}</text></svg>`\n].join('')\nconst watermarkImage = `url(\"data:image/svg+xml,${encodeURIComponent(watermarkSvg)}\")`\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-watermark'\n], classProp, className)\n---\n\n<div\n class:list={classList}\n data-ui-watermark\n style={`--ui-watermark-gap:${tileSize}px;--ui-watermark-image:${watermarkImage}`}\n {...passthrough}\n>\n <slot />\n <div aria-hidden=\"true\" class=\"ui-watermark__overlay\" data-text={watermarkText}></div>\n</div>\n",
|
|
23964
26043
|
"category": "Layout",
|
|
23965
26044
|
"collections": [],
|
|
23966
26045
|
"dependencies": [],
|
|
@@ -24009,7 +26088,7 @@
|
|
|
24009
26088
|
}
|
|
24010
26089
|
],
|
|
24011
26090
|
"propsExtends": "HTMLAttributes<'div'>",
|
|
24012
|
-
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n content?: string\n gap?: number\n rotate?: number\n text?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n content,\n gap = 120,\n rotate = -22,\n text = 'Confidential',\n ...rest\n} = Astro.props\n\nconst watermarkText = content ?? text\nconst tileSize = Math.max(1, gap)\nconst watermarkXmlEntities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst escapedWatermarkText = watermarkText.replaceAll(\n /[&<>\"']/g,\n character => watermarkXmlEntities[character] ?? character\n)\nconst watermarkSvg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileSize}\" height=\"${tileSize}\" viewBox=\"0 0 ${tileSize} ${tileSize}\">`,\n `<text x=\"${tileSize / 2}\" y=\"${tileSize / 2}\" dominant-baseline=\"middle\" text-anchor=\"middle\"`,\n ` transform=\"rotate(${rotate} ${tileSize / 2} ${tileSize / 2})\"`,\n ' fill=\"black\" font-family=\"
|
|
26091
|
+
"source": "---\nimport { resolveLumenAstroProps } from '@santi020k/lumen-core'\n\nimport type { HTMLAttributes } from 'astro/types'\n\ninterface Props extends HTMLAttributes<'div'> {\n class?: string | null\n className?: string\n content?: string\n gap?: number\n rotate?: number\n text?: string\n}\n\nconst {\n class: classProp = '',\n className = '',\n content,\n gap = 120,\n rotate = -22,\n text = 'Confidential',\n ...rest\n} = Astro.props\n\nconst watermarkText = content ?? text\nconst tileSize = Math.max(1, gap)\nconst watermarkXmlEntities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n}\nconst escapedWatermarkText = watermarkText.replaceAll(\n /[&<>\"']/g,\n character => watermarkXmlEntities[character] ?? character\n)\nconst watermarkSvg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileSize}\" height=\"${tileSize}\" viewBox=\"0 0 ${tileSize} ${tileSize}\">`,\n `<text x=\"${tileSize / 2}\" y=\"${tileSize / 2}\" dominant-baseline=\"middle\" text-anchor=\"middle\"`,\n ` transform=\"rotate(${rotate} ${tileSize / 2} ${tileSize / 2})\"`,\n ' fill=\"black\" font-family=\"Montserrat, Avenir Next, Segoe UI, sans-serif\" font-size=\"16\" font-weight=\"500\" letter-spacing=\"1.6\">',\n `${escapedWatermarkText}</text></svg>`\n].join('')\nconst watermarkImage = `url(\"data:image/svg+xml,${encodeURIComponent(watermarkSvg)}\")`\n\nconst { classList, passthrough } = resolveLumenAstroProps(rest, [\n 'ui-watermark'\n], classProp, className)\n---\n\n<div\n class:list={classList}\n data-ui-watermark\n style={`--ui-watermark-gap:${tileSize}px;--ui-watermark-image:${watermarkImage}`}\n {...passthrough}\n>\n <slot />\n <div aria-hidden=\"true\" class=\"ui-watermark__overlay\" data-text={watermarkText}></div>\n</div>\n",
|
|
24013
26092
|
"styleImport": "import '@santi020k/lumen-astro/styles.css'"
|
|
24014
26093
|
},
|
|
24015
26094
|
"elements": {
|
|
@@ -24066,7 +26145,7 @@
|
|
|
24066
26145
|
}
|
|
24067
26146
|
],
|
|
24068
26147
|
"propsExtends": "ComponentPropsWithoutRef<'div'>",
|
|
24069
|
-
"source": "export interface WatermarkProps extends ComponentPropsWithoutRef<'div'> {\n content?: string\n gap?: number\n rotate?: number\n text?: string\n}\n\nexport const Watermark = ({ children, className, content, gap = 120, rotate = -22, style, text = 'Confidential', ...props }: WatermarkProps) => {\n const watermarkText = content ?? text\n const tileSize = Math.max(1, gap)\n\n const watermarkXmlEntities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }\n\n const escapedWatermarkText = watermarkText.replaceAll(\n /[&<>\"']/g,\n character => watermarkXmlEntities[character] ?? character\n )\n\n const watermarkSvg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileSize}\" height=\"${tileSize}\" viewBox=\"0 0 ${tileSize} ${tileSize}\">`,\n `<text x=\"${tileSize / 2}\" y=\"${tileSize / 2}\" dominant-baseline=\"middle\" text-anchor=\"middle\"`,\n ` transform=\"rotate(${rotate} ${tileSize / 2} ${tileSize / 2})\"`,\n ' fill=\"black\" font-family=\"
|
|
26148
|
+
"source": "export interface WatermarkProps extends ComponentPropsWithoutRef<'div'> {\n content?: string\n gap?: number\n rotate?: number\n text?: string\n}\n\nexport const Watermark = ({ children, className, content, gap = 120, rotate = -22, style, text = 'Confidential', ...props }: WatermarkProps) => {\n const watermarkText = content ?? text\n const tileSize = Math.max(1, gap)\n\n const watermarkXmlEntities: Record<string, string> = {\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": '''\n }\n\n const escapedWatermarkText = watermarkText.replaceAll(\n /[&<>\"']/g,\n character => watermarkXmlEntities[character] ?? character\n )\n\n const watermarkSvg = [\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${tileSize}\" height=\"${tileSize}\" viewBox=\"0 0 ${tileSize} ${tileSize}\">`,\n `<text x=\"${tileSize / 2}\" y=\"${tileSize / 2}\" dominant-baseline=\"middle\" text-anchor=\"middle\"`,\n ` transform=\"rotate(${rotate} ${tileSize / 2} ${tileSize / 2})\"`,\n ' fill=\"black\" font-family=\"Montserrat, Avenir Next, Segoe UI, sans-serif\" font-size=\"16\" font-weight=\"500\" letter-spacing=\"1.6\">',\n `${escapedWatermarkText}</text></svg>`\n ].join('')\n\n const watermarkImage = `url(\"data:image/svg+xml,${encodeURIComponent(watermarkSvg)}\")`\n\n return (\n <div\n className={composeClassName('ui-watermark', className)}\n data-ui-watermark\n style={{\n ['--ui-watermark-gap' as string]: `${tileSize}px`,\n ['--ui-watermark-image' as string]: watermarkImage,\n ...style\n }}\n {...props}\n >\n {children}\n <div aria-hidden=\"true\" className=\"ui-watermark__overlay\" data-text={watermarkText} />\n </div>\n )\n}",
|
|
24070
26149
|
"styleImport": "import '@santi020k/lumen-react/styles.css'"
|
|
24071
26150
|
}
|
|
24072
26151
|
},
|
|
@@ -24563,12 +26642,12 @@
|
|
|
24563
26642
|
}
|
|
24564
26643
|
],
|
|
24565
26644
|
"docs": {
|
|
24566
|
-
"aiUsage": "# AI Usage Guide\n\nUse this guide when an AI agent is building an app with Lumen or updating examples that teach\nanother agent how to use the library.\n\n## Install the Lumen Agent Skill\n\nLumen ships a portable Agent Skill for AI coding tools that support the open `SKILL.md` format:\n\n```bash\nnpx skills add santi020k/lumen --skill lumen-ui\n```\n\nThe source lives in [`skills/lumen-ui`](../skills/lumen-ui). The skill provides the durable\nframework-selection, component-composition, theming, accessibility, and verification workflow.\nUse it by naming `$lumen-ui` in a prompt, or let a compatible agent trigger it from Lumen-specific\nrequests.\n\nThe skill and MCP server complement each other: the skill explains how to work, while\n`@santi020k/lumen-mcp` supplies structured catalog search, framework-specific contracts, recipes,\nsource, tokens, resources, and rules.\n\n## Pick the Right Package\n\nUse the framework requested by the user. Every adapter shares the same Lumen foundation.\n\n| App Target | Install | Import Components From | Load Styles From |\n| --- | --- | --- | --- |\n| Astro | `@santi020k/lumen-astro` | `@santi020k/lumen-astro` | `@santi020k/lumen-astro/styles.css` |\n| React | `@santi020k/lumen-react` | `@santi020k/lumen-react` | `@santi020k/lumen-react/styles.css` |\n| Web Components | `@santi020k/lumen-elements` | `@santi020k/lumen-elements/define` | `@santi020k/lumen-elements/styles.css` |\n| Package metadata | `@santi020k/lumen-core` | `@santi020k/lumen-core` | Not applicable |\n\nEach framework package includes the shared foundation. Install `@santi020k/lumen` separately only\nwhen you need its framework-neutral CLI or registry metadata.\n\n## MCP-Assisted Workflow\n\nConnect `@santi020k/lumen-mcp` when the agent supports Model Context Protocol. The server returns\nvalidated structured content as well as readable text, so agents can select components without\nscraping documentation.\n\n```bash\ncodex mcp add lumen -- npx -y @santi020k/lumen-mcp\n```\n\nFor Codex project configuration:\n\n```toml\n[mcp_servers.lumen]\nenabled = true\ncommand = \"npx\"\nargs = [\"-y\", \"@santi020k/lumen-mcp\"]\n```\n\nUse this sequence:\n\n1. Read `lumen://meta` and `lumen://diagnostics` to identify and verify the snapshot.\n2. Read `lumen://rules`.\n3. Search for the use case with `lumen_search`, passing the target `framework` when known.\n4. Inspect the selected framework with `lumen_get_component` and `detail: \"usage\"`.\n5. Follow its framework behavior setup and hook/controller contract.\n6. Read related multi-component guidance with `lumen_get_recipe`.\n7. Request `detail: \"source\"` only when the usage contract is insufficient.\n8. Read `lumen://tokens` before introducing custom styling.\n9. Retain `lumen://catalog-manifest` and use `lumen_diff_catalog` after upgrades to identify contracts that need refreshing.\n\nExample framework-aware component request:\n\n```json\n{\n \"name\": \"lumen_get_component\",\n \"arguments\": {\n \"name\": \"DateRangePicker\",\n \"framework\": \"react\",\n \"detail\": \"usage\"\n }\n}\n```\n\nStable resources are available at `lumen://rules`, `lumen://tokens`, `lumen://components`,\n`lumen://meta`, `lumen://catalog-manifest`, `lumen://diagnostics`,\n`lumen://components/{name}`, and `lumen://recipes/{name}`. See\n[`packages/mcp/README.md`](../packages/mcp/README.md) for Claude Desktop, Cursor, generic stdio,\nlocal repository, and programmatic examples.\n\n## Minimal Setup\n\nImport the stylesheet once in the app's global CSS, root layout, or app entry.\n\n```css\n@import \"@santi020k/lumen-react/styles.css\";\n```\n\nIf Tailwind is present, keep both imports in the same shared CSS entry.\n\n```css\n@import \"@santi020k/lumen-react/layers.css\";\n@import \"tailwindcss\";\n@import \"@santi020k/lumen-react/styles.css\";\n```\n\nKeep the layer prelude first. It places Tailwind base styles below Lumen components and Tailwind\nutilities above them, so consumer spacing, display, radius, width, and responsive visibility\nclasses override Lumen defaults predictably.\n\nAstro apps should mount `UIPrimitives` once in the root layout when using interactive primitives\nsuch as dialogs, menus, popovers, tabs, carousels, command lists, toggles, validated forms, or\ntoasts. Do not place `UIPrimitives` in each component example or next to each primitive instance;\none root include enhances all matching `data-ui-*` markup on the page.\n\n```astro\n---\nimport { UIPrimitives } from '@santi020k/lumen-astro'\n---\n\n<UIPrimitives />\n```\n\n## Astro\n\nUse direct named imports from `@santi020k/lumen-astro`.\n\n```astro\n---\nimport { Button, Card, Input, Label } from '@santi020k/lumen-astro'\n---\n\n<Card>\n <Label for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n <Button type=\"submit\">Subscribe</Button>\n</Card>\n```\n\n## React\n\nReact components share the same visual classes and data attributes as Astro components. For\nbehavior-heavy primitives, use the React behavior hooks from `@santi020k/lumen-react` (`useDialog`,\n`usePopover`, `useDropdownMenu`, `useTabs`, `useSelect`, `useToast`, and `useTooltip`), which track\nthe Astro runtime's ARIA, keyboard, Escape, dismissal, and toast controller semantics.\n\nThe React package entry is a client boundary. In Next.js, it can be imported by a Server Component\nwithout evaluating Lumen's contexts and hooks in the React server runtime; the rendered Lumen\nsubtree becomes a Client Component boundary. Vite and other client-rendered React applications use\nthe same entry without additional setup.\n`Button`, `Link`, `ButtonLink`, and `Input` accept React 19 DOM refs directly as props.\n`Button asChild` composes the button contract onto one child element, while `Input visualSize` controls\npresentation without shadowing the native numeric `size` attribute.\n\n```tsx\nimport '@santi020k/lumen-react/styles.css'\nimport { Button, Card, Input, Label } from '@santi020k/lumen-react'\n\nexport function SubscribeForm() {\n return (\n <Card>\n <Label htmlFor=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n <Button type=\"submit\">Subscribe</Button>\n </Card>\n )\n}\n```\n\n## Web Components\n\nRegister custom elements once, then use `lumen-*` tags in HTML. The elements adapter includes\ninteractive behavior parity for DataTable, Dialog, Popover, DropdownMenu, ContextMenu, Tabs,\nSelect, ThemeBuilder, Toast, Tooltip, forms, RichTextEditor, Schedule, and VirtualList: selection,\nvalidation, rich text command, context menu, schedule drag/drop, theme, and range events, ARIA\nstate, roving/listbox keyboard paths, Escape/outside dismissal, focus return/trapping, native\nselect form participation, and the same toast controller events as the Astro runtime.\n\n```html\n<script type=\"module\">\n import { defineLumenElements } from '@santi020k/lumen-elements/define'\n\n defineLumenElements()\n</script>\n\n<lumen-card>\n <label for=\"email\">Email</label>\n <lumen-input id=\"email\" type=\"email\" placeholder=\"you@example.com\"></lumen-input>\n <lumen-button type=\"submit\">Subscribe</lumen-button>\n</lumen-card>\n```\n\n## Component Selection\n\nThe shared catalog includes:\n\n`Accordion`, `Alert`, `AlertDialog`, `Agenda`, `AspectRatio`, `Attachment`, `Autocomplete`,\n`Avatar`, `Badge`, `Breadcrumb`, `Bubble`, `Button`, `ButtonGroup`, `Calendar`, `Card`,\n`Carousel`, `Chart`, `Checkbox`, `Collapsible`, `Code`, `Combobox`, `Command`, `ColorPicker`,\n`ContextMenu`, `DataTable`, `DatePicker`, `DateRangePicker`, `Dialog`, `Direction`, `Drawer`,\n`DropdownMenu`, `Empty`, `Field`, `HoverCard`, `Icon`, `Input`, `InputGroup`, `InputOTP`, `Item`, `Kbd`,\n`Label`, `Marker`, `Menubar`, `Message`, `MessageScroller`, `NativeSelect`, `NavigationMenu`,\n`NumberField`, `Pagination`, `Popover`, `Progress`, `RadioGroup`, `Resizable`, `RichTextEditor`,\n`ScrollArea`, `Schedule`, `SearchField`, `Select`, `Separator`, `Sheet`, `Sidebar`, `Skeleton`,\n`Slider`, `Spinner`, `Switch`, `Table`, `Tabs`, `TagGroup`, `Textarea`, `ThemeBuilder`,\n`TimeField`, `Toast`, `Toggle`, `ToggleGroup`, `Tooltip`, `Tree`, `TreeGrid`, `Typography`, and\n`VirtualList`.\n\n## Product Recipes\n\n- Use `Icon name=\"search\"` or any Lucide icon name for standard interface pictograms. Kebab-case\n names and Lucide aliases work. Pair decorative icons with `decorative`, and pass `label` only\n when the icon carries meaning on its own. Lucide does not include brand marks such as GitHub;\n render a project-owned SVG through the default `Icon` slot for brand and custom icons. Astro\n reports unknown named icons during development instead of failing silently.\n- Use `Schedule` with `Agenda`, `Calendar`, and `DatePicker` for booking, CRM, content calendar, and\n event planning screens. Mark slots with `data-ui-schedule-slot` and events with\n `data-ui-schedule-event`; the runtime emits `ui:schedule-change` when a draggable event is moved.\n `Calendar` renders a hidden input plus selectable date grid; Astro `UIPrimitives` and registered\n Web Components wire month navigation and roving keyboard focus directly, while React apps can use\n the `Calendar` component or `useCalendar` for the same date selection contract.\n Astro `UIPrimitives` and registered Web Components bind schedule drag/drop directly; React apps\n can use `useSchedule` for `rootProps`, `getEventProps`, `getSlotProps`, and `ui:schedule-change`\n parity. Use `createScheduleSlots`, `moveScheduleEvent`, and `expandRecurringScheduleEvent` from\n `@santi020k/lumen-core` for reusable schedule state; use `getScheduleConflicts` and\n `canPlaceScheduleEvent` before committing drag/drop changes. Persist local schedule edits with\n `createScheduleStorageKey`, `saveScheduleEvents`, and `loadScheduleEvents` against any\n `localStorage`-compatible adapter. Use `resizeScheduleEvent` and `resizeScheduleEvents` for\n snap-to-grid resize handles.\n- Use `DataTable`, `Tree`, `TreeGrid`, `VirtualList`, `Pagination`, and `Command` for dense data\n collection workflows. Astro and Elements wire selectable/sortable `DataTable` behavior and\n `VirtualList` range events; React emits the same data attributes for app-level adapters. `Tree`\n and `TreeGrid` use roving keyboard focus, and `VirtualList` emits `ui:virtual-list-range` as the\n rendered range changes. Use `createDataViewState`,\n `serializeDataViewState`, `parseDataViewState`, `applyDataViewState`, and `getVirtualRange` for\n saved views, filtering, sorting, pagination, and virtualization math. Use\n `createDataViewStorageKey`, `saveDataViewState`, and `loadDataViewState` when saved views should\n survive navigation or reloads. Use `pinDataViewColumn`, `unpinDataViewColumn`,\n `toggleDataViewSelection`, `createDataViewSearchParams`, and `createDataViewServerRequest` when\n connecting dense views to router state or server-backed data.\n- Use `Resizable` for split-pane editors, dashboards, inspectors, and side-by-side review layouts.\n Astro `UIPrimitives` and registered Web Components generate separator handles and pane sizing\n directly; React apps can use the `Resizable` component or `useResizable` for pointer, keyboard,\n min/max, and double-click reset parity.\n- Use `ThemeBuilder`, `ColorPicker`, `Card`, `Button`, and `Input` to build token preview and export\n tools. Add `data-ui-theme-brand-hue`, `data-ui-theme-accent-hue`, `data-ui-theme-scheme`,\n `data-ui-theme-mode`, manual color inputs such as `data-ui-theme-primary-hex`, and\n `data-ui-theme-target` for scoped live previews. Add `data-ui-theme-export-format`,\n `data-ui-theme-export`, and `data-ui-theme-output` to copy CSS, Figma variable JSON, or design\n token JSON. Astro `UIPrimitives` and registered Web Components wire those controls directly;\n React apps can use `useThemeBuilder` for the same tokens, exports, and control props. Use\n `createThemePalette`, `createThemeBuilderTokens`, `exportThemeBuilderValue`, `exportThemeCss`,\n `parseThemeCss`, and `scoreThemeContrast`\n for theme import/export and accessibility checks. Use `suggestReadableInk`, `mergeThemeTokens`,\n and `tuneThemeContrast` when generated palettes need readable foreground repair.\n- Use `RichTextEditor` with `ButtonGroup`, `ToggleGroup`, and `Textarea` for editor compositions.\n Controls with `data-ui-editor-command` dispatch browser editing commands and emit\n `ui:editor-command`; use `data-ui-editor-value` for headings, links, and other value-bearing\n commands. Editable surfaces support common formatting shortcuts, synchronize toggle\n `aria-pressed` state, and emit `ui:editor-change` with HTML and plain text. Astro `UIPrimitives`\n and registered Web Components bind those controls directly; React apps can use\n `useRichTextEditor` for `rootProps`, `getCommandProps`, `getEditableProps`, and `executeCommand`.\n For Tiptap, ProseMirror, Lexical, or Markdown engines, keep the external editor\n package in the app and bridge toolbar buttons through the emitted command event instead of adding\n the editor engine to Lumen.\n- Use `Autocomplete`, `SearchField`, `NumberField`, `TimeField`, `DateRangePicker`, `ColorPicker`,\n and `TagGroup` when forms need more than plain text inputs. Add `data-ui-form` to forms that\n should reflect native Constraint Validation API state into `Field` error slots on blur and submit.\n For `InputOTP`, Astro `UIPrimitives` and registered Web Components render/sync a real native input\n with visual OTP segments; React apps can use the `InputOTP` component or `useInputOTP` for the\n same sanitization, paste handling, and caret navigation.\n For `DateRangePicker`, Astro `UIPrimitives` and registered Web Components sync the paired native\n date input `min`/`max` constraints directly; React apps can use `useDateRangePicker` for the same\n start/end syncing props.\n Use native attributes such as `required`, `pattern`, `min`, `max`, and `type`; add\n `data-error-required`, `data-error-pattern`, `data-error-min`, `data-error-max`, or\n `data-error-custom` when a control needs custom copy. Listen for `ui:validate` to call\n `control.setCustomValidity(message)` before the runtime reads validity, and listen for\n `ui:invalid` or `ui:valid` on the form for submission state. Astro `UIPrimitives` and registered\n Web Components bind `data-ui-form` directly; React apps can use `useFormValidation` with `Field`\n to get the same control props, CustomEvents, and error slot updates.\n- Use `Toast` for transient feedback. Static `<Toast>` markup works without\n JavaScript. With Astro `UIPrimitives` or registered Web Components, create toasts with\n `window.LumenToast.create(detail)`, `LumenToast.create(detail)` from `@santi020k/lumen-elements`,\n or `document.dispatchEvent(new CustomEvent('ui:toast', { detail }))`; update them with\n `.update(id, detail)` or `ui:toast-update`; and dismiss them with `.dismiss(id?)` or\n `ui:toast-dismiss`. `detail` supports `title`, `description`, `variant`, `duration`, `placement`,\n `max`, and `action: { label, value }`. Destructive toasts use `role=\"alert\"`; other variants use\n `role=\"status\"`. Runtime toasts pause their timeout on hover or focus, and Escape dismisses the\n focused toast.\n\n## Runtime CustomEvents\n\nWhen `UIPrimitives` is mounted, or when Web Components are registered for matching behavior, Lumen\nuses these CustomEvents:\n\n| Event | Target | Detail | Fires When |\n| --- | --- | --- | --- |\n| `ui:data-table-selection-change` | `DataTable` root `[data-ui-datatable]` | `{ values: string[] }` | Selectable row checkboxes, the select-all checkbox, or form reset changes selected row values. |\n| `ui:schedule-change` | `Schedule` root `[data-ui-schedule]` | `{ eventId?: string, slot?: string }` | A draggable schedule event is dropped on a `[data-ui-schedule-slot]`. |\n| `ui:virtual-list-range` | `VirtualList` root `[data-ui-virtual-list]` | `{ startIndex: number, endIndex: number }` | The virtual list calculates its visible range on init or scroll. |\n| `ui:tag-remove` | `TagGroup` root `.ui-tag-group` or `[data-ui-tag-group]` | `{ value?: string }` | A `[data-ui-tag-remove]` control removes its closest tag or list item. |\n| `ui:editor-command` | `RichTextEditor` root `[data-ui-rich-text-editor]` | `{ command: string, executed: boolean, value?: string }` | A toolbar control or keyboard shortcut runs an editor command. |\n| `ui:editor-change` | `RichTextEditor` root `[data-ui-rich-text-editor]` | `{ html: string, text: string }` | Editable content changes or an editor command runs. |\n| `ui:theme-change` | `ThemeBuilder` root `[data-ui-theme-builder]` | `{ hue: number, accentHue: number, mode: 'generated' \\| 'manual', scheme: 'dark' \\| 'light', tokens: Record<string, string> }` | Hue, manual color, mode, or scheme controls update generated tokens. |\n| `ui:theme-export` | `ThemeBuilder` root `[data-ui-theme-builder]` | `{ css?: string, format: 'css' \\| 'figma' \\| 'tokens', tokens: Record<string, string> \\| null, value: string }` | A `[data-ui-theme-export]` control writes the selected export to the output and clipboard when available. |\n| `ui:validate` | Form `[data-ui-form]` | `{ control, form, value }` | Before validation state is read, so custom code can call `control.setCustomValidity(message)`. |\n| `ui:invalid` | Form `[data-ui-form]` | `{ control?, controls?, form }` | Blur or submit validation finds invalid controls. Failed submits focus the first invalid control. |\n| `ui:valid` | Form `[data-ui-form]` | `{ control?, controls?, form }` | Blur or submit validation finds the checked control or form valid. |\n| `ui:toast` | `document` | `{ id?, title?, description?, variant?, duration?, placement?, action? }` | Creates a runtime toast in the matching notification viewport. |\n| `ui:toast-update` | `document` | `{ id, title?, description?, variant?, duration? }` | Updates a runtime toast. |\n| `ui:toast-dismiss` | `document` | `{ id? }` | Dismisses one runtime toast, or all runtime toasts when `id` is omitted. |\n| `ui:toast-action` | Toast `[data-ui-toast]` | `{ id, value? }` | A runtime toast action button is pressed, unless the action specifies a custom event name. |\n\n## Registry Helper\n\n`@santi020k/lumen` exports typed component, recipe, and documentation metadata from\n`@santi020k/lumen/registry`. The package also ships a small `lumen` binary. Individual components\nare addressable by name, including kebab-case aliases such as `data-table`:\n\n```bash\nlumen list\nlumen show Button\nlumen show data-table\nlumen add Button\nlumen add Button --target react\nlumen add Button --target elements\nlumen add data-table\nlumen show scheduler\nlumen add scheduler\nlumen add scheduler --target react\nlumen add scheduler --target elements\nlumen add scheduler --dry-run\nlumen add scheduler --fail-on-conflict\nlumen add scheduler --force\nlumen add scheduler --merge\nlumen list --registry ./registry/lumen.registry.json\nlumen add custom-recipe --registry ./registry/custom.registry.json\nlumen add private-recipe --registry https://example.com/lumen.registry.json --registry-token \"$TOKEN\"\nlumen install\n```\n\n`lumen add <component>` defaults to an Astro wrapper. Use `--target react` for a local React wrapper\nor `--target elements` for a custom-elements starter. Bundled recipes also accept `--target astro`,\n`--target react`, and `--target elements`; external registry inline files keep their authored paths\nand sources.\n\nBefore inventing a wrapper or custom class pattern, check the component source in\n`packages/astro/components`. Astro is the reference implementation for props, class names, data\nattributes, and accessible markup.\n\n## Styling Rules for Generated Code\n\n- Do not require consumers to configure Tailwind for Lumen components.\n- Prefer component props and composition before adding custom CSS.\n- Use the shared token names for custom surfaces: `canvas`, `surface`, `surface-muted`,\n `surface-strong`, `line`, `ink`, `ink-soft`, `ink-muted`, `brand`, `brand-solid`, `brand-soft`,\n `accent`, `success`, `warning`, and `danger`.\n- Use `glass` as a boolean prop or attribute for glass surfaces when supported.\n- Do not generate `surface=\"glass\"` for overlays; it is a deprecated alias that maps to `glass`.\n- Preserve semantic labels, keyboard paths, focus states, and native form attributes.\n\n## Figma Handoff\n\nUse `exportThemeFigmaVariables` from `@santi020k/lumen-core/figma` when a design workflow needs\nFigma variable-friendly color values, and `exportThemeDesignTokens` when exporting standard design\ntoken JSON for token importers. See [docs/figma.md](figma.md) for the recommended Figma workflow.\n\n## When Editing This Repo\n\n- Shared contracts belong in `packages/core`.\n- Astro implementation and standalone CSS belong in `packages/astro`.\n- React-specific primitives belong in `packages/react`.\n- Web Component-specific primitives belong in `packages/elements`.\n- Update the relevant package README when public usage changes.\n- Add tests beside package code as `*.test.ts` when behavior, exported metadata, or component\n contracts change.\n",
|
|
24567
|
-
"readme": "
|
|
26645
|
+
"aiUsage": "# AI Usage Guide\n\nUse this guide when an AI agent is building an app with Lumen or updating examples that teach\nanother agent how to use the library.\n\n## Install the Lumen Agent Skill\n\nLumen ships a portable Agent Skill for AI coding tools that support the open `SKILL.md` format:\n\n```bash\nnpx skills add santi020k/lumen --skill lumen-ui\n```\n\nThe source lives in [`skills/lumen-ui`](../skills/lumen-ui). The skill provides the durable\nframework-selection, component-composition, theming, accessibility, and verification workflow.\nUse it by naming `$lumen-ui` in a prompt, or let a compatible agent trigger it from Lumen-specific\nrequests.\n\nThe skill and MCP server complement each other: the skill explains how to work, while\n`@santi020k/lumen-mcp` supplies structured catalog search, framework-specific contracts, recipes,\nsource, tokens, resources, and rules.\n\n## Pick the Right Package\n\nUse the framework requested by the user. Every adapter shares the same Lumen foundation.\n\n| App Target | Install | Import Components From | Load Styles From |\n| --- | --- | --- | --- |\n| Astro | `@santi020k/lumen-astro` | `@santi020k/lumen-astro` | `@santi020k/lumen-astro/styles.css` |\n| React | `@santi020k/lumen-react` | `@santi020k/lumen-react` | `@santi020k/lumen-react/styles.css` |\n| Web Components | `@santi020k/lumen-elements` | `@santi020k/lumen-elements/define` | `@santi020k/lumen-elements/styles.css` |\n| Package metadata | `@santi020k/lumen-core` | `@santi020k/lumen-core` | Not applicable |\n| Optional brand icons | `@santi020k/lumen-icons-brand` | Register once, then use the framework `Icon` | Uses framework styles |\n\nEach framework package includes the shared foundation. Install `@santi020k/lumen` separately only\nwhen you need its framework-neutral CLI or registry metadata.\n\nBrand marks are intentionally excluded from the default Lucide catalog. When a product needs them,\ninstall and register the optional pack once before rendering a namespaced icon:\n\n```ts\nimport { registerLumenBrandIcons } from '@santi020k/lumen-icons-brand'\n\nregisterLumenBrandIcons()\n```\n\nThen use any canonical Font Awesome Free brand name, such as `brand:github`, `brand:discord`,\n`brand:figma`, `brand:linkedin`, `brand:whatsapp`, or `brand:youtube`, through the existing Astro,\nReact, or Web Component `Icon` API. The package also provides `brand:x` as an alias for\n`brand:x-twitter`.\n\nBrand marks keep their recognizable filled geometry instead of being redrawn as Lucide outlines.\nThey still inherit the same Lumen size, alignment, `currentColor`, and accessible-label behavior as\nthe default icon catalog.\n\n## MCP-Assisted Workflow\n\nConnect `@santi020k/lumen-mcp` when the agent supports Model Context Protocol. The server returns\nvalidated structured content as well as readable text, so agents can select components without\nscraping documentation.\n\n```bash\ncodex mcp add lumen -- npx -y @santi020k/lumen-mcp\n```\n\nFor Codex project configuration:\n\n```toml\n[mcp_servers.lumen]\nenabled = true\ncommand = \"npx\"\nargs = [\"-y\", \"@santi020k/lumen-mcp\"]\n```\n\nUse this sequence:\n\n1. Read `lumen://meta` and `lumen://diagnostics` to identify and verify the snapshot.\n2. Read `lumen://rules`.\n3. Search for the use case with `lumen_search`, passing the target `framework` when known.\n4. Inspect the selected framework with `lumen_get_component` and `detail: \"usage\"`.\n5. Follow its framework behavior setup and hook/controller contract.\n6. Read related multi-component guidance with `lumen_get_recipe`.\n7. Request `detail: \"source\"` only when the usage contract is insufficient.\n8. Read `lumen://tokens` before introducing custom styling.\n9. Retain `lumen://catalog-manifest` and use `lumen_diff_catalog` after upgrades to identify contracts that need refreshing.\n\nExample framework-aware component request:\n\n```json\n{\n \"name\": \"lumen_get_component\",\n \"arguments\": {\n \"name\": \"DateRangePicker\",\n \"framework\": \"react\",\n \"detail\": \"usage\"\n }\n}\n```\n\nStable resources are available at `lumen://rules`, `lumen://tokens`, `lumen://components`,\n`lumen://meta`, `lumen://catalog-manifest`, `lumen://diagnostics`,\n`lumen://components/{name}`, and `lumen://recipes/{name}`. See\n[`packages/mcp/README.md`](../packages/mcp/README.md) for Claude Desktop, Cursor, generic stdio,\nlocal repository, and programmatic examples.\n\n## Minimal Setup\n\nImport the stylesheet once in the app's global CSS, root layout, or app entry.\n\n```css\n@import \"@santi020k/lumen-react/styles.css\";\n```\n\nIf Tailwind is present, keep both imports in the same shared CSS entry.\n\n```css\n@import \"@santi020k/lumen-react/layers.css\";\n@import \"tailwindcss\";\n@import \"@santi020k/lumen-react/styles.css\";\n```\n\nKeep the layer prelude first. It places Tailwind base styles below Lumen components and Tailwind\nutilities above them, so consumer spacing, display, radius, width, and responsive visibility\nclasses override Lumen defaults predictably.\n\nAstro apps should mount `UIPrimitives` once in the root layout when using interactive primitives\nsuch as dialogs, menus, popovers, tabs, carousels, command lists, toggles, validated forms, or\ntoasts. Do not place `UIPrimitives` in each component example or next to each primitive instance;\none root include enhances all matching `data-ui-*` markup on the page.\n\n```astro\n---\nimport { UIPrimitives } from '@santi020k/lumen-astro'\n---\n\n<UIPrimitives />\n```\n\n## Astro\n\nUse direct named imports from `@santi020k/lumen-astro`.\n\n```astro\n---\nimport { Button, Card, Input, Label } from '@santi020k/lumen-astro'\n---\n\n<Card>\n <Label for=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n <Button type=\"submit\">Subscribe</Button>\n</Card>\n```\n\n`Stat` defaults to a `div`. Choose `as=\"article\"` for a self-contained metric with supporting\ncontent, or `as=\"section\"` for a labeled region. Do not use a semantic root solely for styling.\nIts visual variants are `default`, `accent`, and `glass`; reserve `accent` for featured metrics and\nkeep glass selective.\n\nFor long reading surfaces, use `Anchor` for local section navigation and pass each item’s optional\nheading `depth` when hierarchy matters. Use `ScrollProgress` for document position; keep `Progress`\nfor application-controlled task completion. `Pill` accepts `neutral`, `brand`, and `outline`\nvariants, plus native link and count composition.\n\n## React\n\nReact components share the same visual classes and data attributes as Astro components. For\nbehavior-heavy primitives, use the React behavior hooks from `@santi020k/lumen-react` (`useDialog`,\n`usePopover`, `useDropdownMenu`, `useTabs`, `useSelect`, `useToast`, and `useTooltip`), which track\nthe Astro runtime's ARIA, keyboard, Escape, dismissal, and toast controller semantics.\n\nThe React package entry is a client boundary. In Next.js, it can be imported by a Server Component\nwithout evaluating Lumen's contexts and hooks in the React server runtime; the rendered Lumen\nsubtree becomes a Client Component boundary. Vite and other client-rendered React applications use\nthe same entry without additional setup.\n`Button`, `Link`, `ButtonLink`, and `Input` accept React 19 DOM refs directly as props.\n`Button asChild` composes the button contract onto one child element, while `Input visualSize` controls\npresentation without shadowing the native numeric `size` attribute.\n`Stat as` and `variant` follow the same semantic-root and visual guidance as the Astro component.\n\n```tsx\nimport '@santi020k/lumen-react/styles.css'\nimport { Button, Card, Input, Label } from '@santi020k/lumen-react'\n\nexport function SubscribeForm() {\n return (\n <Card>\n <Label htmlFor=\"email\">Email</Label>\n <Input id=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n <Button type=\"submit\">Subscribe</Button>\n </Card>\n )\n}\n```\n\n## Web Components\n\nRegister custom elements once, then use `lumen-*` tags in HTML. The elements adapter includes\ninteractive behavior parity for DataTable, Dialog, Popover, DropdownMenu, ContextMenu, Tabs,\nSelect, ThemeBuilder, Toast, Tooltip, forms, RichTextEditor, Schedule, and VirtualList: selection,\nvalidation, rich text command, context menu, schedule drag/drop, theme, and range events, ARIA\nstate, roving/listbox keyboard paths, Escape/outside dismissal, focus return/trapping, native\nselect form participation, and the same toast controller events as the Astro runtime.\n\n```html\n<script type=\"module\">\n import { defineLumenElements } from '@santi020k/lumen-elements/define'\n\n defineLumenElements()\n</script>\n\n<lumen-card>\n <label for=\"email\">Email</label>\n <lumen-input id=\"email\" type=\"email\" placeholder=\"you@example.com\"></lumen-input>\n <lumen-button type=\"submit\">Subscribe</lumen-button>\n</lumen-card>\n```\n\n## Component Selection\n\nThe shared catalog includes:\n\n`Accordion`, `Alert`, `AlertDialog`, `Agenda`, `AspectRatio`, `Attachment`, `Autocomplete`,\n`Avatar`, `Badge`, `BarChart`, `Breadcrumb`, `Bubble`, `Button`, `ButtonGroup`, `Calendar`, `Card`,\n`Carousel`, `Chart`, `Checkbox`, `Collapsible`, `Code`, `Combobox`, `Command`, `ColorPicker`,\n`ContextMenu`, `DataTable`, `DatePicker`, `DateRangePicker`, `Dialog`, `Direction`, `Drawer`,\n`DropdownMenu`, `Empty`, `Field`, `HoverCard`, `Icon`, `Input`, `InputGroup`, `InputOTP`, `Item`, `Kbd`,\n`Label`, `LineChart`, `Marker`, `Menubar`, `Message`, `MessageScroller`, `NativeSelect`, `NavigationMenu`,\n`NumberField`, `Pagination`, `PieChart`, `Popover`, `Progress`, `RadioGroup`, `Resizable`, `RichTextEditor`,\n`ScrollArea`, `Schedule`, `SearchField`, `Select`, `Separator`, `Sheet`, `Sidebar`, `Skeleton`,\n`Slider`, `Sparkline`, `Spinner`, `Switch`, `Table`, `Tabs`, `TagGroup`, `Textarea`, `ThemeBuilder`,\n`TimeField`, `Toast`, `Toggle`, `ToggleGroup`, `Tooltip`, `Tree`, `TreeGrid`, `Typography`, and\n`VirtualList`.\n\n## Product Recipes\n\n- Use `Sparkline` for a compact trend beside a labelled metric, `BarChart` for categorical\n comparison, `LineChart` for ordered or time-series data, and `PieChart` for a small\n part-to-whole breakdown. Pass already-aggregated `LumenChartSeries` data; keep statistics,\n resampling, model evaluation, and domain calculations in application code. Keep `showTable`\n enabled unless the same values are already available in a nearby semantic table. Prefer a bar\n chart when precise slice comparison matters or the pie would exceed roughly seven categories.\n Use `Chart` as the custom SVG/canvas escape hatch.\n- Use `Icon name=\"search\"` or any Lucide icon name for standard interface pictograms. Kebab-case\n names and Lucide aliases work. Pair decorative icons with `decorative`, and pass `label` only\n when the icon carries meaning on its own. Install and register\n `@santi020k/lumen-icons-brand` for supported brand marks, then use names such as\n `brand:github`. Render project-specific or unsupported brand SVGs through the default `Icon`\n slot. Astro reports unknown named icons during development instead of failing silently.\n- Use `Schedule` with `Agenda`, `Calendar`, and `DatePicker` for booking, CRM, content calendar, and\n event planning screens. Mark slots with `data-ui-schedule-slot` and events with\n `data-ui-schedule-event`; the runtime emits `ui:schedule-change` when a draggable event is moved.\n `Calendar` renders a hidden input plus selectable date grid; Astro `UIPrimitives` and registered\n Web Components wire month navigation and roving keyboard focus directly, while React apps can use\n the `Calendar` component or `useCalendar` for the same date selection contract.\n Astro `UIPrimitives` and registered Web Components bind schedule drag/drop directly; React apps\n can use `useSchedule` for `rootProps`, `getEventProps`, `getSlotProps`, and `ui:schedule-change`\n parity. Use `createScheduleSlots`, `moveScheduleEvent`, and `expandRecurringScheduleEvent` from\n `@santi020k/lumen-core` for reusable schedule state; use `getScheduleConflicts` and\n `canPlaceScheduleEvent` before committing drag/drop changes. Persist local schedule edits with\n `createScheduleStorageKey`, `saveScheduleEvents`, and `loadScheduleEvents` against any\n `localStorage`-compatible adapter. Use `resizeScheduleEvent` and `resizeScheduleEvents` for\n snap-to-grid resize handles.\n- Use `DataTable`, `Tree`, `TreeGrid`, `VirtualList`, `Pagination`, and `Command` for dense data\n collection workflows. Astro and Elements wire selectable/sortable `DataTable` behavior and\n `VirtualList` range events; React emits the same data attributes for app-level adapters. `Tree`\n and `TreeGrid` use roving keyboard focus, and `VirtualList` emits `ui:virtual-list-range` as the\n rendered range changes. Use `createDataViewState`,\n `serializeDataViewState`, `parseDataViewState`, `applyDataViewState`, and `getVirtualRange` for\n saved views, filtering, sorting, pagination, and virtualization math. Use\n `createDataViewStorageKey`, `saveDataViewState`, and `loadDataViewState` when saved views should\n survive navigation or reloads. Use `pinDataViewColumn`, `unpinDataViewColumn`,\n `toggleDataViewSelection`, `createDataViewSearchParams`, and `createDataViewServerRequest` when\n connecting dense views to router state or server-backed data.\n- Use `Resizable` for split-pane editors, dashboards, inspectors, and side-by-side review layouts.\n Astro `UIPrimitives` and registered Web Components generate separator handles and pane sizing\n directly; React apps can use the `Resizable` component or `useResizable` for pointer, keyboard,\n min/max, and double-click reset parity.\n- Use `ThemeBuilder`, `ColorPicker`, `Card`, `Button`, and `Input` to build token preview and export\n tools. Add `data-ui-theme-brand-hue`, `data-ui-theme-accent-hue`, `data-ui-theme-scheme`,\n `data-ui-theme-mode`, manual color inputs such as `data-ui-theme-primary-hex`, and\n `data-ui-theme-target` for scoped live previews. Add `data-ui-theme-export-format`,\n `data-ui-theme-export`, and `data-ui-theme-output` to copy CSS, Figma variable JSON, or design\n token JSON. Astro `UIPrimitives` and registered Web Components wire those controls directly;\n React apps can use `useThemeBuilder` for the same tokens, exports, and control props. Use\n `createThemePalette`, `createThemeBuilderTokens`, `exportThemeBuilderValue`, `exportThemeCss`,\n `parseThemeCss`, and `scoreThemeContrast`\n for theme import/export and accessibility checks. Use `suggestReadableInk`, `mergeThemeTokens`,\n and `tuneThemeContrast` when generated palettes need readable foreground repair.\n- Use `RichTextEditor` with `ButtonGroup`, `ToggleGroup`, and `Textarea` for editor compositions.\n Controls with `data-ui-editor-command` dispatch browser editing commands and emit\n `ui:editor-command`; use `data-ui-editor-value` for headings, links, and other value-bearing\n commands. Editable surfaces support common formatting shortcuts, synchronize toggle\n `aria-pressed` state, and emit `ui:editor-change` with HTML and plain text. Astro `UIPrimitives`\n and registered Web Components bind those controls directly; React apps can use\n `useRichTextEditor` for `rootProps`, `getCommandProps`, `getEditableProps`, and `executeCommand`.\n For Tiptap, ProseMirror, Lexical, or Markdown engines, keep the external editor\n package in the app and bridge toolbar buttons through the emitted command event instead of adding\n the editor engine to Lumen.\n- Use `Autocomplete`, `SearchField`, `NumberField`, `TimeField`, `DateRangePicker`, `ColorPicker`,\n and `TagGroup` when forms need more than plain text inputs. Add `data-ui-form` to forms that\n should reflect native Constraint Validation API state into `Field` error slots on blur and submit.\n For `InputOTP`, Astro `UIPrimitives` and registered Web Components render/sync a real native input\n with visual OTP segments; React apps can use the `InputOTP` component or `useInputOTP` for the\n same sanitization, paste handling, and caret navigation.\n For `DateRangePicker`, Astro `UIPrimitives` and registered Web Components sync the paired native\n date input `min`/`max` constraints directly; React apps can use `useDateRangePicker` for the same\n start/end syncing props.\n Use native attributes such as `required`, `pattern`, `min`, `max`, and `type`; add\n `data-error-required`, `data-error-pattern`, `data-error-min`, `data-error-max`, or\n `data-error-custom` when a control needs custom copy. Listen for `ui:validate` to call\n `control.setCustomValidity(message)` before the runtime reads validity, and listen for\n `ui:invalid` or `ui:valid` on the form for submission state. Astro `UIPrimitives` and registered\n Web Components bind `data-ui-form` directly; React apps can use `useFormValidation` with `Field`\n to get the same control props, CustomEvents, and error slot updates.\n- Use `Toast` for transient feedback. Static `<Toast>` markup works without\n JavaScript. With Astro `UIPrimitives` or registered Web Components, create toasts with\n `window.LumenToast.create(detail)`, `LumenToast.create(detail)` from `@santi020k/lumen-elements`,\n or `document.dispatchEvent(new CustomEvent('ui:toast', { detail }))`; update them with\n `.update(id, detail)` or `ui:toast-update`; and dismiss them with `.dismiss(id?)` or\n `ui:toast-dismiss`. `detail` supports `title`, `description`, `variant`, `duration`, `placement`,\n `max`, and `action: { label, value }`. Destructive toasts use `role=\"alert\"`; other variants use\n `role=\"status\"`. Runtime toasts pause their timeout on hover or focus, and Escape dismisses the\n focused toast.\n\n## Runtime CustomEvents\n\nWhen `UIPrimitives` is mounted, or when Web Components are registered for matching behavior, Lumen\nuses these CustomEvents:\n\n| Event | Target | Detail | Fires When |\n| --- | --- | --- | --- |\n| `ui:data-table-selection-change` | `DataTable` root `[data-ui-datatable]` | `{ values: string[] }` | Selectable row checkboxes, the select-all checkbox, or form reset changes selected row values. |\n| `ui:schedule-change` | `Schedule` root `[data-ui-schedule]` | `{ eventId?: string, slot?: string }` | A draggable schedule event is dropped on a `[data-ui-schedule-slot]`. |\n| `ui:virtual-list-range` | `VirtualList` root `[data-ui-virtual-list]` | `{ startIndex: number, endIndex: number }` | The virtual list calculates its visible range on init or scroll. |\n| `ui:tag-remove` | `TagGroup` root `.ui-tag-group` or `[data-ui-tag-group]` | `{ value?: string }` | A `[data-ui-tag-remove]` control removes its closest tag or list item. |\n| `ui:editor-command` | `RichTextEditor` root `[data-ui-rich-text-editor]` | `{ command: string, executed: boolean, value?: string }` | A toolbar control or keyboard shortcut runs an editor command. |\n| `ui:editor-change` | `RichTextEditor` root `[data-ui-rich-text-editor]` | `{ html: string, text: string }` | Editable content changes or an editor command runs. |\n| `ui:theme-change` | `ThemeBuilder` root `[data-ui-theme-builder]` | `{ hue: number, accentHue: number, mode: 'generated' \\| 'manual', scheme: 'dark' \\| 'light', tokens: Record<string, string> }` | Hue, manual color, mode, or scheme controls update generated tokens. |\n| `ui:theme-export` | `ThemeBuilder` root `[data-ui-theme-builder]` | `{ css?: string, format: 'css' \\| 'figma' \\| 'tokens', tokens: Record<string, string> \\| null, value: string }` | A `[data-ui-theme-export]` control writes the selected export to the output and clipboard when available. |\n| `ui:validate` | Form `[data-ui-form]` | `{ control, form, value }` | Before validation state is read, so custom code can call `control.setCustomValidity(message)`. |\n| `ui:invalid` | Form `[data-ui-form]` | `{ control?, controls?, form }` | Blur or submit validation finds invalid controls. Failed submits focus the first invalid control. |\n| `ui:valid` | Form `[data-ui-form]` | `{ control?, controls?, form }` | Blur or submit validation finds the checked control or form valid. |\n| `ui:toast` | `document` | `{ id?, title?, description?, variant?, duration?, placement?, action? }` | Creates a runtime toast in the matching notification viewport. |\n| `ui:toast-update` | `document` | `{ id, title?, description?, variant?, duration? }` | Updates a runtime toast. |\n| `ui:toast-dismiss` | `document` | `{ id? }` | Dismisses one runtime toast, or all runtime toasts when `id` is omitted. |\n| `ui:toast-action` | Toast `[data-ui-toast]` | `{ id, value? }` | A runtime toast action button is pressed, unless the action specifies a custom event name. |\n\n## Registry Helper\n\n`@santi020k/lumen` exports typed component, recipe, and documentation metadata from\n`@santi020k/lumen/registry`. The package also ships a small `lumen` binary. Individual components\nare addressable by name, including kebab-case aliases such as `data-table`:\n\n```bash\nlumen list\nlumen show Button\nlumen show data-table\nlumen add Button\nlumen add Button --target react\nlumen add Button --target elements\nlumen add data-table\nlumen show scheduler\nlumen add scheduler\nlumen add scheduler --target react\nlumen add scheduler --target elements\nlumen add scheduler --dry-run\nlumen add scheduler --fail-on-conflict\nlumen add scheduler --force\nlumen add scheduler --merge\nlumen list --registry ./registry/lumen.registry.json\nlumen add custom-recipe --registry ./registry/custom.registry.json\nlumen add private-recipe --registry https://example.com/lumen.registry.json --registry-token \"$TOKEN\"\nlumen install\n```\n\n`lumen add <component>` defaults to an Astro wrapper. Use `--target react` for a local React wrapper\nor `--target elements` for a custom-elements starter. Bundled recipes also accept `--target astro`,\n`--target react`, and `--target elements`; external registry inline files keep their authored paths\nand sources.\n\nBefore inventing a wrapper or custom class pattern, check the component source in\n`packages/astro/components`. Astro is the reference implementation for props, class names, data\nattributes, and accessible markup.\n\n## Styling Rules for Generated Code\n\n- Do not require consumers to configure Tailwind for Lumen components.\n- Prefer component props and composition before adding custom CSS.\n- Use the shared token names for custom surfaces: `canvas`, `surface`, `surface-muted`,\n `surface-strong`, `line`, `ink`, `ink-soft`, `ink-muted`, `brand`, `brand-solid`, `brand-soft`,\n `accent`, `success`, `warning`, and `danger`.\n- Use `glass` as a boolean prop or attribute for glass surfaces when supported.\n- Do not generate `surface=\"glass\"` for overlays; it is a deprecated alias that maps to `glass`.\n- Preserve semantic labels, keyboard paths, focus states, and native form attributes.\n\n## Figma Handoff\n\nUse `exportThemeFigmaVariables` from `@santi020k/lumen-core/figma` when a design workflow needs\nFigma variable-friendly color values, and `exportThemeDesignTokens` when exporting standard design\ntoken JSON for token importers. See [docs/figma.md](figma.md) for the recommended Figma workflow.\n\n## When Editing This Repo\n\n- Shared contracts belong in `packages/core`.\n- Astro implementation and standalone CSS belong in `packages/astro`.\n- React-specific primitives belong in `packages/react`.\n- Web Component-specific primitives belong in `packages/elements`.\n- Update the relevant package README when public usage changes.\n- Add tests beside package code as `*.test.ts` when behavior, exported metadata, or component\n contracts change.\n",
|
|
26646
|
+
"readme": "<p align=\"center\">\n <a href=\"https://lumen.santi020k.com\">\n <img src=\"./apps/docs/public/logo.svg\" alt=\"Lumen UI\" width=\"239\" height=\"60\">\n </a>\n</p>\n\n<h1 align=\"center\">Lumen UI</h1>\n\n<p align=\"center\">\n A multi-framework UI system with 123 accessible primitives for Astro, React, and Web Components.\n</p>\n\n<p align=\"center\">\n <a href=\"https://lumen.santi020k.com\">Documentation</a>\n ·\n <a href=\"https://lumen.santi020k.com/docs/components\">Components</a>\n ·\n <a href=\"https://www.figma.com/community/file/1662337342676541513\">Figma library</a>\n ·\n <a href=\"https://github.com/santi020k/lumen/issues\">Issues</a>\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/santi020k/lumen/actions\"><img alt=\"GitHub Actions\" src=\"https://img.shields.io/github/actions/workflow/status/santi020k/lumen/ci.yml?branch=main&style=flat-square\"></a>\n <a href=\"https://www.npmjs.com/package/@santi020k/lumen-astro\"><img alt=\"npm version\" src=\"https://img.shields.io/npm/v/@santi020k/lumen-astro?style=flat-square&label=npm\"></a>\n <a href=\"./LICENSE\"><img alt=\"MIT license\" src=\"https://img.shields.io/badge/license-MIT-111827?style=flat-square\"></a>\n</p>\n\nLumen gives applications a consistent visual language without tying them to one rendering model.\nIts packages share tokens, component contracts, styles, and interaction patterns while keeping each\nframework's native authoring experience.\n\n- **Framework native:** Astro components, React primitives, and standards-based custom elements.\n- **Accessible by default:** semantic markup, keyboard paths, focus management, and reduced-motion\n support are built into the primitives.\n- **Standalone CSS:** no Tailwind configuration is required. Tailwind users get an explicit layer\n integration.\n- **Progressively enhanced:** Astro interactions use a small client runtime instead of requiring an\n application framework.\n- **Ready for design and AI workflows:** published Figma resources, a portable agent skill, an MCP\n server, `llms.txt`, and a machine-readable registry ship alongside the component system.\n\n## Quick start\n\nInstall the package for your framework:\n\n```bash\n# Astro\npnpm add @santi020k/lumen-astro\n\n# React\npnpm add @santi020k/lumen-react\n\n# Web Components\npnpm add @santi020k/lumen-elements\n```\n\n### Astro\n\nImport the stylesheet and mount `UIPrimitives` once in your root layout. The runtime enhances all\ninteractive Lumen markup on the page.\n\n```astro\n---\nimport '@santi020k/lumen-astro/styles.css'\nimport { UIPrimitives } from '@santi020k/lumen-astro'\n---\n\n<html lang=\"en\">\n <body>\n <slot />\n <UIPrimitives />\n </body>\n</html>\n```\n\n```astro\n---\nimport { Button, Card, Input } from '@santi020k/lumen-astro'\n---\n\n<Card>\n <label for=\"email\">Email</label>\n <Input id=\"email\" name=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n <Button>Subscribe</Button>\n</Card>\n```\n\n### React\n\nLoad the stylesheet once from your app entry or global CSS:\n\n```tsx\nimport '@santi020k/lumen-react/styles.css'\nimport { Button, Card, Input } from '@santi020k/lumen-react'\n\nexport function SubscribeForm() {\n return (\n <Card>\n <label htmlFor=\"email\">Email</label>\n <Input id=\"email\" name=\"email\" type=\"email\" placeholder=\"you@example.com\" />\n <Button>Subscribe</Button>\n </Card>\n )\n}\n```\n\n### Web Components\n\nImport the styles and register the elements once:\n\n```html\n<style>\n @import \"@santi020k/lumen-elements/styles.css\";\n</style>\n\n<script type=\"module\">\n import { defineLumenElements } from '@santi020k/lumen-elements/define'\n\n defineLumenElements()\n</script>\n\n<lumen-card>\n <label for=\"email\">Email</label>\n <lumen-input id=\"email\" name=\"email\" type=\"email\" placeholder=\"you@example.com\"></lumen-input>\n <lumen-button>Subscribe</lumen-button>\n</lumen-card>\n```\n\nSee the [documentation](https://lumen.santi020k.com/docs) for installation, theming, component\nexamples, and API details.\n\n## Tailwind CSS\n\nKeep the layer prelude, Tailwind import, and Lumen stylesheet in the same shared CSS entry. Replace\n`lumen-astro` with the package for your framework.\n\n```css\n@import \"@santi020k/lumen-astro/layers.css\";\n@import \"tailwindcss\";\n@import \"@santi020k/lumen-astro/styles.css\";\n```\n\nThis order places Tailwind base styles before Lumen components and Tailwind utilities above Lumen\ncomponent defaults.\n\n## Packages\n\n| Package | Purpose |\n| --- | --- |\n| [`@santi020k/lumen-astro`](./packages/astro) | Reference implementation, Astro components, and progressive-enhancement runtime |\n| [`@santi020k/lumen-react`](./packages/react) | React components and behavior hooks |\n| [`@santi020k/lumen-elements`](./packages/elements) | Standards-based Web Components |\n| [`@santi020k/lumen-core`](./packages/core) | Shared tokens, metadata, class helpers, and behavior contracts |\n| [`@santi020k/lumen-icons-brand`](./packages/icons-brand) | Optional namespaced brand icons for the shared `Icon` API |\n| [`@santi020k/lumen`](./packages/lumen) | Umbrella package, CLI, registry metadata, and public package map |\n| [`@santi020k/lumen-mcp`](./packages/mcp) | MCP server for component discovery and source retrieval |\n\n## AI and design workflows\n\nInstall the portable Lumen skill in Codex, Claude Code, Cursor, Windsurf, and other compatible\ncoding agents:\n\n```bash\nnpx skills add santi020k/lumen --skill lumen-ui\n```\n\nThe skill teaches agents how to select, compose, theme, and verify Lumen primitives. Pair it with\n[`@santi020k/lumen-mcp`](./packages/mcp) when an agent needs to search the live catalog or retrieve\ncurrent source, props, tokens, and usage rules.\n\nAdditional machine-readable surfaces include:\n\n- [`llms.txt`](./llms.txt) for a concise project map.\n- [`docs/ai-usage.md`](./docs/ai-usage.md) for downstream generation examples.\n- [`registry/lumen.registry.json`](./registry/lumen.registry.json) for recipes and installable file\n groups.\n- [`docs/figma.md`](./docs/figma.md) for Figma variables and Code Connect workflows.\n\n## Contributing\n\nLumen is a pnpm workspace. Astro is the reference implementation; shared contracts belong in\n`packages/core`, while framework-specific behavior stays in its adapter package.\n\n```bash\npnpm install\npnpm run dev\npnpm run validate\n```\n\nRead [`CONTRIBUTING.md`](./CONTRIBUTING.md) before opening a pull request. User-visible package\nchanges require a changeset.\n\n## License\n\nLumen is available under the [MIT License](./LICENSE).\n"
|
|
24568
26647
|
},
|
|
24569
26648
|
"meta": {
|
|
24570
|
-
"catalogHash": "
|
|
24571
|
-
"componentCount":
|
|
26649
|
+
"catalogHash": "d823f5c7ed0ee5c370cf78381b622ef60046afe977464a75f93e6464db4f037d",
|
|
26650
|
+
"componentCount": 129,
|
|
24572
26651
|
"packages": [
|
|
24573
26652
|
"@santi020k/lumen-astro",
|
|
24574
26653
|
"@santi020k/lumen-react",
|
|
@@ -24576,16 +26655,16 @@
|
|
|
24576
26655
|
"@santi020k/lumen-core"
|
|
24577
26656
|
],
|
|
24578
26657
|
"packageVersions": {
|
|
24579
|
-
"@santi020k/lumen-astro": "0.
|
|
24580
|
-
"@santi020k/lumen-core": "0.
|
|
24581
|
-
"@santi020k/lumen-elements": "0.
|
|
24582
|
-
"@santi020k/lumen-mcp": "0.
|
|
24583
|
-
"@santi020k/lumen-react": "0.
|
|
26658
|
+
"@santi020k/lumen-astro": "0.4.0",
|
|
26659
|
+
"@santi020k/lumen-core": "0.4.0",
|
|
26660
|
+
"@santi020k/lumen-elements": "0.4.0",
|
|
26661
|
+
"@santi020k/lumen-mcp": "0.4.0",
|
|
26662
|
+
"@santi020k/lumen-react": "0.4.0"
|
|
24584
26663
|
},
|
|
24585
26664
|
"registryName": "lumen",
|
|
24586
26665
|
"registryVersion": 1,
|
|
24587
26666
|
"schemaVersion": 3,
|
|
24588
|
-
"serverVersion": "0.
|
|
26667
|
+
"serverVersion": "0.4.0"
|
|
24589
26668
|
},
|
|
24590
26669
|
"recipes": [
|
|
24591
26670
|
{
|
|
@@ -24711,10 +26790,50 @@
|
|
|
24711
26790
|
"elements": "lumen add rich-text-editor --target elements",
|
|
24712
26791
|
"react": "lumen add rich-text-editor --target react"
|
|
24713
26792
|
}
|
|
26793
|
+
},
|
|
26794
|
+
{
|
|
26795
|
+
"name": "data-visualization",
|
|
26796
|
+
"type": "recipe",
|
|
26797
|
+
"components": [
|
|
26798
|
+
"Chart",
|
|
26799
|
+
"Sparkline",
|
|
26800
|
+
"BarChart",
|
|
26801
|
+
"LineChart",
|
|
26802
|
+
"PieChart",
|
|
26803
|
+
"Stat",
|
|
26804
|
+
"Meter"
|
|
26805
|
+
],
|
|
26806
|
+
"categories": [
|
|
26807
|
+
"Data display"
|
|
26808
|
+
],
|
|
26809
|
+
"description": "A data visualization composition using Chart, Sparkline, BarChart, LineChart, PieChart, Stat, Meter.",
|
|
26810
|
+
"install": {
|
|
26811
|
+
"astro": "lumen add data-visualization --target astro",
|
|
26812
|
+
"elements": "lumen add data-visualization --target elements",
|
|
26813
|
+
"react": "lumen add data-visualization --target react"
|
|
26814
|
+
}
|
|
24714
26815
|
}
|
|
24715
26816
|
],
|
|
24716
26817
|
"rules": "# Lumen UI\n\nLumen is a multi-framework primitive UI system with Astro as the reference implementation.\n\nUse these files first when generating, reviewing, or migrating apps that use Lumen:\n\n- README.md: public overview and package strategy.\n- docs/ai-usage.md: AI-focused setup, package selection, and component selection.\n- skills/lumen-ui/SKILL.md: portable Agent Skill for building, reviewing, and theming Lumen interfaces.\n- docs/feature-roadmap.md: competitor-informed gaps and implementation priorities.\n- registry/lumen.registry.json: installable component, recipe, and documentation manifest.\n- packages/core/src/components.ts: authoritative shared component catalog.\n- packages/astro/components: reference component markup and prop shapes.\n- packages/astro/styles/lumen.css: standalone CSS contract for all frameworks.\n- @santi020k/lumen-mcp: Model Context Protocol server exposing snapshot provenance, structured component discovery, framework-aware usage/source, recipes, tolerant search, tokens, rules, and lumen:// resources for AI agents.\n\nInstall the portable Lumen Agent Skill:\n\n```bash\nnpx skills add santi020k/lumen --skill lumen-ui\n```\n\nDefault usage:\n\n```astro\n---\nimport { Button, Card, Input } from '@santi020k/lumen-astro'\nimport { UIPrimitives } from '@santi020k/lumen-astro'\nimport '@santi020k/lumen-astro/styles.css'\n---\n\n<UIPrimitives />\n<Card>\n <label for=\"email\">Email</label>\n <Input id=\"email\" type=\"email\" />\n <Button>Subscribe</Button>\n</Card>\n```\n\nRules for agents:\n\n- When Lumen MCP is connected, read `lumen://meta`, `lumen://diagnostics`, and `lumen://rules`, pass the target framework to `lumen_search`, and follow the framework behavior returned by `lumen_get_component`. Retain `lumen://catalog-manifest` and use `lumen_diff_catalog` after upgrades when the client supports cached context.\n- Prefer Astro unless the user explicitly targets React or Web Components.\n- In React, use the visual components with behavior hooks for Dialog, Popover, DropdownMenu, Tabs, Select, Toast, and Tooltip instead of mounting the Astro runtime.\n- In Web Components, registered `lumen-*` elements include behavior parity for Dialog, Popover, DropdownMenu, Tabs, Select, Toast, and Tooltip, including ARIA state, keyboard paths, Escape/outside dismissal, focus handling, native select form participation, and the shared toast controller.\n- Do not require Tailwind configuration for Lumen components.\n- Use public tokens: canvas, surface, surface-muted, surface-strong, line, ink, ink-soft, ink-muted, brand, brand-solid, brand-soft, accent, success, warning, danger.\n- Mount `UIPrimitives` once for interactive Astro primitives.\n- Use `glass` for glass surfaces. Overlay `surface=\"glass\"` is a deprecated compatibility alias that maps to `glass`.\n- Treat schedule, data collection, rich text, theme builder, and advanced fields as supported surfaces with progressively enhanced behavior.\n- Use `lumen list`, `lumen show <component>`, and `lumen add <component>` for individually addressable registry components; component names also resolve from kebab-case aliases such as `data-table`.\n- Runtime CustomEvents used by `UIPrimitives`: `ui:data-table-selection-change` from `[data-ui-datatable]` with `{ values }` (`ui:datatable-selection-change` remains a deprecated alias until 1.0); `ui:schedule-change` from `[data-ui-schedule]` with `{ eventId, slot }`; `ui:virtual-list-range` from `[data-ui-virtual-list]` with `{ startIndex, endIndex }`; `ui:tag-remove` from tag groups with `{ value }`; `ui:editor-command` from rich text editors with `{ command }`; `ui:theme-change` from theme builders with `{ hue, tokens }`; `ui:theme-export` from theme builders with `{ css }`; `ui:validate`, `ui:invalid`, and `ui:valid` from `[data-ui-form]` for native Constraint Validation API enhancement; document-level `ui:toast`, `ui:toast-update`, and `ui:toast-dismiss` for runtime toasts; `ui:toast-action` from `[data-ui-toast]` when an action button is pressed.\n- Add `data-ui-form` to forms that should reflect `required`, `pattern`, `min`, `max`, `type`, and custom `setCustomValidity()` state into Field error slots on blur and submit. Use `data-error-required`, `data-error-pattern`, `data-error-min`, `data-error-max`, or `data-error-custom` to override browser validation messages.\n- Toasts use `Sonner` viewports with `placement` and `maxCount`. With `UIPrimitives` or registered Web Components, use `window.LumenToast.create(detail)`, `.update(id, detail)`, and `.dismiss(id?)`, import `LumenToast` from `@santi020k/lumen-elements`, or dispatch the matching document events. Runtime toast `detail` supports `title`, `description`, `variant`, `duration`, `placement`, `max`, and `action`.\n",
|
|
24717
26818
|
"tokens": {
|
|
26819
|
+
"chart": {
|
|
26820
|
+
"axis": "var(--ink-muted)",
|
|
26821
|
+
"divergingMid": "220 13% 91%",
|
|
26822
|
+
"divergingNegative": "0 84% 60%",
|
|
26823
|
+
"divergingPositive": "221 83% 53%",
|
|
26824
|
+
"grid": "var(--line)",
|
|
26825
|
+
"sequentialHigh": "221 83% 40%",
|
|
26826
|
+
"sequentialLow": "218 100% 97%",
|
|
26827
|
+
"sequentialMid": "221 83% 67%",
|
|
26828
|
+
"series1": "221 83% 53%",
|
|
26829
|
+
"series2": "168 76% 36%",
|
|
26830
|
+
"series3": "280 72% 56%",
|
|
26831
|
+
"series4": "25 95% 53%",
|
|
26832
|
+
"series5": "340 82% 55%",
|
|
26833
|
+
"series6": "190 82% 42%",
|
|
26834
|
+
"series7": "52 92% 45%",
|
|
26835
|
+
"series8": "215 16% 47%"
|
|
26836
|
+
},
|
|
24718
26837
|
"colors": {
|
|
24719
26838
|
"accent": "264 95% 57%",
|
|
24720
26839
|
"brand": "264 92% 47%",
|