@k8o/arte-odyssey 0.0.5 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -0
- package/dist/components/anchor/anchor.d.ts +3 -3
- package/dist/components/breadcrumb/breadcrumb.d.ts +4 -4
- package/dist/components/breadcrumb/breadcrumb.js +6 -1
- package/dist/components/form/autocomplete/autocomplete.d.ts +2 -1
- package/dist/components/form/autocomplete/autocomplete.js +31 -12
- package/dist/components/form/checkbox/checkbox.d.ts +1 -0
- package/dist/components/form/checkbox/checkbox.js +7 -1
- package/dist/components/form/number-field/number-field.d.ts +1 -0
- package/dist/components/form/number-field/number-field.js +7 -2
- package/dist/components/form/radio/radio.d.ts +1 -0
- package/dist/components/form/radio/radio.js +2 -0
- package/dist/components/form/range-field/range-field.d.ts +1 -0
- package/dist/components/form/range-field/range-field.js +2 -0
- package/dist/components/form/select/select.d.ts +1 -0
- package/dist/components/form/select/select.js +2 -0
- package/dist/components/icon-link/icon-link.d.ts +7 -9
- package/dist/components/link-button/link-button.d.ts +8 -8
- package/dist/components/providers/component-provider.js +1 -0
- package/package.json +13 -13
package/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# @k8o/arte-odyssey
|
|
2
|
+
|
|
3
|
+
A modern React UI component library built with TypeScript, Tailwind CSS, and accessibility in mind.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @k8o/arte-odyssey
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @k8o/arte-odyssey
|
|
11
|
+
# or
|
|
12
|
+
yarn add @k8o/arte-odyssey
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Peer Dependencies
|
|
16
|
+
|
|
17
|
+
Make sure you have the following peer dependencies installed:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install react react-dom typescript tailwindcss
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Required versions:
|
|
24
|
+
- React ≥19.0.0
|
|
25
|
+
- TypeScript ≥5.9.0
|
|
26
|
+
- Tailwind CSS ≥4.0.0
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
1. Install the package and import the CSS:
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
// In your main CSS file or component
|
|
34
|
+
import '@k8o/arte-odyssey/styles.css';
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
2. Use components in your React app:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { Button, Card } from '@k8o/arte-odyssey';
|
|
41
|
+
|
|
42
|
+
function App() {
|
|
43
|
+
return (
|
|
44
|
+
<Card>
|
|
45
|
+
<h1>Welcome to ArteOdyssey</h1>
|
|
46
|
+
<Button variant="primary" onClick={() => alert('Hello!')}>
|
|
47
|
+
Click me
|
|
48
|
+
</Button>
|
|
49
|
+
</Card>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Component Categories
|
|
55
|
+
|
|
56
|
+
### Layout & Navigation
|
|
57
|
+
- **Accordion** - Collapsible content panels
|
|
58
|
+
- **Breadcrumb** - Navigation path indicator
|
|
59
|
+
- **Card** - Flexible content container
|
|
60
|
+
- **Separator** - Visual content divider
|
|
61
|
+
- **Tabs** - Tab-based content organization
|
|
62
|
+
|
|
63
|
+
### Form Controls
|
|
64
|
+
- **Autocomplete** - Search with suggestions
|
|
65
|
+
- **Checkbox** - Multi-selection input
|
|
66
|
+
- **Form Control** - Form field wrapper with label and validation
|
|
67
|
+
- **Number Field** - Numeric input with controls
|
|
68
|
+
- **Radio** - Single selection from options
|
|
69
|
+
- **Range Field** - Slider input control
|
|
70
|
+
- **Select** - Dropdown selection
|
|
71
|
+
- **Text Field** - Single-line text input
|
|
72
|
+
- **Textarea** - Multi-line text input
|
|
73
|
+
|
|
74
|
+
### Buttons & Links
|
|
75
|
+
- **Button** - Primary action button
|
|
76
|
+
- **Icon Button** - Button with icon only
|
|
77
|
+
- **Link Button** - Button styled as link
|
|
78
|
+
- **Anchor** - External link component
|
|
79
|
+
- **Icon Link** - Link with icon
|
|
80
|
+
|
|
81
|
+
### Feedback & Status
|
|
82
|
+
- **Alert** - Important messages and notifications
|
|
83
|
+
- **Toast** - Temporary notification messages
|
|
84
|
+
- **Progress** - Progress indication
|
|
85
|
+
- **Baseline Status** - Web standard support indicator
|
|
86
|
+
|
|
87
|
+
### Overlays & Modals
|
|
88
|
+
- **Dialog** - Modal dialog boxes
|
|
89
|
+
- **Drawer** - Slide-out panel
|
|
90
|
+
- **Modal** - Overlay modal component
|
|
91
|
+
- **Popover** - Floating content container
|
|
92
|
+
- **Tooltip** - Contextual help text
|
|
93
|
+
- **Dropdown Menu** - Action menu component
|
|
94
|
+
|
|
95
|
+
### Data Display
|
|
96
|
+
- **Code** - Formatted code display
|
|
97
|
+
- **Heading** - Typography heading component
|
|
98
|
+
- **List Box** - Selectable list component
|
|
99
|
+
- **Text Tag** - Labeled text elements
|
|
100
|
+
|
|
101
|
+
### Utilities
|
|
102
|
+
- **Error Boundary** - Error handling wrapper
|
|
103
|
+
- **Providers** - Context providers for the library
|
|
104
|
+
- **Scroll Linked** - Scroll-triggered animations
|
|
105
|
+
- **Icons** - Icon component collection
|
|
106
|
+
|
|
107
|
+
## Usage Examples
|
|
108
|
+
|
|
109
|
+
### Basic Button
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { Button } from '@k8o/arte-odyssey';
|
|
113
|
+
|
|
114
|
+
<Button variant="primary" size="medium">
|
|
115
|
+
Primary Button
|
|
116
|
+
</Button>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Form with Validation
|
|
120
|
+
|
|
121
|
+
```tsx
|
|
122
|
+
import { FormControl, TextField, Button } from '@k8o/arte-odyssey';
|
|
123
|
+
|
|
124
|
+
<form>
|
|
125
|
+
<FormControl label="Email" required>
|
|
126
|
+
<TextField
|
|
127
|
+
type="email"
|
|
128
|
+
placeholder="Enter your email"
|
|
129
|
+
required
|
|
130
|
+
/>
|
|
131
|
+
</FormControl>
|
|
132
|
+
<Button type="submit">Submit</Button>
|
|
133
|
+
</form>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Modal Dialog
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
import { Dialog, Button } from '@k8o/arte-odyssey';
|
|
140
|
+
import { useState } from 'react';
|
|
141
|
+
|
|
142
|
+
function MyComponent() {
|
|
143
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
144
|
+
|
|
145
|
+
return (
|
|
146
|
+
<>
|
|
147
|
+
<Button onClick={() => setIsOpen(true)}>
|
|
148
|
+
Open Dialog
|
|
149
|
+
</Button>
|
|
150
|
+
<Dialog
|
|
151
|
+
isOpen={isOpen}
|
|
152
|
+
onClose={() => setIsOpen(false)}
|
|
153
|
+
title="Confirm Action"
|
|
154
|
+
>
|
|
155
|
+
<p>Are you sure you want to continue?</p>
|
|
156
|
+
<Button onClick={() => setIsOpen(false)}>
|
|
157
|
+
Confirm
|
|
158
|
+
</Button>
|
|
159
|
+
</Dialog>
|
|
160
|
+
</>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Granular Imports
|
|
166
|
+
|
|
167
|
+
ArteOdyssey supports granular imports to optimize your bundle size:
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
// Import specific components
|
|
171
|
+
import { Button } from '@k8o/arte-odyssey/button';
|
|
172
|
+
import { Card } from '@k8o/arte-odyssey/card';
|
|
173
|
+
|
|
174
|
+
// Import specific hooks
|
|
175
|
+
import { useClickAway } from '@k8o/arte-odyssey/hooks/click-away';
|
|
176
|
+
import { useLocalStorage } from '@k8o/arte-odyssey/hooks/local-storage';
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Custom Hooks
|
|
180
|
+
|
|
181
|
+
The library includes several useful hooks:
|
|
182
|
+
|
|
183
|
+
- **useClickAway** - Detect clicks outside an element
|
|
184
|
+
- **useClipboard** - Clipboard operations
|
|
185
|
+
- **useHash** - URL hash management
|
|
186
|
+
- **useInterval** - Interval timer management
|
|
187
|
+
- **useLocalStorage** - Local storage with React state
|
|
188
|
+
- **useScrollDirection** - Scroll direction detection
|
|
189
|
+
- **useStep** - Step-based state management
|
|
190
|
+
- **useTimeout** - Timeout management
|
|
191
|
+
- **useWindowSize** - Window size tracking
|
|
192
|
+
|
|
193
|
+
## TypeScript Support
|
|
194
|
+
|
|
195
|
+
All components are fully typed with TypeScript. The library exports comprehensive type definitions for all props and APIs.
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
import type { ButtonProps } from '@k8o/arte-odyssey';
|
|
199
|
+
|
|
200
|
+
const CustomButton: React.FC<ButtonProps> = (props) => {
|
|
201
|
+
return <Button {...props} />;
|
|
202
|
+
};
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Accessibility
|
|
206
|
+
|
|
207
|
+
All components follow WCAG accessibility guidelines:
|
|
208
|
+
|
|
209
|
+
- Semantic HTML elements
|
|
210
|
+
- Proper ARIA attributes
|
|
211
|
+
- Keyboard navigation support
|
|
212
|
+
- Screen reader compatibility
|
|
213
|
+
- Focus management
|
|
214
|
+
- Color contrast compliance
|
|
215
|
+
|
|
216
|
+
## Styling & Customization
|
|
217
|
+
|
|
218
|
+
Components are built with Tailwind CSS and support customization through:
|
|
219
|
+
|
|
220
|
+
- CSS custom properties
|
|
221
|
+
- Tailwind utility classes
|
|
222
|
+
- Theme configuration
|
|
223
|
+
- Style overrides
|
|
224
|
+
|
|
225
|
+
## Development
|
|
226
|
+
|
|
227
|
+
For local development and contributing:
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Install dependencies
|
|
231
|
+
pnpm install
|
|
232
|
+
|
|
233
|
+
# Start Storybook for component development
|
|
234
|
+
pnpm storybook
|
|
235
|
+
|
|
236
|
+
# Run tests
|
|
237
|
+
pnpm test
|
|
238
|
+
|
|
239
|
+
# Build the library
|
|
240
|
+
pnpm build
|
|
241
|
+
|
|
242
|
+
# Type checking
|
|
243
|
+
pnpm typecheck
|
|
244
|
+
|
|
245
|
+
# Linting and formatting
|
|
246
|
+
pnpm check:write
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Browser Support
|
|
250
|
+
|
|
251
|
+
- Chrome (latest)
|
|
252
|
+
- Firefox (latest)
|
|
253
|
+
- Safari (latest)
|
|
254
|
+
- Edge (latest)
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT License - see [LICENSE](../../LICENSE) for details.
|
|
259
|
+
|
|
260
|
+
## Contributing
|
|
261
|
+
|
|
262
|
+
Contributions are welcome! Please see the [main repository](../../README.md) for contribution guidelines.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
Built with ❤️ using React, TypeScript, and Tailwind CSS.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
|
-
export declare const Anchor: ({ href, children, openInNewTab, renderAnchor, }: {
|
|
3
|
-
href:
|
|
2
|
+
export declare const Anchor: <T extends string>({ href, children, openInNewTab, renderAnchor, }: {
|
|
3
|
+
href: T;
|
|
4
4
|
children: ReactNode;
|
|
5
5
|
openInNewTab?: boolean;
|
|
6
6
|
renderAnchor?: (props: {
|
|
7
7
|
type: "internal" | "external";
|
|
8
|
-
href:
|
|
8
|
+
href: NoInfer<T>;
|
|
9
9
|
className: string;
|
|
10
10
|
target?: string;
|
|
11
11
|
rel?: string;
|
|
@@ -7,12 +7,12 @@ export declare const Breadcrumb: {
|
|
|
7
7
|
children?: React.ReactNode | undefined;
|
|
8
8
|
}>;
|
|
9
9
|
readonly Separator: FC;
|
|
10
|
-
readonly Link:
|
|
11
|
-
href:
|
|
10
|
+
readonly Link: <T extends string>({ href, current, children, component, }: PropsWithChildren<{
|
|
11
|
+
href: T;
|
|
12
12
|
current?: boolean;
|
|
13
13
|
component?: FC<{
|
|
14
|
-
href:
|
|
14
|
+
href: T;
|
|
15
15
|
className: string;
|
|
16
16
|
}>;
|
|
17
|
-
}
|
|
17
|
+
}>) => import("react/jsx-runtime").JSX.Element;
|
|
18
18
|
};
|
|
@@ -21,7 +21,12 @@ const Item = ({ children }) => {
|
|
|
21
21
|
const Separator = () => {
|
|
22
22
|
return /* @__PURE__ */ jsx("li", { className: "text-fg-mute", children: /* @__PURE__ */ jsx(ChevronIcon, { direction: "right", size: "sm" }) });
|
|
23
23
|
};
|
|
24
|
-
const _Link = ({
|
|
24
|
+
const _Link = ({
|
|
25
|
+
href,
|
|
26
|
+
current = false,
|
|
27
|
+
children,
|
|
28
|
+
component
|
|
29
|
+
}) => {
|
|
25
30
|
const Link = component ?? "a";
|
|
26
31
|
return current ? /* @__PURE__ */ jsx("span", { className: "text-fg-base", children }) : /* @__PURE__ */ jsx(Link, { className: "text-fg-mute underline hover:text-fg-base", href, children });
|
|
27
32
|
};
|
|
@@ -11,12 +11,27 @@ const Autocomplete = ({
|
|
|
11
11
|
isRequired,
|
|
12
12
|
options,
|
|
13
13
|
value,
|
|
14
|
+
defaultValue,
|
|
14
15
|
onChange
|
|
15
16
|
}) => {
|
|
17
|
+
const [internalValue, setInternalValue] = useState(
|
|
18
|
+
defaultValue || []
|
|
19
|
+
);
|
|
20
|
+
const isControlled = value !== void 0;
|
|
21
|
+
const currentValue = isControlled ? value : internalValue;
|
|
16
22
|
const ref = useRef(null);
|
|
17
23
|
const [open, setOpen] = useState(false);
|
|
18
24
|
const [text, setText] = useState("");
|
|
19
25
|
const [selectIndex, setSelectIndex] = useState();
|
|
26
|
+
const handleChange = useCallback(
|
|
27
|
+
(newValue) => {
|
|
28
|
+
if (!isControlled) {
|
|
29
|
+
setInternalValue(newValue);
|
|
30
|
+
}
|
|
31
|
+
onChange(newValue);
|
|
32
|
+
},
|
|
33
|
+
[isControlled, onChange]
|
|
34
|
+
);
|
|
20
35
|
const filteredOptions = options.filter(
|
|
21
36
|
(option) => option.label.includes(text)
|
|
22
37
|
);
|
|
@@ -48,7 +63,7 @@ const Autocomplete = ({
|
|
|
48
63
|
children: [
|
|
49
64
|
/* @__PURE__ */ jsxs("div", { className: "flex min-h-12 items-center justify-between gap-2 px-3 py-2", children: [
|
|
50
65
|
/* @__PURE__ */ jsxs("div", { className: "flex w-full flex-wrap gap-1", children: [
|
|
51
|
-
|
|
66
|
+
currentValue.map((text2) => {
|
|
52
67
|
const label = options.find(
|
|
53
68
|
(option) => option.value === text2
|
|
54
69
|
)?.label;
|
|
@@ -66,7 +81,7 @@ const Autocomplete = ({
|
|
|
66
81
|
onClick: (e) => {
|
|
67
82
|
e.stopPropagation();
|
|
68
83
|
reset();
|
|
69
|
-
|
|
84
|
+
handleChange(currentValue.filter((v) => v !== text2));
|
|
70
85
|
},
|
|
71
86
|
size: "sm",
|
|
72
87
|
children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" })
|
|
@@ -115,7 +130,7 @@ const Autocomplete = ({
|
|
|
115
130
|
onKeyDown: (e) => {
|
|
116
131
|
if (e.key === "Backspace" && text.length === 0) {
|
|
117
132
|
reset();
|
|
118
|
-
|
|
133
|
+
handleChange(currentValue.slice(0, -1));
|
|
119
134
|
return;
|
|
120
135
|
}
|
|
121
136
|
if (e.key === "ArrowDown") {
|
|
@@ -143,12 +158,14 @@ const Autocomplete = ({
|
|
|
143
158
|
if (!selected) {
|
|
144
159
|
return;
|
|
145
160
|
}
|
|
146
|
-
if (
|
|
147
|
-
|
|
161
|
+
if (currentValue.includes(selected.value)) {
|
|
162
|
+
handleChange(
|
|
163
|
+
currentValue.filter((v) => v !== selected.value)
|
|
164
|
+
);
|
|
148
165
|
reset();
|
|
149
166
|
return;
|
|
150
167
|
}
|
|
151
|
-
|
|
168
|
+
handleChange([...currentValue, selected.value]);
|
|
152
169
|
reset();
|
|
153
170
|
return;
|
|
154
171
|
}
|
|
@@ -160,13 +177,13 @@ const Autocomplete = ({
|
|
|
160
177
|
}
|
|
161
178
|
)
|
|
162
179
|
] }),
|
|
163
|
-
|
|
180
|
+
currentValue.length > 0 && /* @__PURE__ */ jsx(
|
|
164
181
|
IconButton,
|
|
165
182
|
{
|
|
166
183
|
label: "\u3059\u3079\u3066\u9589\u3058\u308B",
|
|
167
184
|
onClick: (e) => {
|
|
168
185
|
e.stopPropagation();
|
|
169
|
-
|
|
186
|
+
handleChange([]);
|
|
170
187
|
},
|
|
171
188
|
size: "sm",
|
|
172
189
|
children: /* @__PURE__ */ jsx(CloseIcon, { size: "sm" })
|
|
@@ -181,13 +198,13 @@ const Autocomplete = ({
|
|
|
181
198
|
children: /* @__PURE__ */ jsxs("ul", { className: "max-h-96 py-2", id: `${id}_listbox`, children: [
|
|
182
199
|
filteredOptions.length === 0 && /* @__PURE__ */ jsx("li", { className: "px-3 py-2 text-fg-mute", children: "\u8A72\u5F53\u306A\u3057" }),
|
|
183
200
|
filteredOptions.map((option, idx) => {
|
|
184
|
-
const selected =
|
|
201
|
+
const selected = currentValue.includes(option.value);
|
|
185
202
|
return /* @__PURE__ */ jsx(
|
|
186
203
|
"li",
|
|
187
204
|
{
|
|
188
205
|
className: cn(
|
|
189
206
|
"cursor-pointer px-3 py-2",
|
|
190
|
-
selected && "bg-primary-bg
|
|
207
|
+
selected && "bg-primary-bg",
|
|
191
208
|
selectIndex === idx && !selected && "bg-bg-emphasize",
|
|
192
209
|
selectIndex === idx && selected && "hover:bg-primary-bg/90"
|
|
193
210
|
),
|
|
@@ -196,10 +213,12 @@ const Autocomplete = ({
|
|
|
196
213
|
e.stopPropagation();
|
|
197
214
|
reset();
|
|
198
215
|
if (selected) {
|
|
199
|
-
|
|
216
|
+
handleChange(
|
|
217
|
+
currentValue.filter((v) => v !== option.value)
|
|
218
|
+
);
|
|
200
219
|
return;
|
|
201
220
|
}
|
|
202
|
-
|
|
221
|
+
handleChange([...currentValue, option.value]);
|
|
203
222
|
},
|
|
204
223
|
onKeyDown: (e) => {
|
|
205
224
|
e.preventDefault();
|
|
@@ -2,7 +2,12 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { cn } from "./../../../helpers/cn";
|
|
4
4
|
import { CheckIcon } from "../../icons";
|
|
5
|
-
const Checkbox = ({
|
|
5
|
+
const Checkbox = ({
|
|
6
|
+
label,
|
|
7
|
+
value,
|
|
8
|
+
defaultChecked,
|
|
9
|
+
onChange
|
|
10
|
+
}) => {
|
|
6
11
|
const [isFocus, setIsFocus] = useState(false);
|
|
7
12
|
return /* @__PURE__ */ jsxs("label", { className: "inline-flex cursor-pointer items-center gap-2", children: [
|
|
8
13
|
/* @__PURE__ */ jsx(
|
|
@@ -10,6 +15,7 @@ const Checkbox = ({ label, value, onChange }) => {
|
|
|
10
15
|
{
|
|
11
16
|
checked: value,
|
|
12
17
|
className: "sr-only",
|
|
18
|
+
defaultChecked,
|
|
13
19
|
onBlur: () => {
|
|
14
20
|
setIsFocus(false);
|
|
15
21
|
},
|
|
@@ -10,6 +10,7 @@ const NumberField = ({
|
|
|
10
10
|
isDisabled,
|
|
11
11
|
isRequired,
|
|
12
12
|
value,
|
|
13
|
+
defaultValue,
|
|
13
14
|
onChange,
|
|
14
15
|
step = 1,
|
|
15
16
|
precision = 0,
|
|
@@ -17,8 +18,12 @@ const NumberField = ({
|
|
|
17
18
|
min = -9007199254740991,
|
|
18
19
|
placeholder
|
|
19
20
|
}) => {
|
|
20
|
-
const [displayValue, setDisplayValue] = useState(
|
|
21
|
-
|
|
21
|
+
const [displayValue, setDisplayValue] = useState(
|
|
22
|
+
defaultValue !== void 0 ? defaultValue.toFixed(precision) : value.toFixed(precision)
|
|
23
|
+
);
|
|
24
|
+
const [prevValue, setPrevValue] = useState(
|
|
25
|
+
defaultValue !== void 0 ? defaultValue : value
|
|
26
|
+
);
|
|
22
27
|
if (value !== prevValue) {
|
|
23
28
|
setDisplayValue(value.toFixed(precision));
|
|
24
29
|
setPrevValue(value);
|
|
@@ -4,6 +4,7 @@ const Radio = ({
|
|
|
4
4
|
labelId,
|
|
5
5
|
isDisabled,
|
|
6
6
|
value,
|
|
7
|
+
defaultValue,
|
|
7
8
|
onChange,
|
|
8
9
|
options
|
|
9
10
|
}) => {
|
|
@@ -32,6 +33,7 @@ const Radio = ({
|
|
|
32
33
|
"cursor-pointer",
|
|
33
34
|
"disabled:cursor-not-allowed disabled:bg-bg-mute"
|
|
34
35
|
),
|
|
36
|
+
defaultChecked: defaultValue === option.value,
|
|
35
37
|
disabled: isDisabled,
|
|
36
38
|
onChange,
|
|
37
39
|
type: "radio",
|
|
@@ -7,6 +7,7 @@ const RangeField = ({
|
|
|
7
7
|
isDisabled,
|
|
8
8
|
isRequired,
|
|
9
9
|
value,
|
|
10
|
+
defaultValue,
|
|
10
11
|
onChange,
|
|
11
12
|
step = 1,
|
|
12
13
|
max = 100,
|
|
@@ -30,6 +31,7 @@ const RangeField = ({
|
|
|
30
31
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
31
32
|
isInvalid && "ring-2 ring-border-error"
|
|
32
33
|
),
|
|
34
|
+
defaultValue,
|
|
33
35
|
disabled: isDisabled,
|
|
34
36
|
id,
|
|
35
37
|
max,
|
|
@@ -9,6 +9,7 @@ const Select = ({
|
|
|
9
9
|
isRequired,
|
|
10
10
|
options,
|
|
11
11
|
value,
|
|
12
|
+
defaultValue,
|
|
12
13
|
onChange
|
|
13
14
|
}) => {
|
|
14
15
|
return /* @__PURE__ */ jsxs("div", { className: "relative h-fit w-full", children: [
|
|
@@ -24,6 +25,7 @@ const Select = ({
|
|
|
24
25
|
"disabled:cursor-not-allowed disabled:border-border-mute disabled:bg-bg-mute disabled:hover:bg-bg-mute",
|
|
25
26
|
"focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info"
|
|
26
27
|
),
|
|
28
|
+
defaultValue,
|
|
27
29
|
disabled: isDisabled,
|
|
28
30
|
id,
|
|
29
31
|
onChange,
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
size?:
|
|
4
|
-
bg?:
|
|
1
|
+
import type { PropsWithChildren, ReactNode } from 'react';
|
|
2
|
+
export declare const IconLink: <T extends string>({ size, bg, label, href, children, openInNewTab, renderAnchor, }: PropsWithChildren<{
|
|
3
|
+
size?: "sm" | "md" | "lg";
|
|
4
|
+
bg?: "transparent" | "base";
|
|
5
5
|
label?: string;
|
|
6
|
-
href:
|
|
6
|
+
href: T;
|
|
7
7
|
openInNewTab?: boolean;
|
|
8
8
|
renderAnchor?: (props: {
|
|
9
|
-
href:
|
|
9
|
+
href: NoInfer<T>;
|
|
10
10
|
className: string;
|
|
11
11
|
target?: string;
|
|
12
12
|
rel?: string;
|
|
13
13
|
children: ReactNode;
|
|
14
14
|
}) => ReactNode;
|
|
15
|
-
}
|
|
16
|
-
export declare const IconLink: FC<IconLinkProps>;
|
|
17
|
-
export {};
|
|
15
|
+
}>) => ReactNode;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const LinkButton:
|
|
3
|
-
variant?:
|
|
4
|
-
size?:
|
|
5
|
-
href:
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export declare const LinkButton: <T extends string>({ children, size, variant, href, startIcon, endIcon, active, openInNewTab, renderAnchor, }: {
|
|
3
|
+
variant?: "contained" | "outlined" | "skeleton";
|
|
4
|
+
size?: "sm" | "md" | "lg";
|
|
5
|
+
href: T;
|
|
6
6
|
startIcon?: ReactNode;
|
|
7
7
|
endIcon?: ReactNode;
|
|
8
8
|
active?: boolean;
|
|
9
9
|
openInNewTab?: boolean;
|
|
10
10
|
children: string;
|
|
11
11
|
renderAnchor?: (props: {
|
|
12
|
-
|
|
13
|
-
href:
|
|
12
|
+
"aria-label"?: string;
|
|
13
|
+
href: NoInfer<T>;
|
|
14
14
|
className: string;
|
|
15
15
|
target?: string;
|
|
16
16
|
rel?: string;
|
|
17
17
|
children: ReactNode;
|
|
18
18
|
}) => ReactNode;
|
|
19
|
-
}
|
|
19
|
+
}) => ReactNode;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@k8o/arte-odyssey",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "k8o's react ui library",
|
|
5
5
|
"author": "k8o <kosakanoki@gmail.com>",
|
|
6
6
|
"keywords": [
|
|
@@ -52,36 +52,36 @@
|
|
|
52
52
|
"*.css"
|
|
53
53
|
],
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@floating-ui/react": "0.27.
|
|
55
|
+
"@floating-ui/react": "0.27.16",
|
|
56
56
|
"baseline-status": "1.0.11",
|
|
57
57
|
"clsx": "2.1.1",
|
|
58
58
|
"esbuild": "0.25.9",
|
|
59
|
-
"lucide-react": "0.
|
|
59
|
+
"lucide-react": "0.542.0",
|
|
60
60
|
"motion": "12.23.12",
|
|
61
61
|
"react-error-boundary": "6.0.0",
|
|
62
62
|
"tailwind-merge": "3.3.1"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@chromatic-com/storybook": "4.1.
|
|
66
|
-
"@storybook/addon-a11y": "9.1.
|
|
67
|
-
"@storybook/addon-docs": "9.1.
|
|
68
|
-
"@storybook/addon-vitest": "9.1.
|
|
69
|
-
"@storybook/react-vite": "9.1.
|
|
65
|
+
"@chromatic-com/storybook": "4.1.1",
|
|
66
|
+
"@storybook/addon-a11y": "9.1.4",
|
|
67
|
+
"@storybook/addon-docs": "9.1.4",
|
|
68
|
+
"@storybook/addon-vitest": "9.1.4",
|
|
69
|
+
"@storybook/react-vite": "9.1.4",
|
|
70
70
|
"@tailwindcss/postcss": "4.1.12",
|
|
71
71
|
"@testing-library/dom": "10.4.1",
|
|
72
72
|
"@testing-library/react": "16.3.0",
|
|
73
|
-
"@types/react": "19.1.
|
|
74
|
-
"@types/react-dom": "19.1.
|
|
75
|
-
"@vitejs/plugin-react-swc": "4.0.
|
|
73
|
+
"@types/react": "19.1.12",
|
|
74
|
+
"@types/react-dom": "19.1.9",
|
|
75
|
+
"@vitejs/plugin-react-swc": "4.0.1",
|
|
76
76
|
"@vitest/browser": "3.2.4",
|
|
77
77
|
"@vitest/ui": "3.2.4",
|
|
78
78
|
"postcss": "8.5.6",
|
|
79
79
|
"react": "19.1.1",
|
|
80
80
|
"react-dom": "19.1.1",
|
|
81
|
-
"storybook": "9.1.
|
|
81
|
+
"storybook": "9.1.4",
|
|
82
82
|
"storybook-addon-mock-date": "1.0.1",
|
|
83
83
|
"tailwindcss": "4.1.12",
|
|
84
|
-
"vite": "7.1.
|
|
84
|
+
"vite": "7.1.4",
|
|
85
85
|
"vitest": "3.2.4"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|