@object-ui/components 0.3.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/CHANGELOG.md +46 -0
- package/LICENSE +21 -0
- package/README.md +170 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +46186 -0
- package/dist/index.umd.cjs +92 -0
- package/dist/src/hooks/use-mobile.d.ts +1 -0
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.test.d.ts +1 -0
- package/dist/src/lib/utils.d.ts +4 -0
- package/dist/src/new-components.test.d.ts +1 -0
- package/dist/src/renderers/basic/div.d.ts +1 -0
- package/dist/src/renderers/basic/html.d.ts +1 -0
- package/dist/src/renderers/basic/icon.d.ts +1 -0
- package/dist/src/renderers/basic/image.d.ts +1 -0
- package/dist/src/renderers/basic/index.d.ts +0 -0
- package/dist/src/renderers/basic/separator.d.ts +1 -0
- package/dist/src/renderers/basic/span.d.ts +1 -0
- package/dist/src/renderers/basic/text.d.ts +1 -0
- package/dist/src/renderers/complex/__tests__/data-table.test.d.ts +0 -0
- package/dist/src/renderers/complex/calendar-view.d.ts +1 -0
- package/dist/src/renderers/complex/carousel.d.ts +1 -0
- package/dist/src/renderers/complex/chatbot.d.ts +1 -0
- package/dist/src/renderers/complex/chatbot.test.d.ts +1 -0
- package/dist/src/renderers/complex/data-table.d.ts +1 -0
- package/dist/src/renderers/complex/filter-builder.d.ts +1 -0
- package/dist/src/renderers/complex/index.d.ts +0 -0
- package/dist/src/renderers/complex/resizable.d.ts +1 -0
- package/dist/src/renderers/complex/scroll-area.d.ts +1 -0
- package/dist/src/renderers/complex/table.d.ts +1 -0
- package/dist/src/renderers/complex/timeline.d.ts +1 -0
- package/dist/src/renderers/data-display/alert.d.ts +1 -0
- package/dist/src/renderers/data-display/avatar.d.ts +1 -0
- package/dist/src/renderers/data-display/badge.d.ts +1 -0
- package/dist/src/renderers/data-display/index.d.ts +0 -0
- package/dist/src/renderers/data-display/list.d.ts +1 -0
- package/dist/src/renderers/data-display/statistic.d.ts +1 -0
- package/dist/src/renderers/data-display/tree-view.d.ts +1 -0
- package/dist/src/renderers/disclosure/accordion.d.ts +1 -0
- package/dist/src/renderers/disclosure/collapsible.d.ts +1 -0
- package/dist/src/renderers/disclosure/index.d.ts +0 -0
- package/dist/src/renderers/feedback/index.d.ts +0 -0
- package/dist/src/renderers/feedback/loading.d.ts +1 -0
- package/dist/src/renderers/feedback/progress.d.ts +1 -0
- package/dist/src/renderers/feedback/skeleton.d.ts +1 -0
- package/dist/src/renderers/feedback/toaster.d.ts +1 -0
- package/dist/src/renderers/form/button.d.ts +1 -0
- package/dist/src/renderers/form/calendar.d.ts +1 -0
- package/dist/src/renderers/form/checkbox.d.ts +1 -0
- package/dist/src/renderers/form/date-picker.d.ts +1 -0
- package/dist/src/renderers/form/file-upload.d.ts +1 -0
- package/dist/src/renderers/form/form.d.ts +1 -0
- package/dist/src/renderers/form/index.d.ts +0 -0
- package/dist/src/renderers/form/input-otp.d.ts +1 -0
- package/dist/src/renderers/form/input.d.ts +1 -0
- package/dist/src/renderers/form/label.d.ts +1 -0
- package/dist/src/renderers/form/radio-group.d.ts +1 -0
- package/dist/src/renderers/form/select.d.ts +1 -0
- package/dist/src/renderers/form/slider.d.ts +1 -0
- package/dist/src/renderers/form/switch.d.ts +1 -0
- package/dist/src/renderers/form/textarea.d.ts +1 -0
- package/dist/src/renderers/form/toggle.d.ts +1 -0
- package/dist/src/renderers/index.d.ts +0 -0
- package/dist/src/renderers/layout/card.d.ts +1 -0
- package/dist/src/renderers/layout/container.d.ts +1 -0
- package/dist/src/renderers/layout/flex.d.ts +1 -0
- package/dist/src/renderers/layout/grid.d.ts +1 -0
- package/dist/src/renderers/layout/index.d.ts +0 -0
- package/dist/src/renderers/layout/page.d.ts +7 -0
- package/dist/src/renderers/layout/semantic.d.ts +1 -0
- package/dist/src/renderers/layout/stack.d.ts +1 -0
- package/dist/src/renderers/layout/tabs.d.ts +1 -0
- package/dist/src/renderers/navigation/header-bar.d.ts +1 -0
- package/dist/src/renderers/navigation/index.d.ts +0 -0
- package/dist/src/renderers/navigation/sidebar.d.ts +1 -0
- package/dist/src/renderers/overlay/alert-dialog.d.ts +1 -0
- package/dist/src/renderers/overlay/context-menu.d.ts +1 -0
- package/dist/src/renderers/overlay/dialog.d.ts +1 -0
- package/dist/src/renderers/overlay/drawer.d.ts +1 -0
- package/dist/src/renderers/overlay/dropdown-menu.d.ts +1 -0
- package/dist/src/renderers/overlay/hover-card.d.ts +1 -0
- package/dist/src/renderers/overlay/index.d.ts +0 -0
- package/dist/src/renderers/overlay/popover.d.ts +1 -0
- package/dist/src/renderers/overlay/sheet.d.ts +1 -0
- package/dist/src/renderers/overlay/tooltip.d.ts +1 -0
- package/dist/src/ui/accordion.d.ts +7 -0
- package/dist/src/ui/alert-dialog.d.ts +14 -0
- package/dist/src/ui/alert.d.ts +9 -0
- package/dist/src/ui/aspect-ratio.d.ts +3 -0
- package/dist/src/ui/avatar.d.ts +6 -0
- package/dist/src/ui/badge.d.ts +9 -0
- package/dist/src/ui/breadcrumb.d.ts +11 -0
- package/dist/src/ui/button-group.d.ts +11 -0
- package/dist/src/ui/button.d.ts +13 -0
- package/dist/src/ui/calendar-view.d.ts +21 -0
- package/dist/src/ui/calendar.d.ts +8 -0
- package/dist/src/ui/card.d.ts +9 -0
- package/dist/src/ui/carousel.d.ts +19 -0
- package/dist/src/ui/chatbot.d.ts +36 -0
- package/dist/src/ui/checkbox.d.ts +4 -0
- package/dist/src/ui/collapsible.d.ts +5 -0
- package/dist/src/ui/command.d.ts +18 -0
- package/dist/src/ui/context-menu.d.ts +25 -0
- package/dist/src/ui/dialog.d.ts +15 -0
- package/dist/src/ui/drawer.d.ts +13 -0
- package/dist/src/ui/dropdown-menu.d.ts +25 -0
- package/dist/src/ui/empty.d.ts +11 -0
- package/dist/src/ui/field.d.ts +24 -0
- package/dist/src/ui/filter-builder.d.ts +31 -0
- package/dist/src/ui/form.d.ts +24 -0
- package/dist/src/ui/hover-card.d.ts +6 -0
- package/dist/src/ui/index.d.ts +56 -0
- package/dist/src/ui/input-group.d.ts +16 -0
- package/dist/src/ui/input-otp.d.ts +11 -0
- package/dist/src/ui/input.d.ts +3 -0
- package/dist/src/ui/item.d.ts +23 -0
- package/dist/src/ui/kbd.d.ts +3 -0
- package/dist/src/ui/label.d.ts +4 -0
- package/dist/src/ui/menubar.d.ts +26 -0
- package/dist/src/ui/navigation-menu.d.ts +14 -0
- package/dist/src/ui/pagination.d.ts +13 -0
- package/dist/src/ui/popover.d.ts +7 -0
- package/dist/src/ui/progress.d.ts +4 -0
- package/dist/src/ui/radio-group.d.ts +5 -0
- package/dist/src/ui/resizable.d.ts +10 -0
- package/dist/src/ui/scroll-area.d.ts +5 -0
- package/dist/src/ui/select.d.ts +15 -0
- package/dist/src/ui/separator.d.ts +4 -0
- package/dist/src/ui/sheet.d.ts +13 -0
- package/dist/src/ui/sidebar.d.ts +69 -0
- package/dist/src/ui/skeleton.d.ts +2 -0
- package/dist/src/ui/slider.d.ts +4 -0
- package/dist/src/ui/sonner.d.ts +3 -0
- package/dist/src/ui/spinner.d.ts +3 -0
- package/dist/src/ui/switch.d.ts +4 -0
- package/dist/src/ui/table.d.ts +10 -0
- package/dist/src/ui/tabs.d.ts +7 -0
- package/dist/src/ui/textarea.d.ts +3 -0
- package/dist/src/ui/timeline.d.ts +25 -0
- package/dist/src/ui/toggle-group.d.ts +9 -0
- package/dist/src/ui/toggle.d.ts +9 -0
- package/dist/src/ui/tooltip.d.ts +7 -0
- package/docs/FilterBuilder.md +268 -0
- package/metadata/Chart.component.yml +30 -0
- package/metadata/FilterBuilder.component.yml +39 -0
- package/metadata/GridLayout.component.yml +27 -0
- package/metadata/Menu.component.yml +31 -0
- package/metadata/ObjectForm.component.yml +34 -0
- package/metadata/ObjectTable.component.yml +41 -0
- package/metadata/Page.component.yml +24 -0
- package/package.json +87 -0
- package/postcss.config.js +6 -0
- package/src/hooks/use-mobile.tsx +19 -0
- package/src/index.css +76 -0
- package/src/index.test.ts +7 -0
- package/src/index.ts +10 -0
- package/src/lib/utils.tsx +27 -0
- package/src/new-components.test.ts +74 -0
- package/src/renderers/basic/div.tsx +41 -0
- package/src/renderers/basic/html.tsx +34 -0
- package/src/renderers/basic/icon.tsx +25 -0
- package/src/renderers/basic/image.tsx +37 -0
- package/src/renderers/basic/index.ts +7 -0
- package/src/renderers/basic/separator.tsx +48 -0
- package/src/renderers/basic/span.tsx +44 -0
- package/src/renderers/basic/text.tsx +42 -0
- package/src/renderers/complex/README-KANBAN.md +208 -0
- package/src/renderers/complex/TIMELINE.md +353 -0
- package/src/renderers/complex/__tests__/data-table.test.ts +52 -0
- package/src/renderers/complex/calendar-view.tsx +219 -0
- package/src/renderers/complex/carousel.tsx +60 -0
- package/src/renderers/complex/chatbot.test.ts +44 -0
- package/src/renderers/complex/chatbot.tsx +185 -0
- package/src/renderers/complex/data-table.tsx +650 -0
- package/src/renderers/complex/filter-builder.tsx +68 -0
- package/src/renderers/complex/index.ts +10 -0
- package/src/renderers/complex/resizable.tsx +54 -0
- package/src/renderers/complex/scroll-area.tsx +32 -0
- package/src/renderers/complex/table.tsx +86 -0
- package/src/renderers/complex/timeline.tsx +466 -0
- package/src/renderers/data-display/alert.tsx +37 -0
- package/src/renderers/data-display/avatar.tsx +29 -0
- package/src/renderers/data-display/badge.tsx +46 -0
- package/src/renderers/data-display/index.ts +6 -0
- package/src/renderers/data-display/list.tsx +95 -0
- package/src/renderers/data-display/statistic.tsx +98 -0
- package/src/renderers/data-display/tree-view.tsx +180 -0
- package/src/renderers/disclosure/accordion.tsx +60 -0
- package/src/renderers/disclosure/collapsible.tsx +44 -0
- package/src/renderers/disclosure/index.ts +2 -0
- package/src/renderers/feedback/index.ts +4 -0
- package/src/renderers/feedback/loading.tsx +69 -0
- package/src/renderers/feedback/progress.tsx +20 -0
- package/src/renderers/feedback/skeleton.tsx +22 -0
- package/src/renderers/feedback/toaster.tsx +26 -0
- package/src/renderers/form/button.tsx +61 -0
- package/src/renderers/form/calendar.tsx +25 -0
- package/src/renderers/form/checkbox.tsx +41 -0
- package/src/renderers/form/date-picker.tsx +75 -0
- package/src/renderers/form/file-upload.tsx +175 -0
- package/src/renderers/form/form.tsx +417 -0
- package/src/renderers/form/index.ts +16 -0
- package/src/renderers/form/input-otp.tsx +31 -0
- package/src/renderers/form/input.tsx +79 -0
- package/src/renderers/form/label.tsx +36 -0
- package/src/renderers/form/radio-group.tsx +54 -0
- package/src/renderers/form/select.tsx +66 -0
- package/src/renderers/form/slider.tsx +45 -0
- package/src/renderers/form/switch.tsx +39 -0
- package/src/renderers/form/textarea.tsx +45 -0
- package/src/renderers/form/toggle.tsx +76 -0
- package/src/renderers/index.ts +9 -0
- package/src/renderers/layout/card.tsx +69 -0
- package/src/renderers/layout/container.tsx +113 -0
- package/src/renderers/layout/flex.tsx +123 -0
- package/src/renderers/layout/grid.tsx +155 -0
- package/src/renderers/layout/index.ts +10 -0
- package/src/renderers/layout/page.tsx +82 -0
- package/src/renderers/layout/semantic.tsx +39 -0
- package/src/renderers/layout/stack.tsx +123 -0
- package/src/renderers/layout/tabs.tsx +63 -0
- package/src/renderers/navigation/header-bar.tsx +50 -0
- package/src/renderers/navigation/index.ts +2 -0
- package/src/renderers/navigation/sidebar.tsx +189 -0
- package/src/renderers/overlay/alert-dialog.tsx +63 -0
- package/src/renderers/overlay/context-menu.tsx +91 -0
- package/src/renderers/overlay/dialog.tsx +68 -0
- package/src/renderers/overlay/drawer.tsx +68 -0
- package/src/renderers/overlay/dropdown-menu.tsx +90 -0
- package/src/renderers/overlay/hover-card.tsx +46 -0
- package/src/renderers/overlay/index.ts +9 -0
- package/src/renderers/overlay/popover.tsx +47 -0
- package/src/renderers/overlay/sheet.tsx +68 -0
- package/src/renderers/overlay/tooltip.tsx +58 -0
- package/src/ui/accordion.tsx +64 -0
- package/src/ui/alert-dialog.tsx +155 -0
- package/src/ui/alert.tsx +78 -0
- package/src/ui/aspect-ratio.tsx +11 -0
- package/src/ui/avatar.tsx +51 -0
- package/src/ui/badge.tsx +46 -0
- package/src/ui/breadcrumb.tsx +109 -0
- package/src/ui/button-group.tsx +83 -0
- package/src/ui/button.tsx +65 -0
- package/src/ui/calendar-view.tsx +503 -0
- package/src/ui/calendar.tsx +237 -0
- package/src/ui/card.tsx +138 -0
- package/src/ui/carousel.tsx +239 -0
- package/src/ui/chatbot.tsx +240 -0
- package/src/ui/checkbox.tsx +32 -0
- package/src/ui/collapsible.tsx +31 -0
- package/src/ui/command.tsx +182 -0
- package/src/ui/context-menu.tsx +247 -0
- package/src/ui/dialog.tsx +141 -0
- package/src/ui/drawer.tsx +135 -0
- package/src/ui/dropdown-menu.tsx +254 -0
- package/src/ui/empty.tsx +104 -0
- package/src/ui/field.tsx +246 -0
- package/src/ui/filter-builder.tsx +359 -0
- package/src/ui/form.tsx +167 -0
- package/src/ui/hover-card.tsx +44 -0
- package/src/ui/index.ts +56 -0
- package/src/ui/input-group.tsx +170 -0
- package/src/ui/input-otp.tsx +81 -0
- package/src/ui/input.tsx +24 -0
- package/src/ui/item.tsx +193 -0
- package/src/ui/kbd.tsx +28 -0
- package/src/ui/label.tsx +24 -0
- package/src/ui/menubar.tsx +274 -0
- package/src/ui/navigation-menu.tsx +168 -0
- package/src/ui/pagination.tsx +127 -0
- package/src/ui/popover.tsx +48 -0
- package/src/ui/progress.tsx +41 -0
- package/src/ui/radio-group.tsx +45 -0
- package/src/ui/resizable.tsx +55 -0
- package/src/ui/scroll-area.tsx +58 -0
- package/src/ui/select.tsx +188 -0
- package/src/ui/separator.tsx +31 -0
- package/src/ui/sheet.tsx +137 -0
- package/src/ui/sidebar.tsx +726 -0
- package/src/ui/skeleton.tsx +20 -0
- package/src/ui/slider.tsx +63 -0
- package/src/ui/sonner.tsx +43 -0
- package/src/ui/spinner.tsx +38 -0
- package/src/ui/switch.tsx +31 -0
- package/src/ui/table.tsx +120 -0
- package/src/ui/tabs.tsx +86 -0
- package/src/ui/textarea.tsx +18 -0
- package/src/ui/timeline.tsx +266 -0
- package/src/ui/toggle-group.tsx +87 -0
- package/src/ui/toggle.tsx +50 -0
- package/src/ui/tooltip.tsx +61 -0
- package/tailwind.config.js +75 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +44 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Filter Builder Component
|
|
2
|
+
|
|
3
|
+
An Airtable-like filter builder component for building complex query conditions in Object UI.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Filter Builder component provides a user-friendly interface for creating and managing filter conditions. It supports:
|
|
8
|
+
|
|
9
|
+
- ✅ Dynamic add/remove filter conditions
|
|
10
|
+
- ✅ Field selection from configurable list
|
|
11
|
+
- ✅ Type-aware operators (text, number, boolean, date, select)
|
|
12
|
+
- ✅ AND/OR logic toggling
|
|
13
|
+
- ✅ Clear all filters button
|
|
14
|
+
- ✅ Date picker support for date fields
|
|
15
|
+
- ✅ Dropdown support for select fields
|
|
16
|
+
- ✅ Schema-driven configuration
|
|
17
|
+
- ✅ Tailwind CSS styled with Shadcn UI components
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
### Basic Example
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
{
|
|
25
|
+
type: 'filter-builder',
|
|
26
|
+
name: 'userFilters',
|
|
27
|
+
label: 'User Filters',
|
|
28
|
+
fields: [
|
|
29
|
+
{ value: 'name', label: 'Name', type: 'text' },
|
|
30
|
+
{ value: 'email', label: 'Email', type: 'text' },
|
|
31
|
+
{ value: 'age', label: 'Age', type: 'number' },
|
|
32
|
+
{ value: 'status', label: 'Status', type: 'text' }
|
|
33
|
+
],
|
|
34
|
+
value: {
|
|
35
|
+
id: 'root',
|
|
36
|
+
logic: 'and',
|
|
37
|
+
conditions: [
|
|
38
|
+
{
|
|
39
|
+
id: 'cond-1',
|
|
40
|
+
field: 'status',
|
|
41
|
+
operator: 'equals',
|
|
42
|
+
value: 'active'
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### With Select Fields
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
{
|
|
53
|
+
type: 'filter-builder',
|
|
54
|
+
name: 'productFilters',
|
|
55
|
+
label: 'Product Filters',
|
|
56
|
+
fields: [
|
|
57
|
+
{ value: 'name', label: 'Product Name', type: 'text' },
|
|
58
|
+
{ value: 'price', label: 'Price', type: 'number' },
|
|
59
|
+
{
|
|
60
|
+
value: 'category',
|
|
61
|
+
label: 'Category',
|
|
62
|
+
type: 'select',
|
|
63
|
+
options: [
|
|
64
|
+
{ value: 'electronics', label: 'Electronics' },
|
|
65
|
+
{ value: 'clothing', label: 'Clothing' },
|
|
66
|
+
{ value: 'food', label: 'Food' }
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{ value: 'inStock', label: 'In Stock', type: 'boolean' }
|
|
70
|
+
],
|
|
71
|
+
value: {
|
|
72
|
+
id: 'root',
|
|
73
|
+
logic: 'and',
|
|
74
|
+
conditions: []
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### With Date Fields
|
|
80
|
+
|
|
81
|
+
```typescript
|
|
82
|
+
{
|
|
83
|
+
type: 'filter-builder',
|
|
84
|
+
name: 'orderFilters',
|
|
85
|
+
label: 'Order Filters',
|
|
86
|
+
fields: [
|
|
87
|
+
{ value: 'orderId', label: 'Order ID', type: 'text' },
|
|
88
|
+
{ value: 'amount', label: 'Amount', type: 'number' },
|
|
89
|
+
{ value: 'orderDate', label: 'Order Date', type: 'date' },
|
|
90
|
+
{ value: 'shipped', label: 'Shipped', type: 'boolean' }
|
|
91
|
+
],
|
|
92
|
+
showClearAll: true
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Props
|
|
97
|
+
|
|
98
|
+
### Schema Properties
|
|
99
|
+
|
|
100
|
+
| Property | Type | Required | Description |
|
|
101
|
+
|----------|------|----------|-------------|
|
|
102
|
+
| `type` | `string` | ✅ | Must be `'filter-builder'` |
|
|
103
|
+
| `name` | `string` | ✅ | Form field name for the filter value |
|
|
104
|
+
| `label` | `string` | ❌ | Label displayed above the filter builder |
|
|
105
|
+
| `fields` | `Field[]` | ✅ | Array of available fields for filtering |
|
|
106
|
+
| `value` | `FilterGroup` | ❌ | Initial filter configuration |
|
|
107
|
+
| `showClearAll` | `boolean` | ❌ | Show "Clear all" button (default: true) |
|
|
108
|
+
|
|
109
|
+
### Field Type
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
interface Field {
|
|
113
|
+
value: string; // Field identifier
|
|
114
|
+
label: string; // Display label
|
|
115
|
+
type?: string; // Field type: 'text' | 'number' | 'boolean' | 'date' | 'select'
|
|
116
|
+
options?: Array<{ value: string; label: string }> // For select fields
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### FilterGroup Type
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
interface FilterGroup {
|
|
124
|
+
id: string; // Group identifier
|
|
125
|
+
logic: 'and' | 'or'; // Logic operator
|
|
126
|
+
conditions: FilterCondition[]; // Array of conditions
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
interface FilterCondition {
|
|
130
|
+
id: string; // Condition identifier
|
|
131
|
+
field: string; // Field value
|
|
132
|
+
operator: string; // Operator (see below)
|
|
133
|
+
value: string | number | boolean; // Filter value
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Operators
|
|
138
|
+
|
|
139
|
+
The available operators change based on the field type:
|
|
140
|
+
|
|
141
|
+
### Text Fields
|
|
142
|
+
- `equals` - Equals
|
|
143
|
+
- `notEquals` - Does not equal
|
|
144
|
+
- `contains` - Contains
|
|
145
|
+
- `notContains` - Does not contain
|
|
146
|
+
- `isEmpty` - Is empty
|
|
147
|
+
- `isNotEmpty` - Is not empty
|
|
148
|
+
|
|
149
|
+
### Number Fields
|
|
150
|
+
- `equals` - Equals
|
|
151
|
+
- `notEquals` - Does not equal
|
|
152
|
+
- `greaterThan` - Greater than
|
|
153
|
+
- `lessThan` - Less than
|
|
154
|
+
- `greaterOrEqual` - Greater than or equal
|
|
155
|
+
- `lessOrEqual` - Less than or equal
|
|
156
|
+
- `isEmpty` - Is empty
|
|
157
|
+
- `isNotEmpty` - Is not empty
|
|
158
|
+
|
|
159
|
+
### Boolean Fields
|
|
160
|
+
- `equals` - Equals
|
|
161
|
+
- `notEquals` - Does not equal
|
|
162
|
+
|
|
163
|
+
### Date Fields
|
|
164
|
+
- `equals` - Equals
|
|
165
|
+
- `notEquals` - Does not equal
|
|
166
|
+
- `before` - Before
|
|
167
|
+
- `after` - After
|
|
168
|
+
- `between` - Between
|
|
169
|
+
- `isEmpty` - Is empty
|
|
170
|
+
- `isNotEmpty` - Is not empty
|
|
171
|
+
|
|
172
|
+
### Select Fields
|
|
173
|
+
- `equals` - Equals
|
|
174
|
+
- `notEquals` - Does not equal
|
|
175
|
+
- `in` - In
|
|
176
|
+
- `notIn` - Not in
|
|
177
|
+
- `isEmpty` - Is empty
|
|
178
|
+
- `isNotEmpty` - Is not empty
|
|
179
|
+
|
|
180
|
+
## Events
|
|
181
|
+
|
|
182
|
+
The component emits change events when the filter configuration is modified:
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
{
|
|
186
|
+
target: {
|
|
187
|
+
name: 'filters',
|
|
188
|
+
value: {
|
|
189
|
+
id: 'root',
|
|
190
|
+
logic: 'and',
|
|
191
|
+
conditions: [...]
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Demo
|
|
198
|
+
|
|
199
|
+
To see the filter builder in action:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
pnpm --filter prototype dev
|
|
203
|
+
# Visit http://localhost:5173/?demo=filter-builder
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Styling
|
|
207
|
+
|
|
208
|
+
The component is fully styled with Tailwind CSS and follows the Object UI design system. All Shadcn UI components are used for consistent look and feel.
|
|
209
|
+
|
|
210
|
+
You can customize the appearance using the `className` prop or by overriding Tailwind classes.
|
|
211
|
+
|
|
212
|
+
## Integration
|
|
213
|
+
|
|
214
|
+
The Filter Builder integrates seamlessly with Object UI's schema system and can be used in:
|
|
215
|
+
|
|
216
|
+
- Forms
|
|
217
|
+
- Data tables
|
|
218
|
+
- Search interfaces
|
|
219
|
+
- Admin panels
|
|
220
|
+
- Dashboard filters
|
|
221
|
+
|
|
222
|
+
## Example in Context
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const pageSchema = {
|
|
226
|
+
type: 'page',
|
|
227
|
+
title: 'User Management',
|
|
228
|
+
body: [
|
|
229
|
+
{
|
|
230
|
+
type: 'card',
|
|
231
|
+
body: [
|
|
232
|
+
{
|
|
233
|
+
type: 'filter-builder',
|
|
234
|
+
name: 'userFilters',
|
|
235
|
+
label: 'Filter Users',
|
|
236
|
+
fields: [
|
|
237
|
+
{ value: 'name', label: 'Name', type: 'text' },
|
|
238
|
+
{ value: 'email', label: 'Email', type: 'text' },
|
|
239
|
+
{ value: 'age', label: 'Age', type: 'number' },
|
|
240
|
+
{ value: 'department', label: 'Department', type: 'text' },
|
|
241
|
+
{ value: 'active', label: 'Active', type: 'boolean' }
|
|
242
|
+
]
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
type: 'table',
|
|
248
|
+
// table configuration...
|
|
249
|
+
}
|
|
250
|
+
]
|
|
251
|
+
};
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Technical Details
|
|
255
|
+
|
|
256
|
+
- Built with React 18+ hooks
|
|
257
|
+
- Uses Radix UI primitives (Select, Popover)
|
|
258
|
+
- Type-safe with TypeScript
|
|
259
|
+
- Accessible keyboard navigation
|
|
260
|
+
- Responsive design
|
|
261
|
+
|
|
262
|
+
## Browser Support
|
|
263
|
+
|
|
264
|
+
Works in all modern browsers that support:
|
|
265
|
+
- ES6+
|
|
266
|
+
- CSS Grid
|
|
267
|
+
- Flexbox
|
|
268
|
+
- crypto.randomUUID()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Chart
|
|
2
|
+
label: Chart
|
|
3
|
+
description: Data visualization component based on Recharts/ECharts
|
|
4
|
+
category: visualization
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: type
|
|
10
|
+
type: string
|
|
11
|
+
enum: [bar, line, pie, area, radar]
|
|
12
|
+
required: true
|
|
13
|
+
- name: data
|
|
14
|
+
type: array
|
|
15
|
+
required: true
|
|
16
|
+
- name: series
|
|
17
|
+
type: array
|
|
18
|
+
description: Configuration for data series
|
|
19
|
+
- name: xAxis
|
|
20
|
+
type: object
|
|
21
|
+
- name: yAxis
|
|
22
|
+
type: object
|
|
23
|
+
|
|
24
|
+
events:
|
|
25
|
+
- name: onClick
|
|
26
|
+
payload: "{ dataIndex: number, value: any }"
|
|
27
|
+
|
|
28
|
+
features:
|
|
29
|
+
responsive: true
|
|
30
|
+
dark_mode: true
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: FilterBuilder
|
|
2
|
+
label: Filter Builder
|
|
3
|
+
description: Airtable-like filter builder for creating complex query conditions
|
|
4
|
+
category: complex
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: label
|
|
10
|
+
type: string
|
|
11
|
+
description: Label text displayed above the filter builder
|
|
12
|
+
- name: name
|
|
13
|
+
type: string
|
|
14
|
+
required: true
|
|
15
|
+
description: Form field name for the filter value
|
|
16
|
+
- name: fields
|
|
17
|
+
type: array
|
|
18
|
+
required: true
|
|
19
|
+
description: Available fields for filtering
|
|
20
|
+
schema:
|
|
21
|
+
- value: string
|
|
22
|
+
- label: string
|
|
23
|
+
- type: string
|
|
24
|
+
- name: value
|
|
25
|
+
type: object
|
|
26
|
+
description: Current filter configuration
|
|
27
|
+
schema:
|
|
28
|
+
- id: string
|
|
29
|
+
- logic: enum[and, or]
|
|
30
|
+
- conditions: array
|
|
31
|
+
|
|
32
|
+
events:
|
|
33
|
+
- name: onChange
|
|
34
|
+
payload: "{ name: string, value: FilterGroup }"
|
|
35
|
+
|
|
36
|
+
features:
|
|
37
|
+
dynamic_conditions: true
|
|
38
|
+
multiple_operators: true
|
|
39
|
+
field_type_aware: true
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: GridLayout
|
|
2
|
+
label: Grid Layout
|
|
3
|
+
description: 12-column grid layout system
|
|
4
|
+
category: layout
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: columns
|
|
10
|
+
type: number
|
|
11
|
+
default: 12
|
|
12
|
+
- name: gap
|
|
13
|
+
type: string
|
|
14
|
+
default: md
|
|
15
|
+
- name: items
|
|
16
|
+
type: array
|
|
17
|
+
description: list of widgets to render in the grid
|
|
18
|
+
schema:
|
|
19
|
+
- x: number
|
|
20
|
+
- y: number
|
|
21
|
+
- w: number
|
|
22
|
+
- h: number
|
|
23
|
+
- component: object # SchemaNode
|
|
24
|
+
|
|
25
|
+
features:
|
|
26
|
+
responsive: true
|
|
27
|
+
drag_and_drop: true
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: Menu
|
|
2
|
+
label: Navigation Menu
|
|
3
|
+
description: Multi-level navigation menu for app shells
|
|
4
|
+
category: navigation
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: type
|
|
10
|
+
type: string
|
|
11
|
+
enum: [sidebar, topnav, context]
|
|
12
|
+
default: sidebar
|
|
13
|
+
- name: items
|
|
14
|
+
type: array
|
|
15
|
+
required: true
|
|
16
|
+
schema:
|
|
17
|
+
- name: string
|
|
18
|
+
- label: string
|
|
19
|
+
- icon: string
|
|
20
|
+
- path: string
|
|
21
|
+
- items: array # nested items
|
|
22
|
+
- name: collapsed
|
|
23
|
+
type: boolean
|
|
24
|
+
default: false
|
|
25
|
+
|
|
26
|
+
events:
|
|
27
|
+
- name: onItemClick
|
|
28
|
+
payload: "{ item: MenuItem }"
|
|
29
|
+
|
|
30
|
+
features:
|
|
31
|
+
router_integration: true
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
name: ObjectForm
|
|
2
|
+
label: Object Form
|
|
3
|
+
description: Smart form for creating and editing object records
|
|
4
|
+
category: data_entry
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: object
|
|
10
|
+
type: string
|
|
11
|
+
required: true
|
|
12
|
+
description: The object API name
|
|
13
|
+
- name: recordId
|
|
14
|
+
type: string
|
|
15
|
+
description: The ID of the record to edit (optional, for create mode leave empty)
|
|
16
|
+
- name: layout
|
|
17
|
+
type: object
|
|
18
|
+
description: Form layout definition
|
|
19
|
+
- name: mode
|
|
20
|
+
type: string
|
|
21
|
+
enum: [read, edit, create]
|
|
22
|
+
default: edit
|
|
23
|
+
|
|
24
|
+
events:
|
|
25
|
+
- name: onSubmit
|
|
26
|
+
payload: "{ data: any }"
|
|
27
|
+
- name: onSuccess
|
|
28
|
+
payload: "{ id: string, data: any }"
|
|
29
|
+
- name: onError
|
|
30
|
+
payload: "{ error: any }"
|
|
31
|
+
|
|
32
|
+
features:
|
|
33
|
+
validation: true
|
|
34
|
+
auto_save: false
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: ObjectTable
|
|
2
|
+
label: Object Table
|
|
3
|
+
description: Production-grade data table for displaying and managing object records
|
|
4
|
+
category: data_display
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: object
|
|
10
|
+
type: string
|
|
11
|
+
required: true
|
|
12
|
+
description: The object API name to display data for
|
|
13
|
+
- name: columns
|
|
14
|
+
type: array
|
|
15
|
+
description: Column configurations
|
|
16
|
+
schema:
|
|
17
|
+
- field: string
|
|
18
|
+
- label: string
|
|
19
|
+
- width: number
|
|
20
|
+
- name: filters
|
|
21
|
+
type: array
|
|
22
|
+
description: Default filters
|
|
23
|
+
- name: sortable
|
|
24
|
+
type: boolean
|
|
25
|
+
default: true
|
|
26
|
+
- name: paginated
|
|
27
|
+
type: boolean
|
|
28
|
+
default: true
|
|
29
|
+
- name: pageSize
|
|
30
|
+
type: number
|
|
31
|
+
default: 20
|
|
32
|
+
|
|
33
|
+
events:
|
|
34
|
+
- name: onRowClick
|
|
35
|
+
payload: "{ row: any, index: number }"
|
|
36
|
+
- name: onSelectionChange
|
|
37
|
+
payload: "{ selectedIds: string[] }"
|
|
38
|
+
|
|
39
|
+
features:
|
|
40
|
+
remote_data: true
|
|
41
|
+
virtual_scroll: true
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
name: Page
|
|
2
|
+
label: Page Container
|
|
3
|
+
description: Root container for application pages
|
|
4
|
+
category: layout
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
framework: react
|
|
7
|
+
|
|
8
|
+
props:
|
|
9
|
+
- name: title
|
|
10
|
+
type: string
|
|
11
|
+
- name: layout
|
|
12
|
+
type: string
|
|
13
|
+
enum: [default, full, blank]
|
|
14
|
+
default: default
|
|
15
|
+
- name: aside
|
|
16
|
+
type: object # SchemaNode
|
|
17
|
+
description: Sidebar content
|
|
18
|
+
- name: body
|
|
19
|
+
type: object # SchemaNode
|
|
20
|
+
description: Main content
|
|
21
|
+
|
|
22
|
+
features:
|
|
23
|
+
seo: true
|
|
24
|
+
breadcrumbs: true
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@object-ui/components",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "dist/index.umd.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.umd.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./dist/style.css": "./dist/style.css"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@radix-ui/react-accordion": "^1.2.12",
|
|
19
|
+
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
20
|
+
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
|
21
|
+
"@radix-ui/react-avatar": "^1.1.11",
|
|
22
|
+
"@radix-ui/react-checkbox": "^1.3.3",
|
|
23
|
+
"@radix-ui/react-collapsible": "^1.1.12",
|
|
24
|
+
"@radix-ui/react-context-menu": "^2.2.16",
|
|
25
|
+
"@radix-ui/react-dialog": "^1.1.15",
|
|
26
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
27
|
+
"@radix-ui/react-hover-card": "^1.1.15",
|
|
28
|
+
"@radix-ui/react-label": "^2.1.8",
|
|
29
|
+
"@radix-ui/react-menubar": "^1.1.16",
|
|
30
|
+
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
31
|
+
"@radix-ui/react-popover": "^1.1.15",
|
|
32
|
+
"@radix-ui/react-progress": "^1.1.8",
|
|
33
|
+
"@radix-ui/react-radio-group": "^1.3.8",
|
|
34
|
+
"@radix-ui/react-scroll-area": "^1.2.10",
|
|
35
|
+
"@radix-ui/react-select": "^2.2.6",
|
|
36
|
+
"@radix-ui/react-separator": "^1.1.8",
|
|
37
|
+
"@radix-ui/react-slider": "^1.3.6",
|
|
38
|
+
"@radix-ui/react-slot": "^1.2.4",
|
|
39
|
+
"@radix-ui/react-switch": "^1.2.6",
|
|
40
|
+
"@radix-ui/react-tabs": "^1.1.13",
|
|
41
|
+
"@radix-ui/react-toast": "^1.2.15",
|
|
42
|
+
"@radix-ui/react-toggle": "^1.1.10",
|
|
43
|
+
"@radix-ui/react-toggle-group": "^1.1.11",
|
|
44
|
+
"@radix-ui/react-tooltip": "^1.2.8",
|
|
45
|
+
"class-variance-authority": "^0.7.1",
|
|
46
|
+
"clsx": "^2.1.1",
|
|
47
|
+
"cmdk": "^1.1.1",
|
|
48
|
+
"date-fns": "^4.1.0",
|
|
49
|
+
"embla-carousel-react": "^8.6.0",
|
|
50
|
+
"input-otp": "^1.4.2",
|
|
51
|
+
"lucide-react": "^0.469.0",
|
|
52
|
+
"next-themes": "^0.4.6",
|
|
53
|
+
"react-day-picker": "^9.13.0",
|
|
54
|
+
"react-hook-form": "^7.71.1",
|
|
55
|
+
"react-resizable-panels": "^4.4.1",
|
|
56
|
+
"sonner": "^2.0.7",
|
|
57
|
+
"tailwind-merge": "^3.4.0",
|
|
58
|
+
"tailwindcss-animate": "^1.0.7",
|
|
59
|
+
"vaul": "^1.1.2",
|
|
60
|
+
"@object-ui/core": "0.3.0",
|
|
61
|
+
"@object-ui/react": "0.3.0",
|
|
62
|
+
"@object-ui/types": "0.3.0"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
66
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
67
|
+
"tailwindcss": "^3.0.0"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/react": "^18.3.12",
|
|
71
|
+
"@types/react-dom": "^18.3.1",
|
|
72
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
73
|
+
"autoprefixer": "^10.4.16",
|
|
74
|
+
"postcss": "^8.4.31",
|
|
75
|
+
"tailwindcss": "^3.3.5",
|
|
76
|
+
"typescript": "^5.9.3",
|
|
77
|
+
"vite": "^7.3.1",
|
|
78
|
+
"vite-plugin-dts": "^4.5.4"
|
|
79
|
+
},
|
|
80
|
+
"scripts": {
|
|
81
|
+
"build": "vite build",
|
|
82
|
+
"pretest": "pnpm --filter @object-ui/core build && pnpm --filter @object-ui/react build",
|
|
83
|
+
"test": "vitest run",
|
|
84
|
+
"type-check": "tsc --noEmit",
|
|
85
|
+
"lint": "eslint ."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as React from "react"
|
|
2
|
+
|
|
3
|
+
const MOBILE_BREAKPOINT = 768
|
|
4
|
+
|
|
5
|
+
export function useIsMobile() {
|
|
6
|
+
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
|
|
7
|
+
|
|
8
|
+
React.useEffect(() => {
|
|
9
|
+
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
|
|
10
|
+
const onChange = () => {
|
|
11
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
12
|
+
}
|
|
13
|
+
mql.addEventListener("change", onChange)
|
|
14
|
+
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
|
15
|
+
return () => mql.removeEventListener("change", onChange)
|
|
16
|
+
}, [])
|
|
17
|
+
|
|
18
|
+
return !!isMobile
|
|
19
|
+
}
|
package/src/index.css
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
@tailwind base;
|
|
2
|
+
@tailwind components;
|
|
3
|
+
@tailwind utilities;
|
|
4
|
+
|
|
5
|
+
@layer base {
|
|
6
|
+
:root {
|
|
7
|
+
--background: 0 0% 100%;
|
|
8
|
+
--foreground: 222.2 84% 4.9%;
|
|
9
|
+
|
|
10
|
+
--card: 0 0% 100%;
|
|
11
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
12
|
+
|
|
13
|
+
--popover: 0 0% 100%;
|
|
14
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
15
|
+
|
|
16
|
+
--primary: 222.2 47.4% 11.2%;
|
|
17
|
+
--primary-foreground: 210 40% 98%;
|
|
18
|
+
|
|
19
|
+
--secondary: 210 40% 96.1%;
|
|
20
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
21
|
+
|
|
22
|
+
--muted: 210 40% 96.1%;
|
|
23
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
24
|
+
|
|
25
|
+
--accent: 210 40% 96.1%;
|
|
26
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
27
|
+
|
|
28
|
+
--destructive: 0 84.2% 60.2%;
|
|
29
|
+
--destructive-foreground: 210 40% 98%;
|
|
30
|
+
|
|
31
|
+
--border: 214.3 31.8% 91.4%;
|
|
32
|
+
--input: 214.3 31.8% 91.4%;
|
|
33
|
+
--ring: 222.2 84% 4.9%;
|
|
34
|
+
|
|
35
|
+
--radius: 0.5rem;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.dark {
|
|
39
|
+
--background: 222.2 84% 4.9%;
|
|
40
|
+
--foreground: 210 40% 98%;
|
|
41
|
+
|
|
42
|
+
--card: 222.2 84% 4.9%;
|
|
43
|
+
--card-foreground: 210 40% 98%;
|
|
44
|
+
|
|
45
|
+
--popover: 222.2 84% 4.9%;
|
|
46
|
+
--popover-foreground: 210 40% 98%;
|
|
47
|
+
|
|
48
|
+
--primary: 210 40% 98%;
|
|
49
|
+
--primary-foreground: 222.2 47.4% 11.2%;
|
|
50
|
+
|
|
51
|
+
--secondary: 217.2 32.6% 17.5%;
|
|
52
|
+
--secondary-foreground: 210 40% 98%;
|
|
53
|
+
|
|
54
|
+
--muted: 217.2 32.6% 17.5%;
|
|
55
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
56
|
+
|
|
57
|
+
--accent: 217.2 32.6% 17.5%;
|
|
58
|
+
--accent-foreground: 210 40% 98%;
|
|
59
|
+
|
|
60
|
+
--destructive: 0 62.8% 30.6%;
|
|
61
|
+
--destructive-foreground: 210 40% 98%;
|
|
62
|
+
|
|
63
|
+
--border: 217.2 32.6% 17.5%;
|
|
64
|
+
--input: 217.2 32.6% 17.5%;
|
|
65
|
+
--ring: 212.7 26.8% 83.9%;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@layer base {
|
|
70
|
+
* {
|
|
71
|
+
@apply border-border;
|
|
72
|
+
}
|
|
73
|
+
body {
|
|
74
|
+
@apply bg-background text-foreground;
|
|
75
|
+
}
|
|
76
|
+
}
|