@jorgequevedoc/react-gridforms 1.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 +278 -0
- package/dist/components/FormField.d.ts +11 -0
- package/dist/components/FormField.d.ts.map +1 -0
- package/dist/components/FormField.js +111 -0
- package/dist/components/FormField.js.map +1 -0
- package/dist/components/FormRow.d.ts +9 -0
- package/dist/components/FormRow.d.ts.map +1 -0
- package/dist/components/FormRow.js +38 -0
- package/dist/components/FormRow.js.map +1 -0
- package/dist/components/FormSection.d.ts +9 -0
- package/dist/components/FormSection.d.ts.map +1 -0
- package/dist/components/FormSection.js +36 -0
- package/dist/components/FormSection.js.map +1 -0
- package/dist/components/GridForm.d.ts +9 -0
- package/dist/components/GridForm.d.ts.map +1 -0
- package/dist/components/GridForm.js +88 -0
- package/dist/components/GridForm.js.map +1 -0
- package/dist/components/ThemeToggle.d.ts +7 -0
- package/dist/components/ThemeToggle.d.ts.map +1 -0
- package/dist/components/ThemeToggle.js +30 -0
- package/dist/components/ThemeToggle.js.map +1 -0
- package/dist/components/index.d.ts +9 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +9 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/inputs/RadioGroup.d.ts +14 -0
- package/dist/components/inputs/RadioGroup.d.ts.map +1 -0
- package/dist/components/inputs/RadioGroup.js +39 -0
- package/dist/components/inputs/RadioGroup.js.map +1 -0
- package/dist/components/inputs/SelectInput.d.ts +18 -0
- package/dist/components/inputs/SelectInput.d.ts.map +1 -0
- package/dist/components/inputs/SelectInput.js +29 -0
- package/dist/components/inputs/SelectInput.js.map +1 -0
- package/dist/components/inputs/TextInput.d.ts +15 -0
- package/dist/components/inputs/TextInput.d.ts.map +1 -0
- package/dist/components/inputs/TextInput.js +28 -0
- package/dist/components/inputs/TextInput.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/index.ts +27 -0
- package/dist/lib.d.ts +4 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +6 -0
- package/dist/lib.js.map +1 -0
- package/dist/theme/ThemeContext.d.ts +16 -0
- package/dist/theme/ThemeContext.d.ts.map +1 -0
- package/dist/theme/ThemeContext.js +32 -0
- package/dist/theme/ThemeContext.js.map +1 -0
- package/dist/theme/index.d.ts +3 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +2 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/themes.d.ts +4 -0
- package/dist/theme/themes.d.ts.map +1 -0
- package/dist/theme/themes.js +87 -0
- package/dist/theme/themes.js.map +1 -0
- package/dist/theme/types.d.ts +46 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +2 -0
- package/dist/theme/types.js.map +1 -0
- package/package.json +78 -0
package/README.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# React GridForms
|
|
2
|
+
|
|
3
|
+
A modern React TypeScript implementation of GridForms - a compact and beautiful grid-based form system with built-in theming support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🎨 **Modern Design**: Clean, responsive grid-based form layout
|
|
8
|
+
- 🌙 **Theme Support**: Built-in light and dark themes with easy customization
|
|
9
|
+
- 📱 **Responsive**: Works seamlessly across all device sizes
|
|
10
|
+
- 🎯 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
11
|
+
- ⚡ **Performance**: Optimized for performance with minimal bundle size
|
|
12
|
+
- 🎨 **Styled Components**: Built with styled-components for flexible styling
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Option 1: Publish to npm (Recommended)
|
|
17
|
+
|
|
18
|
+
1. **Build the library:**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
yarn build:lib
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. **Publish to npm:**
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm publish
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
3. **Install in your project:**
|
|
31
|
+
```bash
|
|
32
|
+
yarn add react-gridforms
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Option 2: Use as a Git dependency
|
|
36
|
+
|
|
37
|
+
Add this repository as a dependency in your `package.json`:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"react-gridforms": "github:yourusername/react-gridforms#main"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Option 3: Use with yarn link (Development)
|
|
48
|
+
|
|
49
|
+
1. **Link the library:**
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cd /path/to/react-gridforms
|
|
53
|
+
yarn link
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
2. **Link in your project:**
|
|
57
|
+
```bash
|
|
58
|
+
cd /path/to/your-project
|
|
59
|
+
yarn link react-gridforms
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Option 4: Use as a local dependency
|
|
63
|
+
|
|
64
|
+
1. **Build the library:**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
cd /path/to/react-gridforms
|
|
68
|
+
yarn build:lib
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. **Add to your project's package.json:**
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"react-gridforms": "file:/path/to/react-gridforms"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
3. **Install:**
|
|
82
|
+
```bash
|
|
83
|
+
yarn install
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Usage
|
|
87
|
+
|
|
88
|
+
### Basic Setup
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import React from 'react';
|
|
92
|
+
import {
|
|
93
|
+
GridForm,
|
|
94
|
+
FormSection,
|
|
95
|
+
FormRow,
|
|
96
|
+
FormField,
|
|
97
|
+
TextInput,
|
|
98
|
+
ThemeProvider,
|
|
99
|
+
lightTheme,
|
|
100
|
+
} from 'react-gridforms';
|
|
101
|
+
|
|
102
|
+
function App() {
|
|
103
|
+
return (
|
|
104
|
+
<ThemeProvider theme={lightTheme}>
|
|
105
|
+
<GridForm onSubmit={(data) => console.log(data)}>
|
|
106
|
+
<FormSection title="Personal Information">
|
|
107
|
+
<FormRow>
|
|
108
|
+
<FormField label="First Name">
|
|
109
|
+
<TextInput name="firstName" placeholder="Enter your first name" />
|
|
110
|
+
</FormField>
|
|
111
|
+
<FormField label="Last Name">
|
|
112
|
+
<TextInput name="lastName" placeholder="Enter your last name" />
|
|
113
|
+
</FormField>
|
|
114
|
+
</FormRow>
|
|
115
|
+
</FormSection>
|
|
116
|
+
</GridForm>
|
|
117
|
+
</ThemeProvider>
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Available Components
|
|
123
|
+
|
|
124
|
+
#### Core Components
|
|
125
|
+
|
|
126
|
+
- `GridForm` - Main form container
|
|
127
|
+
- `FormSection` - Group form fields into sections
|
|
128
|
+
- `FormRow` - Arrange fields in a row
|
|
129
|
+
- `FormField` - Individual form field wrapper
|
|
130
|
+
|
|
131
|
+
#### Input Components
|
|
132
|
+
|
|
133
|
+
- `TextInput` - Text input field
|
|
134
|
+
- `SelectInput` - Dropdown select field
|
|
135
|
+
- `RadioGroup` - Radio button group
|
|
136
|
+
|
|
137
|
+
#### Theme Components
|
|
138
|
+
|
|
139
|
+
- `ThemeProvider` - Theme context provider
|
|
140
|
+
- `ThemeToggle` - Toggle between light and dark themes
|
|
141
|
+
|
|
142
|
+
### Theming
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
import { ThemeProvider, lightTheme, darkTheme, useTheme } from 'react-gridforms';
|
|
146
|
+
|
|
147
|
+
// Use light theme
|
|
148
|
+
<ThemeProvider theme={lightTheme}>
|
|
149
|
+
{/* Your form */}
|
|
150
|
+
</ThemeProvider>
|
|
151
|
+
|
|
152
|
+
// Use dark theme
|
|
153
|
+
<ThemeProvider theme={darkTheme}>
|
|
154
|
+
{/* Your form */}
|
|
155
|
+
</ThemeProvider>
|
|
156
|
+
|
|
157
|
+
// Custom theme
|
|
158
|
+
const customTheme = {
|
|
159
|
+
...lightTheme,
|
|
160
|
+
colors: {
|
|
161
|
+
...lightTheme.colors,
|
|
162
|
+
primary: '#ff6b6b',
|
|
163
|
+
secondary: '#4ecdc4',
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
<ThemeProvider theme={customTheme}>
|
|
168
|
+
{/* Your form */}
|
|
169
|
+
</ThemeProvider>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Form Submission
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
<GridForm
|
|
176
|
+
onSubmit={(data) => {
|
|
177
|
+
console.log('Form data:', data);
|
|
178
|
+
// Handle form submission
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
{/* Form fields */}
|
|
182
|
+
</GridForm>
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## API Reference
|
|
186
|
+
|
|
187
|
+
### GridForm Props
|
|
188
|
+
|
|
189
|
+
- `onSubmit: (data: Record<string, any>) => void` - Form submission handler
|
|
190
|
+
- `children: ReactNode` - Form content
|
|
191
|
+
|
|
192
|
+
### FormSection Props
|
|
193
|
+
|
|
194
|
+
- `title: string` - Section title
|
|
195
|
+
- `children: ReactNode` - Section content
|
|
196
|
+
|
|
197
|
+
### FormRow Props
|
|
198
|
+
|
|
199
|
+
- `children: ReactNode` - Row content
|
|
200
|
+
|
|
201
|
+
### FormField Props
|
|
202
|
+
|
|
203
|
+
- `label: string` - Field label
|
|
204
|
+
- `children: ReactNode` - Input component
|
|
205
|
+
|
|
206
|
+
### TextInput Props
|
|
207
|
+
|
|
208
|
+
- `name: string` - Field name
|
|
209
|
+
- `placeholder?: string` - Placeholder text
|
|
210
|
+
- `type?: string` - Input type (default: "text")
|
|
211
|
+
- `required?: boolean` - Required field
|
|
212
|
+
- `disabled?: boolean` - Disabled state
|
|
213
|
+
|
|
214
|
+
### SelectInput Props
|
|
215
|
+
|
|
216
|
+
- `name: string` - Field name
|
|
217
|
+
- `options: SelectOption[]` - Select options
|
|
218
|
+
- `placeholder?: string` - Placeholder text
|
|
219
|
+
- `required?: boolean` - Required field
|
|
220
|
+
- `disabled?: boolean` - Disabled state
|
|
221
|
+
|
|
222
|
+
### RadioGroup Props
|
|
223
|
+
|
|
224
|
+
- `name: string` - Field name
|
|
225
|
+
- `options: RadioOption[]` - Radio options
|
|
226
|
+
- `required?: boolean` - Required field
|
|
227
|
+
- `disabled?: boolean` - Disabled state
|
|
228
|
+
|
|
229
|
+
## Development
|
|
230
|
+
|
|
231
|
+
### Prerequisites
|
|
232
|
+
|
|
233
|
+
- Node.js 18+
|
|
234
|
+
- Yarn
|
|
235
|
+
|
|
236
|
+
### Setup
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
git clone https://github.com/yourusername/react-gridforms.git
|
|
240
|
+
cd react-gridforms
|
|
241
|
+
yarn install
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Available Scripts
|
|
245
|
+
|
|
246
|
+
- `yarn dev` - Start development server
|
|
247
|
+
- `yarn build` - Build for production
|
|
248
|
+
- `yarn build:lib` - Build library for distribution
|
|
249
|
+
- `yarn lint` - Run ESLint
|
|
250
|
+
- `yarn preview` - Preview production build
|
|
251
|
+
|
|
252
|
+
### Project Structure
|
|
253
|
+
|
|
254
|
+
```
|
|
255
|
+
src/
|
|
256
|
+
├── components/ # React components
|
|
257
|
+
│ ├── inputs/ # Input components
|
|
258
|
+
│ └── index.ts # Component exports
|
|
259
|
+
├── theme/ # Theme configuration
|
|
260
|
+
├── index.ts # Main library exports
|
|
261
|
+
└── lib.ts # Library build entry point
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## Contributing
|
|
265
|
+
|
|
266
|
+
1. Fork the repository
|
|
267
|
+
2. Create a feature branch
|
|
268
|
+
3. Make your changes
|
|
269
|
+
4. Add tests if applicable
|
|
270
|
+
5. Submit a pull request
|
|
271
|
+
|
|
272
|
+
## License
|
|
273
|
+
|
|
274
|
+
MIT License - see LICENSE file for details.
|
|
275
|
+
|
|
276
|
+
## Support
|
|
277
|
+
|
|
278
|
+
For support, please open an issue on GitHub or contact the maintainers.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface FormFieldProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
span: number;
|
|
5
|
+
label?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
rowspan?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const FormField: React.FC<FormFieldProps>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=FormField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormField.d.ts","sourceRoot":"","sources":["../../src/components/FormField.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,UAAU,cAAc;IACtB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkFD,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CA4D9C,CAAC"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect } from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
const StyledFormField = styled.div `
|
|
5
|
+
padding: ${(props) => props.theme.spacing.sm};
|
|
6
|
+
position: relative;
|
|
7
|
+
flex: ${({ span = 1, rowspan = 12 }) => `0 0 ${(100 / rowspan) * span}%`};
|
|
8
|
+
max-width: ${({ span = 1, rowspan = 12 }) => `${(100 / rowspan) * span}%`};
|
|
9
|
+
background-color: ${(props) => props.isFocused ? props.theme.colors.focusBackground : 'transparent'};
|
|
10
|
+
transition: background-color 0.2s ease;
|
|
11
|
+
border-right: 1px solid ${(props) => props.theme.colors.border};
|
|
12
|
+
|
|
13
|
+
label {
|
|
14
|
+
display: block;
|
|
15
|
+
font-size: ${(props) => props.theme.typography.fontSizeSmall};
|
|
16
|
+
color: ${(props) => props.theme.colors.textPrimary};
|
|
17
|
+
text-transform: uppercase;
|
|
18
|
+
letter-spacing: 0.5px;
|
|
19
|
+
margin-bottom: ${(props) => props.theme.spacing.xs};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Field styles */
|
|
23
|
+
input[type='text'],
|
|
24
|
+
input[type='email'],
|
|
25
|
+
input[type='number'],
|
|
26
|
+
input[type='password'],
|
|
27
|
+
input[type='search'],
|
|
28
|
+
input[type='tel'],
|
|
29
|
+
input[type='url'],
|
|
30
|
+
input[type='color'],
|
|
31
|
+
input[type='date'],
|
|
32
|
+
input[type='datetime'],
|
|
33
|
+
input[type='datetime-local'],
|
|
34
|
+
input[type='month'],
|
|
35
|
+
input[type='time'],
|
|
36
|
+
input[type='week'],
|
|
37
|
+
textarea,
|
|
38
|
+
select {
|
|
39
|
+
font-size: ${(props) => props.theme.typography.fontSizeLarge};
|
|
40
|
+
padding: 0;
|
|
41
|
+
margin: 0;
|
|
42
|
+
width: 100%;
|
|
43
|
+
border: 0;
|
|
44
|
+
background: ${(props) => props.theme.colors.inputBackground};
|
|
45
|
+
|
|
46
|
+
&::placeholder {
|
|
47
|
+
font-weight: ${(props) => props.theme.typography.fontWeightLight};
|
|
48
|
+
color: ${(props) => props.theme.colors.inputPlaceholder};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&:focus {
|
|
52
|
+
outline: none;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* Radio and checkbox styles */
|
|
57
|
+
input[type='radio'],
|
|
58
|
+
input[type='checkbox'] {
|
|
59
|
+
margin-right: ${(props) => props.theme.spacing.sm};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Radio and checkbox labels */
|
|
63
|
+
input[type='radio'] + label,
|
|
64
|
+
input[type='checkbox'] + label {
|
|
65
|
+
display: inline;
|
|
66
|
+
text-transform: none;
|
|
67
|
+
letter-spacing: normal;
|
|
68
|
+
margin-bottom: 0;
|
|
69
|
+
margin-left: ${(props) => props.theme.spacing.xs};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@media only screen and (max-width: 768px) {
|
|
73
|
+
flex: 1 1 100%;
|
|
74
|
+
max-width: 100%;
|
|
75
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.border};
|
|
76
|
+
}
|
|
77
|
+
`;
|
|
78
|
+
export const FormField = ({ children, span, label, className, rowspan = 12, }) => {
|
|
79
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
80
|
+
const fieldRef = useRef(null);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
const handleClick = (e) => {
|
|
83
|
+
if (fieldRef.current && !fieldRef.current.contains(e.target)) {
|
|
84
|
+
setIsFocused(false);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const handleFocus = () => setIsFocused(true);
|
|
88
|
+
const handleBlur = () => setIsFocused(false);
|
|
89
|
+
const field = fieldRef.current;
|
|
90
|
+
if (field) {
|
|
91
|
+
const focusableElements = field.querySelectorAll('input, textarea, select');
|
|
92
|
+
focusableElements.forEach((el) => {
|
|
93
|
+
el.addEventListener('focus', handleFocus);
|
|
94
|
+
el.addEventListener('blur', handleBlur);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
document.addEventListener('click', handleClick);
|
|
98
|
+
return () => {
|
|
99
|
+
document.removeEventListener('click', handleClick);
|
|
100
|
+
if (field) {
|
|
101
|
+
const focusableElements = field.querySelectorAll('input, textarea, select');
|
|
102
|
+
focusableElements.forEach((el) => {
|
|
103
|
+
el.removeEventListener('focus', handleFocus);
|
|
104
|
+
el.removeEventListener('blur', handleBlur);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}, []);
|
|
109
|
+
return (_jsxs(StyledFormField, { ref: fieldRef, "data-field-span": span, span: span, isFocused: isFocused, className: className, rowspan: rowspan, children: [label && _jsx("label", { children: label }), children] }));
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=FormField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormField.js","sourceRoot":"","sources":["../../src/components/FormField.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRow.d.ts","sourceRoot":"","sources":["../../src/components/FormRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,YAAY;IACpB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAkB1C,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
const StyledFormRow = styled.div `
|
|
5
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.border};
|
|
6
|
+
width: 100%;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-wrap: wrap
|
|
9
|
+
|
|
10
|
+
> div[data-field-span]:first-child {
|
|
11
|
+
border-left: none;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
> div[data-field-span]:last-child {
|
|
15
|
+
border-right: none;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@media only screen and (max-width: 768px) {
|
|
19
|
+
border-bottom: none;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
|
|
22
|
+
> div[data-field-span] {
|
|
23
|
+
flex: 1 1 100%;
|
|
24
|
+
max-width: 100%;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
export const FormRow = ({ children, span, className, }) => {
|
|
29
|
+
// Clone children and inject rowspan prop
|
|
30
|
+
const childrenWithRowspan = React.Children.map(children, (child) => {
|
|
31
|
+
if (React.isValidElement(child)) {
|
|
32
|
+
return React.cloneElement(child, { rowspan: span });
|
|
33
|
+
}
|
|
34
|
+
return child;
|
|
35
|
+
});
|
|
36
|
+
return (_jsx(StyledFormRow, { "data-row-span": span, span: span, className: className, children: childrenWithRowspan }));
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=FormRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRow.js","sourceRoot":"","sources":["../../src/components/FormRow.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAQvC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAkB;6BACrB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;CAsBhE,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAA2B,CAAC,EAC9C,QAAQ,EACR,IAAI,EACJ,SAAS,GACV,EAAE,EAAE;IACH,yCAAyC;IACzC,MAAM,mBAAmB,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;QACjE,IAAI,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAS,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,KAAC,aAAa,qBAAgB,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,YACjE,mBAAmB,GACN,CACjB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSection.d.ts","sourceRoot":"","sources":["../../src/components/FormSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,gBAAgB;IACxB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiCD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAWlD,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
const StyledFieldset = styled.fieldset `
|
|
4
|
+
border: none;
|
|
5
|
+
padding: 0;
|
|
6
|
+
margin: 0;
|
|
7
|
+
margin-top: ${(props) => props.theme.spacing.xl};
|
|
8
|
+
|
|
9
|
+
legend {
|
|
10
|
+
border: none;
|
|
11
|
+
border-bottom: 4px solid ${(props) => props.theme.colors.legend};
|
|
12
|
+
color: ${(props) => props.theme.colors.legend};
|
|
13
|
+
font-size: ${(props) => props.theme.typography.fontSizeLarge};
|
|
14
|
+
font-weight: ${(props) => props.theme.typography.fontWeightBold};
|
|
15
|
+
padding-bottom: 5px;
|
|
16
|
+
position: static;
|
|
17
|
+
width: 100%;
|
|
18
|
+
margin-bottom: ${(props) => props.theme.spacing.xs};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Nested fieldset styles */
|
|
22
|
+
fieldset legend {
|
|
23
|
+
border-bottom: 2px solid ${(props) => props.theme.colors.legend};
|
|
24
|
+
font-weight: ${(props) => props.theme.typography.fontWeightNormal};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fieldset fieldset legend {
|
|
28
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.legend};
|
|
29
|
+
font-weight: ${(props) => props.theme.typography.fontWeightNormal};
|
|
30
|
+
font-size: ${(props) => props.theme.typography.fontSizeBase};
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
export const FormSection = ({ children, title, className, }) => {
|
|
34
|
+
return (_jsxs(StyledFieldset, { className: className, children: [_jsx("legend", { children: title }), children] }));
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=FormSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormSection.js","sourceRoot":"","sources":["../../src/components/FormSection.tsx"],"names":[],"mappings":";AACA,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAQvC,MAAM,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAA;;;;gBAItB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;;;;+BAIlB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;aACtD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;iBAChC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa;mBAC7C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc;;;;qBAI9C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;;;;;+BAKvB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;mBAChD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,gBAAgB;;;;+BAItC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;mBAChD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,gBAAgB;iBACpD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY;;CAE9D,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAA+B,CAAC,EACtD,QAAQ,EACR,KAAK,EACL,SAAS,GACV,EAAE,EAAE;IACH,OAAO,CACL,MAAC,cAAc,IAAC,SAAS,EAAE,SAAS,aAClC,2BAAS,KAAK,GAAU,EACvB,QAAQ,IACM,CAClB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface GridFormProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
onSubmit?: (e: React.FormEvent) => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const GridForm: React.FC<GridFormProps>;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=GridForm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GridForm.d.ts","sourceRoot":"","sources":["../../src/components/GridForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,UAAU,aAAa;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqFD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAa5C,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
const StyledGridForm = styled.form `
|
|
4
|
+
width: 100%;
|
|
5
|
+
max-width: 100%;
|
|
6
|
+
|
|
7
|
+
/* Grid form base styles */
|
|
8
|
+
*,
|
|
9
|
+
*:before,
|
|
10
|
+
*:after {
|
|
11
|
+
box-sizing: border-box;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Remove backgrounds and borders from fields */
|
|
15
|
+
input[type='text'],
|
|
16
|
+
input[type='email'],
|
|
17
|
+
input[type='number'],
|
|
18
|
+
input[type='password'],
|
|
19
|
+
input[type='search'],
|
|
20
|
+
input[type='tel'],
|
|
21
|
+
input[type='url'],
|
|
22
|
+
input[type='color'],
|
|
23
|
+
input[type='date'],
|
|
24
|
+
input[type='datetime'],
|
|
25
|
+
input[type='datetime-local'],
|
|
26
|
+
input[type='month'],
|
|
27
|
+
input[type='time'],
|
|
28
|
+
input[type='week'],
|
|
29
|
+
textarea {
|
|
30
|
+
border: 0;
|
|
31
|
+
background: ${(props) => props.theme.colors.inputBackground};
|
|
32
|
+
|
|
33
|
+
&::placeholder {
|
|
34
|
+
font-weight: ${(props) => props.theme.typography.fontWeightLight};
|
|
35
|
+
color: ${(props) => props.theme.colors.inputPlaceholder};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&:focus {
|
|
39
|
+
outline: none;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Row styles */
|
|
44
|
+
[data-row-span] {
|
|
45
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.border};
|
|
46
|
+
width: 100%;
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-wrap: wrap;
|
|
49
|
+
|
|
50
|
+
@media only screen and (max-width: 768px) {
|
|
51
|
+
border-bottom: none;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* Field container styles */
|
|
56
|
+
[data-field-span] {
|
|
57
|
+
padding: ${(props) => props.theme.spacing.sm};
|
|
58
|
+
position: relative;
|
|
59
|
+
|
|
60
|
+
label {
|
|
61
|
+
display: block;
|
|
62
|
+
font-size: ${(props) => props.theme.typography.fontSizeSmall};
|
|
63
|
+
color: ${(props) => props.theme.colors.textPrimary};
|
|
64
|
+
text-transform: uppercase;
|
|
65
|
+
letter-spacing: 0.5px;
|
|
66
|
+
margin-bottom: ${(props) => props.theme.spacing.xs};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&.focus {
|
|
70
|
+
background-color: ${(props) => props.theme.colors.focusBackground};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Responsive behavior */
|
|
75
|
+
@media only screen and (max-width: 768px) {
|
|
76
|
+
[data-row-span] {
|
|
77
|
+
flex-direction: column;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[data-field-span] {
|
|
81
|
+
border-bottom: 1px solid ${(props) => props.theme.colors.border};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
`;
|
|
85
|
+
export const GridForm = ({ children, onSubmit, className, }) => {
|
|
86
|
+
return (_jsx(StyledGridForm, { className: `grid-form ${className || ''}`, onSubmit: onSubmit, children: children }));
|
|
87
|
+
};
|
|
88
|
+
//# sourceMappingURL=GridForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GridForm.js","sourceRoot":"","sources":["../../src/components/GridForm.tsx"],"names":[],"mappings":";AACA,OAAO,MAAM,MAAM,mBAAmB,CAAC;AAQvC,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBA4BhB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe;;;qBAG1C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,eAAe;eACvD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB;;;;;;;;;;+BAU9B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;;;;;;;;;;;;eAYpD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;;;;;mBAK7B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa;eACnD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW;;;uBAGjC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;;;;0BAI9B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe;;;;;;;;;;;iCAWtC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;;;CAGpE,CAAC;AAEF,MAAM,CAAC,MAAM,QAAQ,GAA4B,CAAC,EAChD,QAAQ,EACR,QAAQ,EACR,SAAS,GACV,EAAE,EAAE;IACH,OAAO,CACL,KAAC,cAAc,IACb,SAAS,EAAE,aAAa,SAAS,IAAI,EAAE,EAAE,EACzC,QAAQ,EAAE,QAAQ,YAEjB,QAAQ,GACM,CAClB,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../src/components/ThemeToggle.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,gBAAgB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0BD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CASlD,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
import { useTheme } from '../theme/ThemeContext';
|
|
4
|
+
const ToggleButton = styled.button `
|
|
5
|
+
background: ${(props) => props.theme.colors.surface};
|
|
6
|
+
border: 1px solid ${(props) => props.theme.colors.border};
|
|
7
|
+
color: ${(props) => props.theme.colors.textPrimary};
|
|
8
|
+
padding: ${(props) => props.theme.spacing.sm}
|
|
9
|
+
${(props) => props.theme.spacing.md};
|
|
10
|
+
border-radius: ${(props) => props.theme.borderRadius.md};
|
|
11
|
+
cursor: pointer;
|
|
12
|
+
font-size: ${(props) => props.theme.typography.fontSizeBase};
|
|
13
|
+
transition: all 0.2s ease;
|
|
14
|
+
|
|
15
|
+
&:hover {
|
|
16
|
+
background: ${(props) => props.theme.colors.hover};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&:active {
|
|
20
|
+
background: ${(props) => props.theme.colors.active};
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
const ToggleIcon = styled.span `
|
|
24
|
+
margin-right: ${(props) => props.theme.spacing.xs};
|
|
25
|
+
`;
|
|
26
|
+
export const ThemeToggle = ({ className }) => {
|
|
27
|
+
const { themeMode, toggleTheme } = useTheme();
|
|
28
|
+
return (_jsxs(ToggleButton, { onClick: toggleTheme, className: className, children: [_jsx(ToggleIcon, { children: themeMode === 'light' ? '🌙' : '☀️' }), themeMode === 'light' ? 'Dark Mode' : 'Light Mode'] }));
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=ThemeToggle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ThemeToggle.js","sourceRoot":"","sources":["../../src/components/ThemeToggle.tsx"],"names":[],"mappings":";AACA,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAMjD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAA;gBAClB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;sBAC/B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;WAC/C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW;aACvC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;MACxC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;mBACpB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE;;eAE1C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,YAAY;;;;kBAI3C,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK;;;;kBAInC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM;;CAErD,CAAC;AAEF,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAA;kBACZ,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;CAClD,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAA+B,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;IACvE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,QAAQ,EAAE,CAAC;IAE9C,OAAO,CACL,MAAC,YAAY,IAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,aACtD,KAAC,UAAU,cAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAc,EAC7D,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,IACtC,CAChB,CAAC;AACJ,CAAC,CAAC"}
|