@udixio/mcp 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -0
- package/dist/bundled/components-index.json +369 -0
- package/dist/bundled/doc-src/components/Code.astro +14 -0
- package/dist/bundled/doc-src/components/ComponentPreview.astro +218 -0
- package/dist/bundled/doc-src/data/components/button.overview.mdx +152 -0
- package/dist/bundled/doc-src/data/components/card.overview.mdx +91 -0
- package/dist/bundled/doc-src/data/components/carousel.overview.mdx +108 -0
- package/dist/bundled/doc-src/data/components/checkbox.overview.mdx +172 -0
- package/dist/bundled/doc-src/data/components/chip.overview.mdx +216 -0
- package/dist/bundled/doc-src/data/components/date-picker.overview.mdx +102 -0
- package/dist/bundled/doc-src/data/components/divider.overview.mdx +54 -0
- package/dist/bundled/doc-src/data/components/fab-menu.overview.mdx +69 -0
- package/dist/bundled/doc-src/data/components/fab.overview.mdx +80 -0
- package/dist/bundled/doc-src/data/components/icon-button.overview.mdx +155 -0
- package/dist/bundled/doc-src/data/components/navigation-rail.overview.mdx +142 -0
- package/dist/bundled/doc-src/data/components/progress-indicator.overview.mdx +49 -0
- package/dist/bundled/doc-src/data/components/slider.overview.mdx +64 -0
- package/dist/bundled/doc-src/data/components/snackbar.overview.mdx +37 -0
- package/dist/bundled/doc-src/data/components/switch.overview.mdx +41 -0
- package/dist/bundled/doc-src/data/components/tabs.overview.mdx +171 -0
- package/dist/bundled/doc-src/data/components/temp.md +506 -0
- package/dist/bundled/doc-src/data/components/text-field.overview.mdx +90 -0
- package/dist/bundled/doc-src/data/components/tooltip.overview.mdx +159 -0
- package/dist/bundled/doc-src/data/pages/mcp.mdx +92 -0
- package/dist/bundled/doc-src/layouts/components.astro +87 -0
- package/dist/bundled/doc-src/layouts/layout.astro +55 -0
- package/dist/bundled/doc-src/pages/404.astro +18 -0
- package/dist/bundled/doc-src/pages/[...url].astro +34 -0
- package/dist/bundled/doc-src/pages/animations.astro +322 -0
- package/dist/bundled/doc-src/pages/components/[component]/api.astro +89 -0
- package/dist/bundled/doc-src/pages/components/[component]/index.astro +5 -0
- package/dist/bundled/doc-src/pages/components/[component]/overview.astro +37 -0
- package/dist/bundled/doc-src/pages/components/index.astro +130 -0
- package/dist/bundled/doc-src/pages/index.astro +5 -0
- package/dist/bundled/doc-src/pages/search.astro +12 -0
- package/dist/bundled/doc-src/pages/themes.astro +86 -0
- package/dist/bundled/theme.json +359 -0
- package/dist/cli.mjs +450 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +5 -0
- package/dist/lib/cli.d.ts +3 -0
- package/dist/lib/cli.d.ts.map +1 -0
- package/dist/lib/loaders/components.d.ts +6 -0
- package/dist/lib/loaders/components.d.ts.map +1 -0
- package/dist/lib/loaders/docs.d.ts +11 -0
- package/dist/lib/loaders/docs.d.ts.map +1 -0
- package/dist/lib/loaders/theme.d.ts +37 -0
- package/dist/lib/loaders/theme.d.ts.map +1 -0
- package/dist/lib/main.d.ts +3 -0
- package/dist/lib/main.d.ts.map +1 -0
- package/dist/lib/mcp.d.ts +3 -0
- package/dist/lib/mcp.d.ts.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
import {
|
|
3
|
+
Button,
|
|
4
|
+
Card,
|
|
5
|
+
Carousel,
|
|
6
|
+
CarouselItem,
|
|
7
|
+
Checkbox,
|
|
8
|
+
Chip,
|
|
9
|
+
Chips,
|
|
10
|
+
DatePicker,
|
|
11
|
+
Divider,
|
|
12
|
+
Fab,
|
|
13
|
+
FabMenu,
|
|
14
|
+
IconButton,
|
|
15
|
+
NavigationRail,
|
|
16
|
+
NavigationRailItem,
|
|
17
|
+
ProgressIndicator,
|
|
18
|
+
SideSheet,
|
|
19
|
+
Slider,
|
|
20
|
+
Snackbar,
|
|
21
|
+
Switch,
|
|
22
|
+
Tab,
|
|
23
|
+
TabGroup,
|
|
24
|
+
TabPanel,
|
|
25
|
+
TabPanels,
|
|
26
|
+
Tabs,
|
|
27
|
+
TextField,
|
|
28
|
+
Tooltip,
|
|
29
|
+
} from '@udixio/ui-react';
|
|
30
|
+
import {
|
|
31
|
+
faBell,
|
|
32
|
+
faGear,
|
|
33
|
+
faHouse,
|
|
34
|
+
faPlus,
|
|
35
|
+
faStar,
|
|
36
|
+
} from '@fortawesome/free-solid-svg-icons';
|
|
37
|
+
|
|
38
|
+
type PreviewProps = {
|
|
39
|
+
id: string;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const { id } = Astro.props as PreviewProps;
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<div class="w-full flex items-center justify-center gap-4 pointer-events-none">
|
|
46
|
+
{
|
|
47
|
+
id === 'button' && (
|
|
48
|
+
<div class="flex flex-wrap gap-2">
|
|
49
|
+
<Button label="Primary" />
|
|
50
|
+
<Button label="Outlined" variant="outlined" />
|
|
51
|
+
<Button label="Tonal" variant="tonal" />
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
{
|
|
56
|
+
id === 'card' && (
|
|
57
|
+
<Card className="p-4">
|
|
58
|
+
<div class="h-4 w-1/2 rounded bg-surface-variant" />
|
|
59
|
+
<div class="mt-3 h-3 w-full rounded bg-surface-variant/60" />
|
|
60
|
+
<div class="mt-2 h-3 w-5/6 rounded bg-surface-variant/60" />
|
|
61
|
+
</Card>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
{
|
|
65
|
+
id === 'carousel' && (
|
|
66
|
+
<Carousel gap={12} outputRange={[120, 160]} inputRange={[0.1, 0.8]}>
|
|
67
|
+
{[0, 1, 2, 3].map((index) => (
|
|
68
|
+
<CarouselItem index={index} width={140} outputRange={[120, 160]}>
|
|
69
|
+
<Card className="p-4">Item {index + 1}</Card>
|
|
70
|
+
</CarouselItem>
|
|
71
|
+
))}
|
|
72
|
+
</Carousel>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
{
|
|
76
|
+
id === 'chip' && (
|
|
77
|
+
<div class="flex flex-wrap gap-2">
|
|
78
|
+
<Chip label="Chip" />
|
|
79
|
+
<Chip label="Selected" activated />
|
|
80
|
+
<Chip label="Input" variant="tonal" />
|
|
81
|
+
</div>
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
{
|
|
85
|
+
id === 'chips' && (
|
|
86
|
+
<Chips
|
|
87
|
+
items={[{ label: 'Design' }, { label: 'Research' }, { label: 'QA' }]}
|
|
88
|
+
onItemsChange={() => {}}
|
|
89
|
+
/>
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
{
|
|
93
|
+
id === 'divider' && (
|
|
94
|
+
<div class="flex items-center gap-4">
|
|
95
|
+
<Divider className="flex-1" />
|
|
96
|
+
<span class="text-label-small text-on-surface-variant">OR</span>
|
|
97
|
+
<Divider className="flex-1" />
|
|
98
|
+
</div>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
{
|
|
102
|
+
id === 'fab' && (
|
|
103
|
+
<div class="flex items-center gap-3">
|
|
104
|
+
<Fab label="Create" icon={faPlus} />
|
|
105
|
+
<Fab label="Add" extended icon={faPlus} />
|
|
106
|
+
</div>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
{
|
|
110
|
+
id === 'fab-menu' && (
|
|
111
|
+
<FabMenu icon={faPlus} label="Create" defaultOpen={true}>
|
|
112
|
+
<Button label="New doc" />
|
|
113
|
+
<Button label="Upload" />
|
|
114
|
+
</FabMenu>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
{
|
|
118
|
+
id === 'icon-button' && (
|
|
119
|
+
<div class="flex gap-2">
|
|
120
|
+
<IconButton label="Favorite" icon={faStar} />
|
|
121
|
+
<IconButton label="Star" icon={faStar} variant="outlined" />
|
|
122
|
+
</div>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
{
|
|
126
|
+
id === 'navigation-rail' && (
|
|
127
|
+
<NavigationRail>
|
|
128
|
+
<NavigationRailItem label="Home" icon={faHouse} />
|
|
129
|
+
<NavigationRailItem label="Updates" icon={faBell} />
|
|
130
|
+
<NavigationRailItem label="Settings" icon={faGear} />
|
|
131
|
+
</NavigationRail>
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
{
|
|
135
|
+
id === 'progress-indicator' && (
|
|
136
|
+
<div class="flex items-center gap-4">
|
|
137
|
+
<ProgressIndicator variant="linear-determinate" value={70} />
|
|
138
|
+
<ProgressIndicator variant="circular-indeterminate" />
|
|
139
|
+
</div>
|
|
140
|
+
)
|
|
141
|
+
}
|
|
142
|
+
{
|
|
143
|
+
id === 'side-sheet' && (
|
|
144
|
+
<SideSheet title="Details" extended={true} variant="standard">
|
|
145
|
+
<p class="text-body-small text-on-surface-variant">Side content</p>
|
|
146
|
+
</SideSheet>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
{id === 'slider' && <Slider value={70} onChange={() => {}} />}
|
|
150
|
+
{id === 'snackbar' && <Snackbar message="Message sent" />}
|
|
151
|
+
{id === 'switch' && <Switch selected />}
|
|
152
|
+
{
|
|
153
|
+
(id === 'tabs' || id === 'tab-group' || id === 'tab-panels') && (
|
|
154
|
+
<TabGroup defaultTab={0}>
|
|
155
|
+
<Tabs>
|
|
156
|
+
<Tab label="Overview" />
|
|
157
|
+
<Tab label="Details" />
|
|
158
|
+
<Tab label="Settings" />
|
|
159
|
+
</Tabs>
|
|
160
|
+
<TabPanels>
|
|
161
|
+
<TabPanel>Overview content</TabPanel>
|
|
162
|
+
<TabPanel>Details content</TabPanel>
|
|
163
|
+
<TabPanel>Settings content</TabPanel>
|
|
164
|
+
</TabPanels>
|
|
165
|
+
</TabGroup>
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
{
|
|
169
|
+
id === 'text-field' && (
|
|
170
|
+
<TextField label="Label" value="Type here" onChange={() => {}} />
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
{
|
|
174
|
+
id === 'tooltip' && (
|
|
175
|
+
<Tooltip text="Tooltip text">
|
|
176
|
+
<Button label="Hover me" />
|
|
177
|
+
</Tooltip>
|
|
178
|
+
)
|
|
179
|
+
}
|
|
180
|
+
{id === 'checkbox' && <Checkbox checked onChange={() => {}} />}
|
|
181
|
+
{
|
|
182
|
+
id === 'date-picker' && (
|
|
183
|
+
<div class="scale-75 origin-top">
|
|
184
|
+
<DatePicker defaultValue={new Date()} />
|
|
185
|
+
</div>
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
{
|
|
189
|
+
!(
|
|
190
|
+
id === 'button' ||
|
|
191
|
+
id === 'card' ||
|
|
192
|
+
id === 'carousel' ||
|
|
193
|
+
id === 'chip' ||
|
|
194
|
+
id === 'chips' ||
|
|
195
|
+
id === 'checkbox' ||
|
|
196
|
+
id === 'date-picker' ||
|
|
197
|
+
id === 'divider' ||
|
|
198
|
+
id === 'fab' ||
|
|
199
|
+
id === 'fab-menu' ||
|
|
200
|
+
id === 'icon-button' ||
|
|
201
|
+
id === 'navigation-rail' ||
|
|
202
|
+
id === 'progress-indicator' ||
|
|
203
|
+
id === 'side-sheet' ||
|
|
204
|
+
id === 'slider' ||
|
|
205
|
+
id === 'snackbar' ||
|
|
206
|
+
id === 'switch' ||
|
|
207
|
+
id === 'tabs' ||
|
|
208
|
+
id === 'tab-group' ||
|
|
209
|
+
id === 'tab-panels' ||
|
|
210
|
+
id === 'text-field' ||
|
|
211
|
+
id === 'tooltip'
|
|
212
|
+
) && (
|
|
213
|
+
<span class="inline-flex items-center rounded-full bg-surface-variant px-3 py-1 text-label-small text-on-surface-variant">
|
|
214
|
+
Preview pending
|
|
215
|
+
</span>
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
</div>
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
---
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import { CodePreview } from '@/components/CodePreview.js';
|
|
8
|
+
import { faPlus } from '@fortawesome/free-solid-svg-icons';
|
|
9
|
+
|
|
10
|
+
## Usage
|
|
11
|
+
|
|
12
|
+
The Button component can trigger an action or navigate to a link. Import it from the @udixio/ui-react package and provide at least a label via the label prop.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
import { Button } from "@udixio/ui-react"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
```tsx
|
|
19
|
+
<Button>Button</Button>
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Variants
|
|
23
|
+
|
|
24
|
+
```jsx
|
|
25
|
+
<div className="flex flex-wrap gap-3">
|
|
26
|
+
<Button variant="filled">Filled</Button>
|
|
27
|
+
<Button variant="elevated">Elevated</Button>
|
|
28
|
+
<Button variant="tonal">Tonal</Button>
|
|
29
|
+
<Button variant="outlined">Outlined</Button>
|
|
30
|
+
<Button variant="text">Text</Button>
|
|
31
|
+
</div>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Toggle buttons
|
|
35
|
+
|
|
36
|
+
Make a button togglable by providing `onToggle` and controlling its state with `activated`.
|
|
37
|
+
|
|
38
|
+
```jsx
|
|
39
|
+
function ToggleExample() {
|
|
40
|
+
const [activeStates, setActiveStates] = React.useState({
|
|
41
|
+
filled: false,
|
|
42
|
+
elevated: false,
|
|
43
|
+
tonal: false,
|
|
44
|
+
outlined: false,
|
|
45
|
+
text: false,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const handleToggle = (buttonType) => (newState) => {
|
|
49
|
+
setActiveStates((prev) => ({
|
|
50
|
+
...prev,
|
|
51
|
+
[buttonType]: newState,
|
|
52
|
+
}));
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className="flex flex-wrap gap-3">
|
|
57
|
+
<Button
|
|
58
|
+
label={activeStates.filled ? 'Active' : 'Inactive'}
|
|
59
|
+
variant="filled"
|
|
60
|
+
onToggle={handleToggle('filled')}
|
|
61
|
+
activated={activeStates.filled}
|
|
62
|
+
/>
|
|
63
|
+
<Button
|
|
64
|
+
label="Elevated"
|
|
65
|
+
variant="elevated"
|
|
66
|
+
onToggle={handleToggle('elevated')}
|
|
67
|
+
activated={activeStates.elevated}
|
|
68
|
+
/>
|
|
69
|
+
<Button
|
|
70
|
+
label="Filled Tonal"
|
|
71
|
+
variant="tonal"
|
|
72
|
+
onToggle={handleToggle('tonal')}
|
|
73
|
+
activated={activeStates.tonal}
|
|
74
|
+
/>
|
|
75
|
+
<Button
|
|
76
|
+
label="Outlined"
|
|
77
|
+
variant="outlined"
|
|
78
|
+
onToggle={handleToggle('outlined')}
|
|
79
|
+
activated={activeStates.outlined}
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Note: When used as a toggle button, accessibility is handled via `aria-pressed` automatically.
|
|
87
|
+
|
|
88
|
+
## Disabled state
|
|
89
|
+
|
|
90
|
+
Use the `disabled` prop to make the button inactive.
|
|
91
|
+
|
|
92
|
+
```jsx
|
|
93
|
+
<div className="flex flex-wrap gap-3">
|
|
94
|
+
<Button label="Disabled" disabled />
|
|
95
|
+
<Button label="Disabled" variant="outlined" disabled />
|
|
96
|
+
</div>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Sizes
|
|
100
|
+
|
|
101
|
+
```jsx
|
|
102
|
+
<div className="flex flex-wrap items-end gap-3">
|
|
103
|
+
<Button label="XS" size="xSmall" />
|
|
104
|
+
<Button label="S" size="small" />
|
|
105
|
+
<Button label="M" size="medium" />
|
|
106
|
+
<Button label="L" size="large" />
|
|
107
|
+
<Button label="XL" size="xLarge" />
|
|
108
|
+
</div>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Shapes
|
|
112
|
+
|
|
113
|
+
Control the button's appearance via the `shape` prop.
|
|
114
|
+
|
|
115
|
+
```jsx
|
|
116
|
+
<div className="flex flex-wrap gap-3">
|
|
117
|
+
<Button label="Rounded" shape="rounded" />
|
|
118
|
+
<Button label="Squared" shape="squared" />
|
|
119
|
+
</div>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Icon
|
|
123
|
+
|
|
124
|
+
You can add an icon (FontAwesome) and choose its position.
|
|
125
|
+
|
|
126
|
+
<CodePreview
|
|
127
|
+
client:load
|
|
128
|
+
code={`
|
|
129
|
+
<div className="flex gap-3">
|
|
130
|
+
<Button label="Add" icon={faPlus} />
|
|
131
|
+
<Button label="Next" iconPosition="right" icon={faPlus} />
|
|
132
|
+
</div>
|
|
133
|
+
`}
|
|
134
|
+
scope={{ faPlus }}
|
|
135
|
+
/>
|
|
136
|
+
|
|
137
|
+
## Loading state
|
|
138
|
+
|
|
139
|
+
```jsx
|
|
140
|
+
<Button label="Sending..." loading />
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Link or action
|
|
144
|
+
|
|
145
|
+
If the `href` prop is provided, the component renders an `<a>` link; otherwise it renders a `<button>`.
|
|
146
|
+
|
|
147
|
+
```jsx
|
|
148
|
+
<div className="flex gap-3">
|
|
149
|
+
<Button label="Click me" onClick={() => console.log('clicked')} />
|
|
150
|
+
<Button label="Go to Udixio" href="https://udixio.dev" />
|
|
151
|
+
</div>
|
|
152
|
+
```
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
---
|
|
3
|
+
|
|
4
|
+
## Usage
|
|
5
|
+
|
|
6
|
+
Import the Card component from @udixio/ui-react to group related content and actions.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
import { Card } from "@udixio/ui-react"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```tsx
|
|
13
|
+
<Card>
|
|
14
|
+
<div className="p-4 space-y-2">
|
|
15
|
+
<h3 className="text-lg font-semibold">Card title</h3>
|
|
16
|
+
<p>Card body content goes here.</p>
|
|
17
|
+
</div>
|
|
18
|
+
</Card>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Variants
|
|
22
|
+
|
|
23
|
+
```jsx
|
|
24
|
+
<div className="flex flex-wrap gap-4 w-full">
|
|
25
|
+
<Card className={"flex-1 h-48 min-w-48 flex items-center justify-center"}>
|
|
26
|
+
<div className="text-display-small text-center">Outlined (default)</div>
|
|
27
|
+
</Card>
|
|
28
|
+
<Card className={"flex-1 h-48 min-w-48 flex items-center justify-center"} variant="elevated">
|
|
29
|
+
<div className="text-display-small">Elevated</div>
|
|
30
|
+
</Card>
|
|
31
|
+
<Card className={"flex-1 h-48 min-w-48 flex items-center justify-center"} variant="filled">
|
|
32
|
+
<div className="text-display-small">Filled</div>
|
|
33
|
+
</Card>
|
|
34
|
+
</div>
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Interactive state
|
|
38
|
+
|
|
39
|
+
Enable hover and press feedback by setting `interactive` to true. Use it for clickable cards (e.g., navigation tiles).
|
|
40
|
+
|
|
41
|
+
```jsx
|
|
42
|
+
<>
|
|
43
|
+
<Card className={"w-full h-48 flex items-center justify-center"} interactive>
|
|
44
|
+
<div className={"text-display-small"} >Clickable card</div>
|
|
45
|
+
</Card>
|
|
46
|
+
<Card className={"w-full h-48 flex items-center justify-center"} interactive>
|
|
47
|
+
<div className={"text-display-small"} >Clickable card</div>
|
|
48
|
+
</Card>
|
|
49
|
+
</>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Composition patterns
|
|
53
|
+
|
|
54
|
+
Cards are layout containers. Combine simple elements to create common patterns.
|
|
55
|
+
|
|
56
|
+
### Header + body
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<Card>
|
|
60
|
+
<div className="p-4 space-y-1">
|
|
61
|
+
<h3 className="text-base font-semibold">Project Aurora</h3>
|
|
62
|
+
<p className="text-sm text-on-surface-variant">Last updated 2 days ago</p>
|
|
63
|
+
</div>
|
|
64
|
+
</Card>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Media + text
|
|
68
|
+
|
|
69
|
+
```jsx
|
|
70
|
+
<Card>
|
|
71
|
+
<img className="w-full h-40 object-cover" src="https://picsum.photos/640/240" alt="Cover" />
|
|
72
|
+
<div className="p-4">
|
|
73
|
+
<p>Beautiful landscapes collection</p>
|
|
74
|
+
</div>
|
|
75
|
+
</Card>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Actions
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
<Card>
|
|
82
|
+
<div className="p-4 not-prose px-6 space-y-6">
|
|
83
|
+
<p class={"not-prose text-headline-small"}>Delete Confirmation</p>
|
|
84
|
+
<p>Are you sure you want to delete this item?</p>
|
|
85
|
+
<div className="flex gap-6">
|
|
86
|
+
<Button disableTextMargins size={"small"} label="Cancel" variant="text" />
|
|
87
|
+
<Button size={"small"} label="Delete" variant="filled" />
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
</Card>
|
|
91
|
+
```
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Use Carousel with CarouselItem children to create a horizontally scrollable showcase.
|
|
2
|
+
|
|
3
|
+
```bash
|
|
4
|
+
import { Carousel, CarouselItem } from "@udixio/ui-react"
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Carousel variant="hero" gap={8}>
|
|
9
|
+
<CarouselItem>
|
|
10
|
+
<div className="p-6 bg-surface rounded-xl">Slide 1</div>
|
|
11
|
+
</CarouselItem>
|
|
12
|
+
<CarouselItem>
|
|
13
|
+
<div className="p-6 bg-surface rounded-xl">Slide 2</div>
|
|
14
|
+
</CarouselItem>
|
|
15
|
+
<CarouselItem>
|
|
16
|
+
<div className="p-6 bg-surface rounded-xl">Slide 3</div>
|
|
17
|
+
</CarouselItem>
|
|
18
|
+
</Carousel>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Behavior and callbacks
|
|
22
|
+
|
|
23
|
+
- `gap`: spacing between items.
|
|
24
|
+
- `marginPourcent`: outer margins as a percentage of the viewport width.
|
|
25
|
+
- `scrollSensitivity`: adjust scroll/drag responsiveness.
|
|
26
|
+
- `onChange`: called with the active index.
|
|
27
|
+
|
|
28
|
+
```jsx
|
|
29
|
+
<Carousel
|
|
30
|
+
variant="hero"
|
|
31
|
+
gap={16}
|
|
32
|
+
marginPourcent={12}
|
|
33
|
+
scrollSensitivity={0.8}
|
|
34
|
+
onChange={(index) => console.log('Active slide:', index)}
|
|
35
|
+
>
|
|
36
|
+
{Array.from({length: 15}, (_, i) => i + 1).map((i) => {
|
|
37
|
+
const fmt = i % 3;
|
|
38
|
+
const w = fmt === 0 ? 640 : fmt === 1 ? 400 : 240;
|
|
39
|
+
const h = fmt === 0 ? 240 : fmt === 1 ? 400 : 640;
|
|
40
|
+
return (
|
|
41
|
+
<CarouselItem key={i}>
|
|
42
|
+
<div className="bg-surface rounded-xl h-full flex flex-col">
|
|
43
|
+
<div className="flex-1 min-h-0">
|
|
44
|
+
<img className="size-full object-cover rounded-2xl" src={`https://picsum.photos/seed/udx-${i}-fmt-${fmt}/${w}/${h}`} alt="Cover" />
|
|
45
|
+
</div>
|
|
46
|
+
<p class={'text-title-large m-8 text-nowrap'}>Slide {i}</p>
|
|
47
|
+
</div>
|
|
48
|
+
</CarouselItem>
|
|
49
|
+
);
|
|
50
|
+
})}
|
|
51
|
+
</Carousel>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### With navigation buttons
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
() => {
|
|
59
|
+
const total = 15;
|
|
60
|
+
|
|
61
|
+
const [index, setIndex] = React.useState(0);
|
|
62
|
+
const [step, setStep] = React.useState(1);
|
|
63
|
+
const [visible, setVisible] = React.useState({ approx: 0, full: 0 });
|
|
64
|
+
|
|
65
|
+
const prev = () => setIndex((i) => Math.max(0, i - step));
|
|
66
|
+
const next = () => setIndex((i) => Math.min(total - 1, i + step));
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div className="w-full">
|
|
70
|
+
<Carousel
|
|
71
|
+
variant="hero"
|
|
72
|
+
scrollSensitivity={0.8}
|
|
73
|
+
index={index}
|
|
74
|
+
onChange={setIndex}
|
|
75
|
+
onMetricsChange={(m) => {
|
|
76
|
+
setStep(m.stepHalf); // step equals half of visible items
|
|
77
|
+
setVisible({ approx: m.visibleApprox, full: m.visibleFull });
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
{Array.from({ length: total }, (_, i) => i + 1).map((i) => {
|
|
81
|
+
const fmt = i % 3;
|
|
82
|
+
const w = fmt === 0 ? 640 : fmt === 1 ? 400 : 240;
|
|
83
|
+
const h = fmt === 0 ? 240 : fmt === 1 ? 400 : 640;
|
|
84
|
+
return (
|
|
85
|
+
<CarouselItem key={i}>
|
|
86
|
+
<div className="bg-surface rounded-xl h-full flex flex-col ">
|
|
87
|
+
<div className="flex-1 min-h-0">
|
|
88
|
+
<img className="size-full object-cover rounded-2xl" src={`https://picsum.photos/seed/udx-${i}-fmt-${fmt}/${w}/${h}`} alt="Cover" />
|
|
89
|
+
</div>
|
|
90
|
+
<p className={'text-title-large m-8 text-nowrap'}>Slide {i}</p>
|
|
91
|
+
</div>
|
|
92
|
+
</CarouselItem>
|
|
93
|
+
);
|
|
94
|
+
})}
|
|
95
|
+
</Carousel>
|
|
96
|
+
<div className="w-full mt-3 flex items-center justify-between gap-3">
|
|
97
|
+
<div className="text-on-surface-variant text-body-small">
|
|
98
|
+
Visible ≈ {visible.approx.toFixed(2)} (full {visible.full}), step: {step}
|
|
99
|
+
</div>
|
|
100
|
+
<div className="flex gap-3">
|
|
101
|
+
<Button variant="text" label="Previous" onClick={prev} />
|
|
102
|
+
<Button variant="filled" label="Next" onClick={next} />
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
```
|