pgo-uiux2 1.0.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/.env +1 -0
- package/.env.production +1 -0
- package/.prettierrc +13 -0
- package/.vscode/extensions.json +3 -0
- package/BUTTON_GUIDE.md +257 -0
- package/README.md +49 -0
- package/THEME_REFERENCE.md +310 -0
- package/eslint.config.ts +27 -0
- package/index.html +13 -0
- package/package.json +85 -0
- package/public/favicon.ico +0 -0
- package/src/App.vue +368 -0
- package/src/assets/fonts/Faruma.ttf +0 -0
- package/src/components/examples/AppBarExample.vue +101 -0
- package/src/components/examples/AvatarExample.vue +47 -0
- package/src/components/examples/BannerExample.vue +287 -0
- package/src/components/examples/BaseInputExample.vue +25 -0
- package/src/components/examples/BreadcrumbExample.vue +53 -0
- package/src/components/examples/CardExample.vue +77 -0
- package/src/components/examples/ChipExample.vue +225 -0
- package/src/components/examples/DatePickerExample.vue +31 -0
- package/src/components/examples/DropdownExample.vue +84 -0
- package/src/components/examples/EditorExample.vue +200 -0
- package/src/components/examples/ExpansionPanelExample.vue +42 -0
- package/src/components/examples/FileUploadExample.vue +40 -0
- package/src/components/examples/FormExample.vue +121 -0
- package/src/components/examples/HugeTest.vue +8 -0
- package/src/components/examples/LayoutContainerExample.vue +80 -0
- package/src/components/examples/ModalExample.vue +82 -0
- package/src/components/examples/NavDrawerExample.vue +170 -0
- package/src/components/examples/NumberFieldExample.vue +145 -0
- package/src/components/examples/RadioButtonExample.vue +161 -0
- package/src/components/examples/SearchExample.vue +322 -0
- package/src/components/examples/SelectExample.vue +121 -0
- package/src/components/examples/StackedTableViewExample.vue +53 -0
- package/src/components/examples/TabExample.vue +336 -0
- package/src/components/examples/TableExample.vue +228 -0
- package/src/components/examples/TextFieldExample.vue +181 -0
- package/src/components/examples/TextareaExample.vue +173 -0
- package/src/components/examples/ThemeToggle.vue +50 -0
- package/src/components/examples/TimelineExample.vue +66 -0
- package/src/components/examples/TipTapEditorExample.vue +20 -0
- package/src/components/examples/TooltipExample.vue +53 -0
- package/src/components/examples/VueDatePickerShowcase.vue +214 -0
- package/src/components/examples/_DatePickerExample.vue +33 -0
- package/src/components/examples/__FormExample.vue +77 -0
- package/src/components/index.ts +25 -0
- package/src/components/pgo/AppBar.vue +347 -0
- package/src/components/pgo/Avatar.vue +139 -0
- package/src/components/pgo/Banner.vue +300 -0
- package/src/components/pgo/Breadcrumb.vue +101 -0
- package/src/components/pgo/Button.vue +171 -0
- package/src/components/pgo/Card.vue +178 -0
- package/src/components/pgo/ConfirmationModel.vue +32 -0
- package/src/components/pgo/DataTable.vue +845 -0
- package/src/components/pgo/DatePicker/CalendarPanel.vue +43 -0
- package/src/components/pgo/DatePicker/__DatePicker.vue +122 -0
- package/src/components/pgo/DatePicker/types.ts +11 -0
- package/src/components/pgo/DatePicker/useCalendar.ts +39 -0
- package/src/components/pgo/DatePicker/useDatePicker.ts +31 -0
- package/src/components/pgo/Deprecated/ToastContainer.vue +51 -0
- package/src/components/pgo/Deprecated/ToastItem.vue +55 -0
- package/src/components/pgo/Dropdown.vue +296 -0
- package/src/components/pgo/DropdownItem.vue +40 -0
- package/src/components/pgo/Editor.vue +511 -0
- package/src/components/pgo/ExpansionPanel.vue +185 -0
- package/src/components/pgo/Footer.vue +39 -0
- package/src/components/pgo/HeroIcon.vue +124 -0
- package/src/components/pgo/InputSearch.vue +194 -0
- package/src/components/pgo/LayoutContainer.vue +104 -0
- package/src/components/pgo/Main.vue +37 -0
- package/src/components/pgo/Modal.vue +273 -0
- package/src/components/pgo/NavDrawer.vue +127 -0
- package/src/components/pgo/NavDrawerItem.vue +161 -0
- package/src/components/pgo/NavigationDrawer.vue +849 -0
- package/src/components/pgo/OLDNavDrawer.vue +661 -0
- package/src/components/pgo/OldAppBar.vue +223 -0
- package/src/components/pgo/PApp.vue +102 -0
- package/src/components/pgo/Pagination.vue +242 -0
- package/src/components/pgo/Search copy.vue +310 -0
- package/src/components/pgo/Search.vue +411 -0
- package/src/components/pgo/StackedTableView.vue +167 -0
- package/src/components/pgo/Tab.vue +617 -0
- package/src/components/pgo/TestInput.vue +395 -0
- package/src/components/pgo/Timeline.vue +367 -0
- package/src/components/pgo/TimelineItem.vue +80 -0
- package/src/components/pgo/TipTapEditor.vue +315 -0
- package/src/components/pgo/Tooltip.NOTES.md +12 -0
- package/src/components/pgo/Tooltip.PROPS.md +21 -0
- package/src/components/pgo/Tooltip.vue +281 -0
- package/src/components/pgo/base/Base.vue +444 -0
- package/src/components/pgo/buttons/Chip.vue +324 -0
- package/src/components/pgo/buttons/ChipGroup.vue +224 -0
- package/src/components/pgo/buttons/Radio.vue +424 -0
- package/src/components/pgo/filters/FilterSection.vue +188 -0
- package/src/components/pgo/filters/Searchbar.vue +216 -0
- package/src/components/pgo/forms/DynamicForm.vue +45 -0
- package/src/components/pgo/forms/Form.vue +132 -0
- package/src/components/pgo/index.ts +15 -0
- package/src/components/pgo/inputs/Checkbox.vue +320 -0
- package/src/components/pgo/inputs/DatePicker.vue +395 -0
- package/src/components/pgo/inputs/FileUpload.vue +326 -0
- package/src/components/pgo/inputs/NumberField.vue +243 -0
- package/src/components/pgo/inputs/Radio.vue +162 -0
- package/src/components/pgo/inputs/RadioGroup.vue +188 -0
- package/src/components/pgo/inputs/Select.vue +535 -0
- package/src/components/pgo/inputs/TextField.vue +194 -0
- package/src/components/pgo/inputs/Textarea.vue +181 -0
- package/src/main.js +12 -0
- package/src/pgo-components/_index.js +31 -0
- package/src/pgo-components/assets/fonts/Faruma.ttf +0 -0
- package/src/pgo-components/assets/fonts/logo.png +0 -0
- package/src/pgo-components/composables/useTheme.js +10 -0
- package/src/pgo-components/directives/tooltip-directive.ts +393 -0
- package/src/pgo-components/index.js +96 -0
- package/src/pgo-components/lib/componentConfig.js +147 -0
- package/src/pgo-components/lib/core/composables/_useCalendar.ts +127 -0
- package/src/pgo-components/lib/core/composables/useDefaults.ts +15 -0
- package/src/pgo-components/lib/core/composables/useLanguageSelect.js +0 -0
- package/src/pgo-components/lib/core/composables/useRtl.ts +12 -0
- package/src/pgo-components/lib/core/defaults/createDefaults.ts +5 -0
- package/src/pgo-components/lib/core/defaults/defaults.ts +7 -0
- package/src/pgo-components/lib/core/rtl/rtl.ts +3 -0
- package/src/pgo-components/lib/core/rtl/setRtl.ts +19 -0
- package/src/pgo-components/lib/drawerState.ts +3 -0
- package/src/pgo-components/lib/i18n/defaultLables.js +71 -0
- package/src/pgo-components/lib/i18n/i18nPlugin.js +52 -0
- package/src/pgo-components/lib/i18n/useI18n.js +35 -0
- package/src/pgo-components/lib/index.ts +38 -0
- package/src/pgo-components/pages/Component.vue +7 -0
- package/src/pgo-components/pages/ComponentRenderer.vue +85 -0
- package/src/pgo-components/pages/Home.vue +130 -0
- package/src/pgo-components/pages/ListView.vue +370 -0
- package/src/pgo-components/pages/Page1.vue +296 -0
- package/src/pgo-components/pages/_Page1.vue +180 -0
- package/src/pgo-components/plugins/SnackBar.vue +251 -0
- package/src/pgo-components/plugins/SnackBarContainer.vue +53 -0
- package/src/pgo-components/plugins/SnackBarPlugin.ts +136 -0
- package/src/pgo-components/plugins/theme-plugin.js +114 -0
- package/src/pgo-components/plugins/types.ts +46 -0
- package/src/pgo-components/plugins/useSnackBar.js +11 -0
- package/src/pgo-components/plugins/useSnackBar.ts +21 -0
- package/src/pgo-components/plugins/validation-plugin.js +11 -0
- package/src/pgo-components/services/Entry.json +813 -0
- package/src/pgo-components/services/axios.js +54 -0
- package/src/pgo-components/services/data.json +90 -0
- package/src/pgo-components/services/person.json +260 -0
- package/src/pgo-components/services/toast.ts +44 -0
- package/src/pgo-components/styles/global.css +234 -0
- package/src/pgo-components/styles/reset.css +96 -0
- package/src/pgo-components/styles/tokens.css +18 -0
- package/src/pgo-components/styles/utilities/border-radius.css +57 -0
- package/src/pgo-components/styles/utilities/borders.css +85 -0
- package/src/pgo-components/styles/utilities/colors.css +38 -0
- package/src/pgo-components/styles/utilities/cursor.css +19 -0
- package/src/pgo-components/styles/utilities/display.css +78 -0
- package/src/pgo-components/styles/utilities/elevation.css +33 -0
- package/src/pgo-components/styles/utilities/flex.css +403 -0
- package/src/pgo-components/styles/utilities/float.css +41 -0
- package/src/pgo-components/styles/utilities/hover.css +9 -0
- package/src/pgo-components/styles/utilities/index.css +18 -0
- package/src/pgo-components/styles/utilities/opacity.css +27 -0
- package/src/pgo-components/styles/utilities/overflow.css +26 -0
- package/src/pgo-components/styles/utilities/palette.css +515 -0
- package/src/pgo-components/styles/utilities/position.css +14 -0
- package/src/pgo-components/styles/utilities/sizing.css +70 -0
- package/src/pgo-components/styles/utilities/spacing.css +578 -0
- package/src/pgo-components/styles/utilities/transitions.css +58 -0
- package/src/pgo-components/styles/utilities/typography.css +91 -0
- package/src/pgo-components/styles/utilities/z-index.css +11 -0
- package/src/pgo-components/tokens/index.js +337 -0
- package/src/router/index.js +88 -0
- package/src/shims-vue.d.ts +14 -0
- package/src/validations/validationRules.js +50 -0
- package/tailwind.config.js +73 -0
- package/test.php +5 -0
- package/tsconfig.json +25 -0
- package/ui +31 -0
- package/ui.pgo.mv.conf +18 -0
- package/vite.config.js +42 -0
package/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_API_BASE_URL=https://uiapi.pgo.mv/api
|
package/.env.production
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VITE_API_BASE_URL=https://your-production-api.com/api
|
package/.prettierrc
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"semi": false,
|
|
3
|
+
"singleQuote": true,
|
|
4
|
+
"useTabs": false,
|
|
5
|
+
"trailingComma": "none",
|
|
6
|
+
"printWidth": 140,
|
|
7
|
+
"vueIndentScriptAndStyle": true,
|
|
8
|
+
"htmlWhitespaceSensitivity": "ignore",
|
|
9
|
+
"singleAttributePerLine": false,
|
|
10
|
+
"arrowParens": "avoid",
|
|
11
|
+
"bracketSpacing": true,
|
|
12
|
+
"embeddedLanguageFormatting": "auto"
|
|
13
|
+
}
|
package/BUTTON_GUIDE.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Button Component Guide
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The Button component has been refactored to use **semantic theme tokens** instead of hardcoded colors. It now automatically adapts to any theme and switches between light/dark variants.
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
|------|------|---------|-------------|
|
|
11
|
+
| `variant` | String | `'contained'` | Button style: `'contained'` \| `'outlined'` \| `'text'` \| `'tonal'` \| `'plain'` |
|
|
12
|
+
| `color` | String | `'primary'` | Button color: `'primary'` \| `'secondary'` \| `'gray'` (or any other color) |
|
|
13
|
+
| `size` | String | `'md'` | Button size: `'xs'` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` |
|
|
14
|
+
| `rounded` | String | `'md'` | Border radius: `'none'` \| `'sm'` \| `'md'` \| `'lg'` \| `'xl'` \| `'full'` |
|
|
15
|
+
| `block` | Boolean | `false` | Full width button |
|
|
16
|
+
| `disabled` | Boolean | `false` | Disable button |
|
|
17
|
+
| `loading` | Boolean | `false` | Show loading state |
|
|
18
|
+
| `label` | String | `''` | Button label (supports i18n keys like `'buttons.submit'`) |
|
|
19
|
+
| `icon` | String | `''` | Icon name from HeroIcons |
|
|
20
|
+
| `prependIcon` | String | `''` | Icon before label |
|
|
21
|
+
| `appendIcon` | String | `''` | Icon after label |
|
|
22
|
+
| `padding` | Boolean | `false` | Custom padding (when using icon-only) |
|
|
23
|
+
| `lang` | String | `''` | Component-level language override |
|
|
24
|
+
|
|
25
|
+
## Usage Examples
|
|
26
|
+
|
|
27
|
+
### Basic Button
|
|
28
|
+
```vue
|
|
29
|
+
<Button color="primary">Click Me</Button>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Variants
|
|
33
|
+
|
|
34
|
+
#### Contained (default)
|
|
35
|
+
```vue
|
|
36
|
+
<Button color="primary" variant="contained">Contained</Button>
|
|
37
|
+
<Button color="secondary" variant="contained">Secondary</Button>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
#### Outlined
|
|
41
|
+
```vue
|
|
42
|
+
<Button color="primary" variant="outlined">Outlined</Button>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
#### Text
|
|
46
|
+
```vue
|
|
47
|
+
<Button color="primary" variant="text">Text Only</Button>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Tonal
|
|
51
|
+
```vue
|
|
52
|
+
<Button color="primary" variant="tonal">Tonal</Button>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### Plain
|
|
56
|
+
```vue
|
|
57
|
+
<Button color="primary" variant="plain">Plain</Button>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Sizes
|
|
61
|
+
```vue
|
|
62
|
+
<Button size="xs">Extra Small</Button>
|
|
63
|
+
<Button size="sm">Small</Button>
|
|
64
|
+
<Button size="md">Medium</Button>
|
|
65
|
+
<Button size="lg">Large</Button>
|
|
66
|
+
<Button size="xl">Extra Large</Button>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### With Icons
|
|
70
|
+
```vue
|
|
71
|
+
<Button prependIcon="heart">Add to Favorites</Button>
|
|
72
|
+
<Button appendIcon="arrow-right">Next</Button>
|
|
73
|
+
<Button icon="bell" padding />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### States
|
|
77
|
+
```vue
|
|
78
|
+
<Button disabled>Disabled</Button>
|
|
79
|
+
<Button loading>Loading...</Button>
|
|
80
|
+
<Button block>Full Width</Button>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Border Radius
|
|
84
|
+
```vue
|
|
85
|
+
<Button rounded="none">Sharp</Button>
|
|
86
|
+
<Button rounded="sm">Small Radius</Button>
|
|
87
|
+
<Button rounded="md">Medium Radius</Button>
|
|
88
|
+
<Button rounded="full">Pill Button</Button>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### With Custom Slots
|
|
92
|
+
```vue
|
|
93
|
+
<Button color="primary">
|
|
94
|
+
<template #prepend>
|
|
95
|
+
<CustomIcon />
|
|
96
|
+
</template>
|
|
97
|
+
Click Me
|
|
98
|
+
</Button>
|
|
99
|
+
|
|
100
|
+
<Button color="secondary">
|
|
101
|
+
<template #append>
|
|
102
|
+
<ArrowIcon />
|
|
103
|
+
</template>
|
|
104
|
+
Next Step
|
|
105
|
+
</Button>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Internationalization (i18n)
|
|
109
|
+
```vue
|
|
110
|
+
<!-- Uses 'buttons.submit' key from i18n -->
|
|
111
|
+
<Button label="buttons.submit" />
|
|
112
|
+
|
|
113
|
+
<!-- Direct label -->
|
|
114
|
+
<Button label="Click Me" />
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Theme Integration
|
|
118
|
+
|
|
119
|
+
### Color Mapping
|
|
120
|
+
|
|
121
|
+
The Button component automatically uses theme tokens:
|
|
122
|
+
|
|
123
|
+
| Color | Primary Token | Text Token |
|
|
124
|
+
|-------|---------------|-----------|
|
|
125
|
+
| `primary` | `--vts-color-primary` | `--vts-color-primaryText` |
|
|
126
|
+
| `secondary` | `--vts-color-secondary` | `--vts-color-secondaryText` |
|
|
127
|
+
| `gray` (default) | `--vts-color-surface` | `--vts-color-text` |
|
|
128
|
+
|
|
129
|
+
### Variant Styles
|
|
130
|
+
|
|
131
|
+
Each variant uses theme tokens:
|
|
132
|
+
|
|
133
|
+
- **Contained**: Solid background with primary color
|
|
134
|
+
- **Outlined**: Transparent background with colored border
|
|
135
|
+
- **Text**: No background, text only
|
|
136
|
+
- **Tonal**: Light background with text color
|
|
137
|
+
- **Plain**: Minimal styling, transparent background
|
|
138
|
+
|
|
139
|
+
### Border Radius
|
|
140
|
+
|
|
141
|
+
Uses theme radius tokens:
|
|
142
|
+
- `none` → `var(--vts-radius-none)`
|
|
143
|
+
- `sm` → `var(--vts-radius-sm)`
|
|
144
|
+
- `md` → `var(--vts-radius-md)` (default)
|
|
145
|
+
- `lg` → `var(--vts-radius-lg)`
|
|
146
|
+
- `xl` → `var(--vts-radius-xl)`
|
|
147
|
+
- `full` → `var(--vts-radius-full)`
|
|
148
|
+
|
|
149
|
+
### Dark Mode Support
|
|
150
|
+
|
|
151
|
+
Buttons automatically adjust colors when switching between light and dark themes because they use CSS variables from the theme system.
|
|
152
|
+
|
|
153
|
+
## Events
|
|
154
|
+
|
|
155
|
+
```vue
|
|
156
|
+
<Button @click="handleClick">Click Me</Button>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
The `click` event is emitted when the button is clicked (unless disabled or loading).
|
|
160
|
+
|
|
161
|
+
## Best Practices
|
|
162
|
+
|
|
163
|
+
✅ **Do:**
|
|
164
|
+
- Use semantic colors: `primary`, `secondary`, `gray`
|
|
165
|
+
- Leverage built-in variants for consistent styling
|
|
166
|
+
- Use `label` prop with i18n keys for internationalization
|
|
167
|
+
- Use icon props for consistent icon sizing
|
|
168
|
+
- Use `block` for full-width buttons when needed
|
|
169
|
+
|
|
170
|
+
❌ **Don't:**
|
|
171
|
+
- Override button styles with custom CSS classes
|
|
172
|
+
- Hardcode colors directly
|
|
173
|
+
- Use raw HTML buttons in examples; use the Button component instead
|
|
174
|
+
- Mix icon systems (use HeroIcons consistently)
|
|
175
|
+
|
|
176
|
+
## Complete Example
|
|
177
|
+
|
|
178
|
+
```vue
|
|
179
|
+
<template>
|
|
180
|
+
<div class="space-y-4 p-6">
|
|
181
|
+
<!-- Primary action -->
|
|
182
|
+
<Button color="primary" size="md">Save Changes</Button>
|
|
183
|
+
|
|
184
|
+
<!-- Secondary action -->
|
|
185
|
+
<Button color="secondary" variant="outlined">Cancel</Button>
|
|
186
|
+
|
|
187
|
+
<!-- With icons -->
|
|
188
|
+
<Button prependIcon="heart" color="primary">Add to Favorites</Button>
|
|
189
|
+
<Button appendIcon="arrow-right">Next Step</Button>
|
|
190
|
+
|
|
191
|
+
<!-- Different variants -->
|
|
192
|
+
<Button variant="text">Text Link</Button>
|
|
193
|
+
<Button variant="tonal" color="secondary">Info</Button>
|
|
194
|
+
|
|
195
|
+
<!-- States -->
|
|
196
|
+
<Button disabled>Disabled</Button>
|
|
197
|
+
<Button loading>Processing...</Button>
|
|
198
|
+
<Button block>Full Width Action</Button>
|
|
199
|
+
|
|
200
|
+
<!-- All sizes -->
|
|
201
|
+
<div class="space-x-2">
|
|
202
|
+
<Button size="xs">XS</Button>
|
|
203
|
+
<Button size="sm">SM</Button>
|
|
204
|
+
<Button size="md">MD</Button>
|
|
205
|
+
<Button size="lg">LG</Button>
|
|
206
|
+
<Button size="xl">XL</Button>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
</template>
|
|
210
|
+
|
|
211
|
+
<script setup>
|
|
212
|
+
import Button from '@/components/pgo/Button.vue'
|
|
213
|
+
</script>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Theme Customization
|
|
217
|
+
|
|
218
|
+
To customize button appearance globally, edit the theme tokens in `/src/tokens/index.js`:
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
export const themes = {
|
|
222
|
+
default: {
|
|
223
|
+
light: {
|
|
224
|
+
color: {
|
|
225
|
+
primary: '#0066ff', // Changes all primary buttons
|
|
226
|
+
primaryText: '#ffffff',
|
|
227
|
+
secondary: '#64748b', // Changes all secondary buttons
|
|
228
|
+
secondaryText: '#ffffff'
|
|
229
|
+
},
|
|
230
|
+
radius: {
|
|
231
|
+
md: '8px' // Default button border radius
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
No component-specific Button configuration needed! The Button component automatically uses the semantic tokens.
|
|
239
|
+
|
|
240
|
+
## Migration from Old Approach
|
|
241
|
+
|
|
242
|
+
### Before (hardcoded styles in example components)
|
|
243
|
+
```vue
|
|
244
|
+
<button :style="{
|
|
245
|
+
backgroundColor: '#0066ff',
|
|
246
|
+
color: 'white',
|
|
247
|
+
borderRadius: '8px',
|
|
248
|
+
padding: '0.5rem 1rem'
|
|
249
|
+
}">Click</button>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### After (use Button component)
|
|
253
|
+
```vue
|
|
254
|
+
<Button color="primary">Click</Button>
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Much cleaner and theme-aware! 🎉
|
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# uiux
|
|
2
|
+
|
|
3
|
+
This template should help get you started developing with Vue 3 in Vite.
|
|
4
|
+
|
|
5
|
+
## Recommended IDE Setup
|
|
6
|
+
|
|
7
|
+
[VS Code](https://code.visualstudio.com/) + [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
|
|
8
|
+
|
|
9
|
+
## Recommended Browser Setup
|
|
10
|
+
|
|
11
|
+
- Chromium-based browsers (Chrome, Edge, Brave, etc.):
|
|
12
|
+
- [Vue.js devtools](https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd)
|
|
13
|
+
- [Turn on Custom Object Formatter in Chrome DevTools](http://bit.ly/object-formatters)
|
|
14
|
+
- Firefox:
|
|
15
|
+
- [Vue.js devtools](https://addons.mozilla.org/en-US/firefox/addon/vue-js-devtools/)
|
|
16
|
+
- [Turn on Custom Object Formatter in Firefox DevTools](https://fxdx.dev/firefox-devtools-custom-object-formatters/)
|
|
17
|
+
|
|
18
|
+
## Customize configuration
|
|
19
|
+
|
|
20
|
+
See [Vite Configuration Reference](https://vite.dev/config/).
|
|
21
|
+
|
|
22
|
+
## Project Setup
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
npm install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Compile and Hot-Reload for Development
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npm run dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### New components
|
|
35
|
+
|
|
36
|
+
`NavDrawerItem` — A small wrapper to create consistent navigation items inside `NavDrawer`. Use it like:
|
|
37
|
+
|
|
38
|
+
```vue
|
|
39
|
+
<NavDrawerItem href="#/">
|
|
40
|
+
<HeroIcon name="home" /> Dashboard
|
|
41
|
+
</NavDrawerItem>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
### Compile and Minify for Production
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
npm run build
|
|
49
|
+
```
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Theme System Reference
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This project uses a **semantic token-based theme system** where components reference generic design tokens rather than component-specific keys. This approach ensures consistency and scalability across all components.
|
|
6
|
+
|
|
7
|
+
## CSS Variable Naming Convention
|
|
8
|
+
|
|
9
|
+
All theme tokens are converted to CSS variables with the prefix `--vts-`:
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Token path: color.text → CSS variable: --vts-color-text
|
|
13
|
+
Token path: shadow.md → CSS variable: --vts-shadow-md
|
|
14
|
+
Token path: elevation.2 → CSS variable: --vts-elevation-2
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Available Semantic Tokens
|
|
18
|
+
|
|
19
|
+
### Color Tokens
|
|
20
|
+
|
|
21
|
+
Use these for ALL components (no component-specific color keys needed):
|
|
22
|
+
|
|
23
|
+
| Token | CSS Variable | Usage |
|
|
24
|
+
|-------|-------------|--------|
|
|
25
|
+
| `color.text` | `--vts-color-text` | Primary text color |
|
|
26
|
+
| `color.textSecondary` | `--vts-color-text-secondary` | Secondary/muted text |
|
|
27
|
+
| `color.background` | `--vts-color-background` | Page background |
|
|
28
|
+
| `color.surface` | `--vts-color-surface` | Card/panel backgrounds |
|
|
29
|
+
| `color.surfaceElevated` | `--vts-color-surface-elevated` | Elevated surfaces (AppBar, modals) |
|
|
30
|
+
| `color.primary` | `--vts-color-primary` | Primary brand color |
|
|
31
|
+
| `color.primaryText` | `--vts-color-primary-text` | Text on primary color |
|
|
32
|
+
| `color.secondary` | `--vts-color-secondary` | Secondary brand color |
|
|
33
|
+
| `color.border` | `--vts-color-border` | Default borders |
|
|
34
|
+
| `color.borderLight` | `--vts-color-border-light` | Subtle borders |
|
|
35
|
+
| `color.borderHeavy` | `--vts-color-border-heavy` | Emphasized borders |
|
|
36
|
+
| `color.divider` | `--vts-color-divider` | Divider lines |
|
|
37
|
+
| `color.overlay` | `--vts-color-overlay` | Modal/dialog overlays |
|
|
38
|
+
| `color.success` | `--vts-color-success` | Success states |
|
|
39
|
+
| `color.warning` | `--vts-color-warning` | Warning states |
|
|
40
|
+
| `color.error` | `--vts-color-error` | Error states |
|
|
41
|
+
| `color.info` | `--vts-color-info` | Info states |
|
|
42
|
+
|
|
43
|
+
### Border Radius Tokens
|
|
44
|
+
|
|
45
|
+
| Token | CSS Variable | Usage |
|
|
46
|
+
|-------|-------------|--------|
|
|
47
|
+
| `radius.sm` | `--vts-radius-sm` | Small radius (buttons, chips) |
|
|
48
|
+
| `radius.md` | `--vts-radius-md` | Medium radius (cards, inputs) |
|
|
49
|
+
| `radius.lg` | `--vts-radius-lg` | Large radius (modals) |
|
|
50
|
+
| `radius.xl` | `--vts-radius-xl` | Extra large radius |
|
|
51
|
+
| `radius.full` | `--vts-radius-full` | Fully rounded (pills, avatars) |
|
|
52
|
+
|
|
53
|
+
### Shadow Tokens
|
|
54
|
+
|
|
55
|
+
| Token | CSS Variable | Usage |
|
|
56
|
+
|-------|-------------|--------|
|
|
57
|
+
| `shadow.sm` | `--vts-shadow-sm` | Small shadow |
|
|
58
|
+
| `shadow.md` | `--vts-shadow-md` | Medium shadow (default) |
|
|
59
|
+
| `shadow.lg` | `--vts-shadow-lg` | Large shadow (cards) |
|
|
60
|
+
| `shadow.xl` | `--vts-shadow-xl` | Extra large shadow (modals) |
|
|
61
|
+
|
|
62
|
+
### Elevation Tokens
|
|
63
|
+
|
|
64
|
+
Elevations provide consistent shadow levels:
|
|
65
|
+
|
|
66
|
+
| Token | CSS Variable | Usage |
|
|
67
|
+
|-------|-------------|--------|
|
|
68
|
+
| `elevation.0` | `--vts-elevation-0` | No elevation |
|
|
69
|
+
| `elevation.1` | `--vts-elevation-1` | Slight elevation |
|
|
70
|
+
| `elevation.2` | `--vts-elevation-2` | Medium elevation (AppBar) |
|
|
71
|
+
| `elevation.3` | `--vts-elevation-3` | High elevation (floating) |
|
|
72
|
+
| `elevation.4` | `--vts-elevation-4` | Maximum elevation (modals) |
|
|
73
|
+
|
|
74
|
+
## Component Examples
|
|
75
|
+
|
|
76
|
+
### AppBar (Updated Example)
|
|
77
|
+
|
|
78
|
+
```vue
|
|
79
|
+
<script setup>
|
|
80
|
+
import { computed } from 'vue'
|
|
81
|
+
|
|
82
|
+
const props = defineProps({
|
|
83
|
+
elevation: { type: Number, default: 2 }
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const themeStyles = computed(() => ({
|
|
87
|
+
backgroundColor: 'var(--vts-color-surface-elevated)',
|
|
88
|
+
color: 'var(--vts-color-text)',
|
|
89
|
+
boxShadow: `var(--vts-elevation-${props.elevation})`,
|
|
90
|
+
borderBottom: '1px solid var(--vts-color-border)'
|
|
91
|
+
}))
|
|
92
|
+
</script>
|
|
93
|
+
|
|
94
|
+
<template>
|
|
95
|
+
<header :style="themeStyles">
|
|
96
|
+
<!-- content -->
|
|
97
|
+
</header>
|
|
98
|
+
</template>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Card Component
|
|
102
|
+
|
|
103
|
+
```vue
|
|
104
|
+
<script setup>
|
|
105
|
+
const cardStyles = computed(() => ({
|
|
106
|
+
backgroundColor: 'var(--vts-color-surface)',
|
|
107
|
+
color: 'var(--vts-color-text)',
|
|
108
|
+
borderRadius: 'var(--vts-radius-md)',
|
|
109
|
+
boxShadow: 'var(--vts-shadow-md)',
|
|
110
|
+
border: '1px solid var(--vts-color-border-light)'
|
|
111
|
+
}))
|
|
112
|
+
</script>
|
|
113
|
+
|
|
114
|
+
<template>
|
|
115
|
+
<div :style="cardStyles">
|
|
116
|
+
<slot />
|
|
117
|
+
</div>
|
|
118
|
+
</template>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Button Component
|
|
122
|
+
|
|
123
|
+
```vue
|
|
124
|
+
<script setup>
|
|
125
|
+
const props = defineProps({
|
|
126
|
+
variant: { type: String, default: 'primary' }
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
const buttonStyles = computed(() => {
|
|
130
|
+
if (props.variant === 'primary') {
|
|
131
|
+
return {
|
|
132
|
+
backgroundColor: 'var(--vts-color-primary)',
|
|
133
|
+
color: 'var(--vts-color-primary-text)',
|
|
134
|
+
borderRadius: 'var(--vts-radius-sm)'
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
backgroundColor: 'var(--vts-color-surface)',
|
|
139
|
+
color: 'var(--vts-color-text)',
|
|
140
|
+
border: '1px solid var(--vts-color-border)',
|
|
141
|
+
borderRadius: 'var(--vts-radius-sm)'
|
|
142
|
+
}
|
|
143
|
+
})
|
|
144
|
+
</script>
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Modal Component
|
|
148
|
+
|
|
149
|
+
```vue
|
|
150
|
+
<script setup>
|
|
151
|
+
const modalStyles = computed(() => ({
|
|
152
|
+
backgroundColor: 'var(--vts-color-surface-elevated)',
|
|
153
|
+
color: 'var(--vts-color-text)',
|
|
154
|
+
borderRadius: 'var(--vts-radius-lg)',
|
|
155
|
+
boxShadow: 'var(--vts-elevation-4)'
|
|
156
|
+
}))
|
|
157
|
+
|
|
158
|
+
const overlayStyles = computed(() => ({
|
|
159
|
+
backgroundColor: 'var(--vts-color-overlay)'
|
|
160
|
+
}))
|
|
161
|
+
</script>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Input Component
|
|
165
|
+
|
|
166
|
+
```vue
|
|
167
|
+
<script setup>
|
|
168
|
+
const inputStyles = computed(() => ({
|
|
169
|
+
backgroundColor: 'var(--vts-color-surface)',
|
|
170
|
+
color: 'var(--vts-color-text)',
|
|
171
|
+
border: '1px solid var(--vts-color-border)',
|
|
172
|
+
borderRadius: 'var(--vts-radius-sm)'
|
|
173
|
+
}))
|
|
174
|
+
|
|
175
|
+
const focusStyles = {
|
|
176
|
+
borderColor: 'var(--vts-color-primary)'
|
|
177
|
+
}
|
|
178
|
+
</script>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Divider Component
|
|
182
|
+
|
|
183
|
+
```vue
|
|
184
|
+
<template>
|
|
185
|
+
<hr :style="{
|
|
186
|
+
borderTop: '1px solid var(--vts-color-divider)',
|
|
187
|
+
margin: '16px 0'
|
|
188
|
+
}" />
|
|
189
|
+
</template>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Best Practices
|
|
193
|
+
|
|
194
|
+
### ✅ DO
|
|
195
|
+
|
|
196
|
+
- **Use semantic tokens** for all component styling
|
|
197
|
+
- **Reference elevation levels** for consistent shadows
|
|
198
|
+
- **Use surface tokens** for backgrounds (surface, surfaceElevated)
|
|
199
|
+
- **Use border variants** based on emphasis (border, borderLight, borderHeavy)
|
|
200
|
+
- **Use state colors** for feedback (success, warning, error, info)
|
|
201
|
+
|
|
202
|
+
```vue
|
|
203
|
+
// ✅ Good
|
|
204
|
+
const styles = {
|
|
205
|
+
backgroundColor: 'var(--vts-color-surface)',
|
|
206
|
+
border: '1px solid var(--vts-color-border)',
|
|
207
|
+
boxShadow: 'var(--vts-elevation-2)'
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### ❌ DON'T
|
|
212
|
+
|
|
213
|
+
- **Don't create component-specific color keys** in theme tokens
|
|
214
|
+
- **Don't hardcode colors** in components
|
|
215
|
+
- **Don't use arbitrary shadow values** - use elevation levels
|
|
216
|
+
|
|
217
|
+
```vue
|
|
218
|
+
// ❌ Bad - component-specific theme key
|
|
219
|
+
const styles = {
|
|
220
|
+
backgroundColor: 'var(--vts-my-component-background)', // Don't do this
|
|
221
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.1)' // Use elevation instead
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// ❌ Bad - hardcoded color
|
|
225
|
+
const styles = {
|
|
226
|
+
backgroundColor: '#ffffff', // Use token instead
|
|
227
|
+
color: '#000000'
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Adding New Themes
|
|
232
|
+
|
|
233
|
+
When creating a new theme, only define these semantic tokens:
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
export const themes = {
|
|
237
|
+
myNewTheme: {
|
|
238
|
+
light: {
|
|
239
|
+
color: {
|
|
240
|
+
text: '...',
|
|
241
|
+
textSecondary: '...',
|
|
242
|
+
background: '...',
|
|
243
|
+
surface: '...',
|
|
244
|
+
surfaceElevated: '...',
|
|
245
|
+
primary: '...',
|
|
246
|
+
primaryText: '...',
|
|
247
|
+
border: '...',
|
|
248
|
+
// ... all semantic colors
|
|
249
|
+
},
|
|
250
|
+
radius: { sm: '...', md: '...', lg: '...', xl: '...', full: '...' },
|
|
251
|
+
shadow: { sm: '...', md: '...', lg: '...', xl: '...' },
|
|
252
|
+
elevation: { 0: 'none', 1: '...', 2: '...', 3: '...', 4: '...' }
|
|
253
|
+
},
|
|
254
|
+
dark: {
|
|
255
|
+
// Same structure
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**No component-specific keys needed!** All components reference the same semantic tokens.
|
|
262
|
+
|
|
263
|
+
## Migration Guide
|
|
264
|
+
|
|
265
|
+
If you have existing components using component-specific tokens:
|
|
266
|
+
|
|
267
|
+
### Before (component-specific):
|
|
268
|
+
```javascript
|
|
269
|
+
// tokens/index.js
|
|
270
|
+
appBar: {
|
|
271
|
+
background: '#ffffff',
|
|
272
|
+
text: '#000000',
|
|
273
|
+
border: 'rgba(0,0,0,0.1)'
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// AppBar.vue
|
|
277
|
+
const styles = {
|
|
278
|
+
backgroundColor: 'var(--app-bar-background)'
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### After (semantic):
|
|
283
|
+
```javascript
|
|
284
|
+
// tokens/index.js - no appBar key needed!
|
|
285
|
+
color: {
|
|
286
|
+
surfaceElevated: '#ffffff',
|
|
287
|
+
text: '#000000',
|
|
288
|
+
border: 'rgba(0,0,0,0.1)'
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// AppBar.vue
|
|
292
|
+
const styles = {
|
|
293
|
+
backgroundColor: 'var(--vts-color-surface-elevated)'
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## Benefits
|
|
298
|
+
|
|
299
|
+
1. **Consistency**: All components use the same design language
|
|
300
|
+
2. **Scalability**: Add new components without adding theme keys
|
|
301
|
+
3. **Maintainability**: Update colors in one place, affects all components
|
|
302
|
+
4. **Smaller bundle**: No duplicate theme definitions per component
|
|
303
|
+
5. **Flexibility**: Switch themes without updating components
|
|
304
|
+
6. **Type safety**: Predictable token structure
|
|
305
|
+
|
|
306
|
+
## Questions?
|
|
307
|
+
|
|
308
|
+
- Want a specific semantic token? Consider adding it to the base theme rather than creating a component-specific key
|
|
309
|
+
- Need component-specific behavior? Use props and computed styles, not theme tokens
|
|
310
|
+
- Unsure which token to use? Check this reference guide!
|
package/eslint.config.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import vue from 'eslint-plugin-vue'
|
|
2
|
+
|
|
3
|
+
export default [
|
|
4
|
+
...vue.configs['flat/recommended'],
|
|
5
|
+
|
|
6
|
+
{
|
|
7
|
+
files: ['**/*.vue'],
|
|
8
|
+
plugins: { vue },
|
|
9
|
+
rules: {
|
|
10
|
+
'vue/block-order': [
|
|
11
|
+
'error',
|
|
12
|
+
{
|
|
13
|
+
order: ['template', 'script', 'style']
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
'vue/max-attributes-per-line': 'off',
|
|
17
|
+
'vue/attributes-order': 'off',
|
|
18
|
+
'vue/multi-word-component-names': 'off',
|
|
19
|
+
'vue/opening-bracket-newline': 'off',
|
|
20
|
+
'vue/closing-bracket-newline': 'off',
|
|
21
|
+
'vue/jsx-opening-bracket-newline': 'off',
|
|
22
|
+
'vue/jsx-closing-bracket-newline': 'off',
|
|
23
|
+
'vue/singleline-html-element-content-newline': 'off',
|
|
24
|
+
'vue/multiline-html-element-content-newline': 'off'
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
]
|
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="" class="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<link rel="icon" href="/favicon.ico">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
|
+
<title>Vite App</title>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module" src="/src/main.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|