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.
Files changed (180) hide show
  1. package/.env +1 -0
  2. package/.env.production +1 -0
  3. package/.prettierrc +13 -0
  4. package/.vscode/extensions.json +3 -0
  5. package/BUTTON_GUIDE.md +257 -0
  6. package/README.md +49 -0
  7. package/THEME_REFERENCE.md +310 -0
  8. package/eslint.config.ts +27 -0
  9. package/index.html +13 -0
  10. package/package.json +85 -0
  11. package/public/favicon.ico +0 -0
  12. package/src/App.vue +368 -0
  13. package/src/assets/fonts/Faruma.ttf +0 -0
  14. package/src/components/examples/AppBarExample.vue +101 -0
  15. package/src/components/examples/AvatarExample.vue +47 -0
  16. package/src/components/examples/BannerExample.vue +287 -0
  17. package/src/components/examples/BaseInputExample.vue +25 -0
  18. package/src/components/examples/BreadcrumbExample.vue +53 -0
  19. package/src/components/examples/CardExample.vue +77 -0
  20. package/src/components/examples/ChipExample.vue +225 -0
  21. package/src/components/examples/DatePickerExample.vue +31 -0
  22. package/src/components/examples/DropdownExample.vue +84 -0
  23. package/src/components/examples/EditorExample.vue +200 -0
  24. package/src/components/examples/ExpansionPanelExample.vue +42 -0
  25. package/src/components/examples/FileUploadExample.vue +40 -0
  26. package/src/components/examples/FormExample.vue +121 -0
  27. package/src/components/examples/HugeTest.vue +8 -0
  28. package/src/components/examples/LayoutContainerExample.vue +80 -0
  29. package/src/components/examples/ModalExample.vue +82 -0
  30. package/src/components/examples/NavDrawerExample.vue +170 -0
  31. package/src/components/examples/NumberFieldExample.vue +145 -0
  32. package/src/components/examples/RadioButtonExample.vue +161 -0
  33. package/src/components/examples/SearchExample.vue +322 -0
  34. package/src/components/examples/SelectExample.vue +121 -0
  35. package/src/components/examples/StackedTableViewExample.vue +53 -0
  36. package/src/components/examples/TabExample.vue +336 -0
  37. package/src/components/examples/TableExample.vue +228 -0
  38. package/src/components/examples/TextFieldExample.vue +181 -0
  39. package/src/components/examples/TextareaExample.vue +173 -0
  40. package/src/components/examples/ThemeToggle.vue +50 -0
  41. package/src/components/examples/TimelineExample.vue +66 -0
  42. package/src/components/examples/TipTapEditorExample.vue +20 -0
  43. package/src/components/examples/TooltipExample.vue +53 -0
  44. package/src/components/examples/VueDatePickerShowcase.vue +214 -0
  45. package/src/components/examples/_DatePickerExample.vue +33 -0
  46. package/src/components/examples/__FormExample.vue +77 -0
  47. package/src/components/index.ts +25 -0
  48. package/src/components/pgo/AppBar.vue +347 -0
  49. package/src/components/pgo/Avatar.vue +139 -0
  50. package/src/components/pgo/Banner.vue +300 -0
  51. package/src/components/pgo/Breadcrumb.vue +101 -0
  52. package/src/components/pgo/Button.vue +171 -0
  53. package/src/components/pgo/Card.vue +178 -0
  54. package/src/components/pgo/ConfirmationModel.vue +32 -0
  55. package/src/components/pgo/DataTable.vue +845 -0
  56. package/src/components/pgo/DatePicker/CalendarPanel.vue +43 -0
  57. package/src/components/pgo/DatePicker/__DatePicker.vue +122 -0
  58. package/src/components/pgo/DatePicker/types.ts +11 -0
  59. package/src/components/pgo/DatePicker/useCalendar.ts +39 -0
  60. package/src/components/pgo/DatePicker/useDatePicker.ts +31 -0
  61. package/src/components/pgo/Deprecated/ToastContainer.vue +51 -0
  62. package/src/components/pgo/Deprecated/ToastItem.vue +55 -0
  63. package/src/components/pgo/Dropdown.vue +296 -0
  64. package/src/components/pgo/DropdownItem.vue +40 -0
  65. package/src/components/pgo/Editor.vue +511 -0
  66. package/src/components/pgo/ExpansionPanel.vue +185 -0
  67. package/src/components/pgo/Footer.vue +39 -0
  68. package/src/components/pgo/HeroIcon.vue +124 -0
  69. package/src/components/pgo/InputSearch.vue +194 -0
  70. package/src/components/pgo/LayoutContainer.vue +104 -0
  71. package/src/components/pgo/Main.vue +37 -0
  72. package/src/components/pgo/Modal.vue +273 -0
  73. package/src/components/pgo/NavDrawer.vue +127 -0
  74. package/src/components/pgo/NavDrawerItem.vue +161 -0
  75. package/src/components/pgo/NavigationDrawer.vue +849 -0
  76. package/src/components/pgo/OLDNavDrawer.vue +661 -0
  77. package/src/components/pgo/OldAppBar.vue +223 -0
  78. package/src/components/pgo/PApp.vue +102 -0
  79. package/src/components/pgo/Pagination.vue +242 -0
  80. package/src/components/pgo/Search copy.vue +310 -0
  81. package/src/components/pgo/Search.vue +411 -0
  82. package/src/components/pgo/StackedTableView.vue +167 -0
  83. package/src/components/pgo/Tab.vue +617 -0
  84. package/src/components/pgo/TestInput.vue +395 -0
  85. package/src/components/pgo/Timeline.vue +367 -0
  86. package/src/components/pgo/TimelineItem.vue +80 -0
  87. package/src/components/pgo/TipTapEditor.vue +315 -0
  88. package/src/components/pgo/Tooltip.NOTES.md +12 -0
  89. package/src/components/pgo/Tooltip.PROPS.md +21 -0
  90. package/src/components/pgo/Tooltip.vue +281 -0
  91. package/src/components/pgo/base/Base.vue +444 -0
  92. package/src/components/pgo/buttons/Chip.vue +324 -0
  93. package/src/components/pgo/buttons/ChipGroup.vue +224 -0
  94. package/src/components/pgo/buttons/Radio.vue +424 -0
  95. package/src/components/pgo/filters/FilterSection.vue +188 -0
  96. package/src/components/pgo/filters/Searchbar.vue +216 -0
  97. package/src/components/pgo/forms/DynamicForm.vue +45 -0
  98. package/src/components/pgo/forms/Form.vue +132 -0
  99. package/src/components/pgo/index.ts +15 -0
  100. package/src/components/pgo/inputs/Checkbox.vue +320 -0
  101. package/src/components/pgo/inputs/DatePicker.vue +395 -0
  102. package/src/components/pgo/inputs/FileUpload.vue +326 -0
  103. package/src/components/pgo/inputs/NumberField.vue +243 -0
  104. package/src/components/pgo/inputs/Radio.vue +162 -0
  105. package/src/components/pgo/inputs/RadioGroup.vue +188 -0
  106. package/src/components/pgo/inputs/Select.vue +535 -0
  107. package/src/components/pgo/inputs/TextField.vue +194 -0
  108. package/src/components/pgo/inputs/Textarea.vue +181 -0
  109. package/src/main.js +12 -0
  110. package/src/pgo-components/_index.js +31 -0
  111. package/src/pgo-components/assets/fonts/Faruma.ttf +0 -0
  112. package/src/pgo-components/assets/fonts/logo.png +0 -0
  113. package/src/pgo-components/composables/useTheme.js +10 -0
  114. package/src/pgo-components/directives/tooltip-directive.ts +393 -0
  115. package/src/pgo-components/index.js +96 -0
  116. package/src/pgo-components/lib/componentConfig.js +147 -0
  117. package/src/pgo-components/lib/core/composables/_useCalendar.ts +127 -0
  118. package/src/pgo-components/lib/core/composables/useDefaults.ts +15 -0
  119. package/src/pgo-components/lib/core/composables/useLanguageSelect.js +0 -0
  120. package/src/pgo-components/lib/core/composables/useRtl.ts +12 -0
  121. package/src/pgo-components/lib/core/defaults/createDefaults.ts +5 -0
  122. package/src/pgo-components/lib/core/defaults/defaults.ts +7 -0
  123. package/src/pgo-components/lib/core/rtl/rtl.ts +3 -0
  124. package/src/pgo-components/lib/core/rtl/setRtl.ts +19 -0
  125. package/src/pgo-components/lib/drawerState.ts +3 -0
  126. package/src/pgo-components/lib/i18n/defaultLables.js +71 -0
  127. package/src/pgo-components/lib/i18n/i18nPlugin.js +52 -0
  128. package/src/pgo-components/lib/i18n/useI18n.js +35 -0
  129. package/src/pgo-components/lib/index.ts +38 -0
  130. package/src/pgo-components/pages/Component.vue +7 -0
  131. package/src/pgo-components/pages/ComponentRenderer.vue +85 -0
  132. package/src/pgo-components/pages/Home.vue +130 -0
  133. package/src/pgo-components/pages/ListView.vue +370 -0
  134. package/src/pgo-components/pages/Page1.vue +296 -0
  135. package/src/pgo-components/pages/_Page1.vue +180 -0
  136. package/src/pgo-components/plugins/SnackBar.vue +251 -0
  137. package/src/pgo-components/plugins/SnackBarContainer.vue +53 -0
  138. package/src/pgo-components/plugins/SnackBarPlugin.ts +136 -0
  139. package/src/pgo-components/plugins/theme-plugin.js +114 -0
  140. package/src/pgo-components/plugins/types.ts +46 -0
  141. package/src/pgo-components/plugins/useSnackBar.js +11 -0
  142. package/src/pgo-components/plugins/useSnackBar.ts +21 -0
  143. package/src/pgo-components/plugins/validation-plugin.js +11 -0
  144. package/src/pgo-components/services/Entry.json +813 -0
  145. package/src/pgo-components/services/axios.js +54 -0
  146. package/src/pgo-components/services/data.json +90 -0
  147. package/src/pgo-components/services/person.json +260 -0
  148. package/src/pgo-components/services/toast.ts +44 -0
  149. package/src/pgo-components/styles/global.css +234 -0
  150. package/src/pgo-components/styles/reset.css +96 -0
  151. package/src/pgo-components/styles/tokens.css +18 -0
  152. package/src/pgo-components/styles/utilities/border-radius.css +57 -0
  153. package/src/pgo-components/styles/utilities/borders.css +85 -0
  154. package/src/pgo-components/styles/utilities/colors.css +38 -0
  155. package/src/pgo-components/styles/utilities/cursor.css +19 -0
  156. package/src/pgo-components/styles/utilities/display.css +78 -0
  157. package/src/pgo-components/styles/utilities/elevation.css +33 -0
  158. package/src/pgo-components/styles/utilities/flex.css +403 -0
  159. package/src/pgo-components/styles/utilities/float.css +41 -0
  160. package/src/pgo-components/styles/utilities/hover.css +9 -0
  161. package/src/pgo-components/styles/utilities/index.css +18 -0
  162. package/src/pgo-components/styles/utilities/opacity.css +27 -0
  163. package/src/pgo-components/styles/utilities/overflow.css +26 -0
  164. package/src/pgo-components/styles/utilities/palette.css +515 -0
  165. package/src/pgo-components/styles/utilities/position.css +14 -0
  166. package/src/pgo-components/styles/utilities/sizing.css +70 -0
  167. package/src/pgo-components/styles/utilities/spacing.css +578 -0
  168. package/src/pgo-components/styles/utilities/transitions.css +58 -0
  169. package/src/pgo-components/styles/utilities/typography.css +91 -0
  170. package/src/pgo-components/styles/utilities/z-index.css +11 -0
  171. package/src/pgo-components/tokens/index.js +337 -0
  172. package/src/router/index.js +88 -0
  173. package/src/shims-vue.d.ts +14 -0
  174. package/src/validations/validationRules.js +50 -0
  175. package/tailwind.config.js +73 -0
  176. package/test.php +5 -0
  177. package/tsconfig.json +25 -0
  178. package/ui +31 -0
  179. package/ui.pgo.mv.conf +18 -0
  180. package/vite.config.js +42 -0
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div class="example-component p-6">
3
+ <h2 class="mb-4 text-lg font-semibold">
4
+ Vue 3 DatePicker Example
5
+ </h2>
6
+
7
+ <DatePicker
8
+ v-model="selectedDate"
9
+ format="yyyy-MM-dd"
10
+ :clearable="true"
11
+ placeholder="Select a date"
12
+ />
13
+
14
+ <p class="mt-4">
15
+ Selected date: {{ selectedDate ? selectedDate.toDateString() : 'None' }}
16
+ </p>
17
+ </div>
18
+ </template>
19
+
20
+ <script setup lang="ts">
21
+ import { ref } from 'vue'
22
+ import DatePicker from '../pgo/inputs/DatePicker.vue'
23
+
24
+ const selectedDate = ref<Date | null>(null)
25
+ </script>
26
+
27
+ <style scoped>
28
+ .example-component {
29
+ font-family: system-ui, sans-serif;
30
+ }
31
+ </style>
@@ -0,0 +1,84 @@
1
+ <template>
2
+ <div class="p-6 max-w-4xl mx-auto space-y-8">
3
+ <h2 class="text-3xl font-bold text-gray-800 mb-6">Dropdown Components</h2>
4
+
5
+ <Card title="Dropdown Examples" class="space-y-6">
6
+ <div class="flex items-center gap-4 flex-wrap">
7
+ <!-- Basic Dropdown with items prop -->
8
+ <Dropdown label="Select Option" :items="items" @select="handleSelect" />
9
+ <Dropdown variant="outlined" color="success" label="Select Option" :items="items" @select="handleSelect" />
10
+
11
+ <!-- Custom trigger -->
12
+ <Dropdown :items="items" @select="handleSelect">
13
+ <template #trigger>
14
+ <button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
15
+ Custom Trigger
16
+ </button>
17
+ </template>
18
+ </Dropdown>
19
+
20
+ <!-- With custom content -->
21
+ <Dropdown label="Actions" align="right">
22
+ <DropdownItem @select="edit">
23
+ <template #prepend>📝</template>
24
+ Edit
25
+ </DropdownItem>
26
+ <DropdownItem @select="view">
27
+ <template #prepend>👁️</template>
28
+ View
29
+ </DropdownItem>
30
+ <div class="border-t my-1"></div>
31
+ <DropdownItem @select="remove">
32
+ <template #prepend>🗑️</template>
33
+ Delete
34
+ </DropdownItem>
35
+ </Dropdown>
36
+
37
+ <!-- Dense variant -->
38
+ <Dropdown label="Dense Menu" dense :items="items" @select="handleSelect" />
39
+
40
+ <!-- Open on hover -->
41
+ <Dropdown label="Hover Menu" open-on-hover :items="items" @select="handleSelect" />
42
+
43
+ <!-- Right aligned -->
44
+ <Dropdown label="Right Aligned" align="right" :items="items" @select="handleSelect" />
45
+ </div>
46
+
47
+ <div class="mt-4 p-4 bg-gray-100 rounded">
48
+ <p class="text-sm font-medium">Selected: {{ selectedItem || 'None' }}</p>
49
+ </div>
50
+ </Card>
51
+ </div>
52
+ </template>
53
+
54
+ <script setup>
55
+ import { ref } from 'vue'
56
+ import Card from '../pgo/Card.vue'
57
+ import Dropdown from '../pgo/Dropdown.vue'
58
+ import DropdownItem from '../pgo/DropdownItem.vue'
59
+
60
+ const selectedItem = ref(null)
61
+
62
+ const items = [
63
+ { label: 'Profile', value: 'profile' },
64
+ { label: 'Settings', value: 'settings' },
65
+ { label: 'Logout', value: 'logout' }
66
+ ]
67
+
68
+ const handleSelect = (item) => {
69
+ selectedItem.value = item.label || item
70
+ console.log('Selected:', item)
71
+ }
72
+
73
+ const edit = () => {
74
+ console.log('Edit clicked')
75
+ }
76
+
77
+ const view = () => {
78
+ console.log('View clicked')
79
+ }
80
+
81
+ const remove = () => {
82
+ console.log('Delete clicked')
83
+ }
84
+ </script>
@@ -0,0 +1,200 @@
1
+ <template>
2
+ <div class="space-y-6">
3
+ <!-- Header -->
4
+ <div>
5
+ <h2 class="text-2xl font-bold mb-2">Rich Text Editor Demo</h2>
6
+ <p class="text-gray-600 dark:text-gray-400">A full-featured rich text editor with formatting, tables, and HTML editing</p>
7
+ </div>
8
+
9
+ <!-- Controls Section -->
10
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4 p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
11
+ <div>
12
+ <label class="block text-sm font-medium mb-2">Character Limit:</label>
13
+ <input
14
+ v-model.number="characterLimit"
15
+ type="number"
16
+ class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-900"
17
+ min="0"
18
+ placeholder="Leave empty for no limit"
19
+ />
20
+ </div>
21
+
22
+ <div>
23
+ <label class="flex items-center gap-2 cursor-pointer">
24
+ <input v-model="stickyToolbar" type="checkbox" class="w-4 h-4" />
25
+ <span class="text-sm font-medium">Sticky Toolbar</span>
26
+ </label>
27
+ </div>
28
+
29
+ <div>
30
+ <label class="flex items-center gap-2 cursor-pointer">
31
+ <input v-model="allowHtmlEdit" type="checkbox" class="w-4 h-4" />
32
+ <span class="text-sm font-medium">Allow HTML Editing</span>
33
+ </label>
34
+ </div>
35
+
36
+ <div class="flex gap-2">
37
+ <button
38
+ @click="loadSampleContent"
39
+ class="px-3 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded font-medium transition"
40
+ >
41
+ Load Sample
42
+ </button>
43
+ <button
44
+ @click="clearEditor"
45
+ class="px-3 py-2 bg-red-600 hover:bg-red-700 text-white rounded font-medium transition"
46
+ >
47
+ Clear All
48
+ </button>
49
+ </div>
50
+ </div>
51
+
52
+ <!-- Editor Instance -->
53
+ <div>
54
+ <h3 class="text-lg font-semibold mb-3">Editor</h3>
55
+ <Editor
56
+ v-model="content"
57
+ :maximum-length="characterLimit || null"
58
+ :can-edit-html="allowHtmlEdit"
59
+ :sticky-toolbar="stickyToolbar"
60
+ @limitReached="onLimitReached"
61
+ @limitOk="onLimitOk"
62
+ />
63
+ </div>
64
+
65
+ <!-- Status and Information -->
66
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
67
+ <!-- Content Info -->
68
+ <div class="p-4 bg-blue-50 dark:bg-blue-900/30 rounded-lg border border-blue-200 dark:border-blue-800">
69
+ <h4 class="font-semibold mb-2 text-blue-900 dark:text-blue-100">Content Status</h4>
70
+ <div class="space-y-1 text-sm text-blue-800 dark:text-blue-200">
71
+ <p><strong>Characters:</strong> {{ editorCharCount }}</p>
72
+ <p v-if="characterLimit">
73
+ <strong>Limit:</strong> {{ characterLimit }}
74
+ <span v-if="isAtLimit" class="text-red-600 dark:text-red-400 font-medium ml-2">⚠ LIMIT REACHED</span>
75
+ </p>
76
+ <p><strong>Status:</strong> {{ isAtLimit ? '❌ Limit reached' : '✅ Within limit' }}</p>
77
+ </div>
78
+ </div>
79
+
80
+ <!-- Features Info -->
81
+ <div class="p-4 bg-green-50 dark:bg-green-900/30 rounded-lg border border-green-200 dark:border-green-800">
82
+ <h4 class="font-semibold mb-2 text-green-900 dark:text-green-100">Features</h4>
83
+ <ul class="text-sm text-green-800 dark:text-green-200 space-y-1">
84
+ <li>✓ Bold & Underline formatting</li>
85
+ <li>✓ Bullet & Ordered lists</li>
86
+ <li>✓ LTR / RTL direction support</li>
87
+ <li>✓ Table creation & editing</li>
88
+ <li>✓ HTML mode for advanced editing</li>
89
+ <li>✓ Character limit tracking</li>
90
+ </ul>
91
+ </div>
92
+ </div>
93
+
94
+ <!-- Events Log -->
95
+ <div class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
96
+ <h4 class="font-semibold mb-2">Recent Events</h4>
97
+ <div class="space-y-1 text-sm max-h-32 overflow-y-auto">
98
+ <div v-if="eventLog.length === 0" class="text-gray-500 dark:text-gray-400">
99
+ No events yet
100
+ </div>
101
+ <div v-for="(event, idx) in eventLog.slice(-5)" :key="idx" class="text-gray-700 dark:text-gray-300">
102
+ <span class="text-xs text-gray-500 dark:text-gray-500">{{ event.time }}</span>
103
+ {{ event.message }}
104
+ </div>
105
+ </div>
106
+ </div>
107
+
108
+ <!-- HTML Output -->
109
+ <div class="p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700">
110
+ <h4 class="font-semibold mb-2">HTML Output</h4>
111
+ <div class="p-3 bg-white dark:bg-gray-900 rounded border border-gray-300 dark:border-gray-600 font-mono text-xs overflow-x-auto max-h-40 overflow-y-auto">
112
+ <code>{{ content }}</code>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </template>
117
+
118
+ <script setup lang="ts">
119
+ import { ref, watch } from 'vue'
120
+ import Editor from '../pgo/Editor.vue'
121
+
122
+ const content = ref('<p>Hello world</p>')
123
+ const characterLimit = ref(500)
124
+ const allowHtmlEdit = ref(true)
125
+ const stickyToolbar = ref(true)
126
+ const editorCharCount = ref(0)
127
+ const isAtLimit = ref(false)
128
+ const eventLog = ref<Array<{ time: string; message: string }>>([])
129
+
130
+ const sampleContent = `
131
+ <h2>Welcome to the Rich Text Editor</h2>
132
+ <p>This editor supports the following formatting options:</p>
133
+ <ul>
134
+ <li><strong>Bold text</strong> for emphasis</li>
135
+ <li><u>Underlined text</u> for additional highlighting</li>
136
+ <li>Bullet lists for organizing information</li>
137
+ </ul>
138
+ <ol>
139
+ <li>Numbered lists for sequential items</li>
140
+ <li>Perfect for instructions or steps</li>
141
+ </ol>
142
+ <p>You can also:</p>
143
+ <ul>
144
+ <li>Insert tables for structured data</li>
145
+ <li>Edit HTML directly when needed</li>
146
+ <li>Use LTR or RTL text direction</li>
147
+ <li>Track character count with limits</li>
148
+ </ul>
149
+ `
150
+
151
+ function loadSampleContent() {
152
+ content.value = sampleContent.replace(/\n\s+/g, '').trim()
153
+ addEvent('Sample content loaded')
154
+ }
155
+
156
+ function clearEditor() {
157
+ if (confirm('Are you sure you want to clear all content?')) {
158
+ content.value = '<p></p>'
159
+ addEvent('Editor cleared')
160
+ }
161
+ }
162
+
163
+ function onLimitReached() {
164
+ isAtLimit.value = true
165
+ addEvent('⚠️ Character limit reached! Editing disabled.')
166
+ console.warn('Character limit reached')
167
+ }
168
+
169
+ function onLimitOk() {
170
+ isAtLimit.value = false
171
+ addEvent('✅ Back under character limit')
172
+ console.log('Back under limit')
173
+ }
174
+
175
+ function addEvent(message: string) {
176
+ const now = new Date()
177
+ const time = now.toLocaleTimeString('en-US', {
178
+ hour: '2-digit',
179
+ minute: '2-digit',
180
+ second: '2-digit'
181
+ })
182
+ eventLog.value.push({ time, message })
183
+ }
184
+
185
+ // Watch for content changes to update character count
186
+ const updateCharCount = () => {
187
+ // Count only visible text characters
188
+ const div = document.createElement('div')
189
+ div.innerHTML = content.value
190
+ editorCharCount.value = div.innerText.length
191
+ }
192
+
193
+ // Update character count when content changes
194
+ watch(content, () => {
195
+ updateCharCount()
196
+ })
197
+
198
+ // Initial character count
199
+ updateCharCount()
200
+ </script>
@@ -0,0 +1,42 @@
1
+ <template>
2
+ <div>
3
+ <ExpansionPanel :panelsData="panels" :allowMultiple="false" :readOnly="false" :disable="false" />
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import ExpansionPanel from '../pgo/ExpansionPanel.vue';
9
+
10
+ export default {
11
+ components: {
12
+ ExpansionPanel
13
+ },
14
+ data() {
15
+ return {
16
+ panels: [
17
+ {
18
+ title: 'Panel 1',
19
+ content: 'This is the content of Panel 1.',
20
+ icon: '🔒',
21
+ readonly: false,
22
+ disabled: false
23
+ },
24
+ {
25
+ title: 'Panel 2',
26
+ content: 'This is the content of Panel 2.',
27
+ icon: '✅',
28
+ readonly: false,
29
+ disabled: false
30
+ },
31
+ {
32
+ title: 'Panel 3',
33
+ content: 'This is the content of Panel 3.',
34
+ icon: '📚',
35
+ readonly: true,
36
+ disabled: false
37
+ }
38
+ ]
39
+ }
40
+ }
41
+ }
42
+ </script>
@@ -0,0 +1,40 @@
1
+ <template>
2
+ <Card :title="'File Upload'" class="mb-4">
3
+ <div class="space-y-3">
4
+ <FileUpload
5
+ v-model="files"
6
+ label="Upload files"
7
+ hint="Images allowed, max 2MB each"
8
+ :accept="'image/*,.pdf'"
9
+ :max-size-mb="2"
10
+ :multiple="true"
11
+
12
+ />
13
+
14
+ <div v-if="files.length" class="mt-2">
15
+ <div class="text-sm text-input-text mb-1">Selected:</div>
16
+ <ul class="space-y-1">
17
+ <li v-for="(f, i) in files" :key="i" class="text-xs text-input-text">{{ f.file.name }} — {{ formatSize(f.file.size) }}</li>
18
+ </ul>
19
+ </div>
20
+ </div>
21
+ </Card>
22
+ </template>
23
+
24
+ <script setup>
25
+ import { ref } from 'vue'
26
+ import Card from '../pgo/Card.vue'
27
+ import FileUpload from '../pgo/inputs/FileUpload.vue'
28
+
29
+ const files = ref([])
30
+
31
+ function formatSize(bytes) {
32
+ if (bytes < 1024) return `${bytes} B`
33
+ const kb = bytes / 1024
34
+ if (kb < 1024) return `${kb.toFixed(1)} KB`
35
+ const mb = kb / 1024
36
+ return `${mb.toFixed(2)} MB`
37
+ }
38
+ </script>
39
+
40
+ <style scoped></style>
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <Card
3
+ :title="'Form Example'"
4
+ class="mb-4"
5
+ bg=""
6
+ >
7
+ <!-- Debug Info -->
8
+ <div class="mb-4 p-4 bg-surface rounded">
9
+ <div>Form Valid: {{ isValid }}</div>
10
+ <div>Form Data: {{ data }}</div>
11
+ </div>
12
+
13
+ <!-- New Vuetify-style Form -->
14
+ <Form
15
+ ref="form"
16
+ v-model="isValid"
17
+ validate-on="blur"
18
+ padding="p-4 space-y-4"
19
+ >
20
+ <div class="space-y-4">
21
+ <InputSearch
22
+ v-model="data.name"
23
+ label="Name"
24
+ :rules="[rules.required, rules.min(3)]"
25
+ />
26
+
27
+ <Select
28
+ v-model="data.country"
29
+ label="Country"
30
+ :items="countries"
31
+ item-title="text"
32
+ item-value="value"
33
+ :rules="[rules.required]"
34
+ :searchable="true"
35
+ :multiple="true"
36
+ />
37
+
38
+ <InputSearch
39
+ v-model="data.nid"
40
+ label="NID"
41
+ :rules="[rules.required, rules.customPattern(
42
+ () => data.country === 'mv',
43
+ '^A\\d{6}$',
44
+ 'NID must start with A followed by 6 digits for Maldives'
45
+ )]"
46
+ />
47
+ <TextField
48
+ v-model="data.nid2"
49
+ label="NID2"
50
+ :rules="[rules.required, rules.nid(data.country)]"
51
+ />
52
+ <Textarea
53
+ v-model="data.description"
54
+ label="Description"
55
+ :rules="[rules.max(200)]"
56
+ />
57
+
58
+ <div class="flex gap-2">
59
+ <Button
60
+ type="submit"
61
+ :disabled="!isValid"
62
+ @click="submit"
63
+ >
64
+ Submit
65
+ </Button>
66
+
67
+ <Button
68
+ @click="form?.reset()"
69
+ label="reset"
70
+ />
71
+
72
+ <!-- <Button
73
+ @click="form?.validate()"
74
+ variant="outlined"
75
+ >
76
+ Validate
77
+ </Button> -->
78
+ </div>
79
+ </div>
80
+ </Form>
81
+ </Card>
82
+ </template>
83
+
84
+ <script setup>
85
+ import { ref, inject } from 'vue'
86
+ import Card from '../pgo/Card.vue'
87
+ import Form from '../pgo/forms/Form.vue'
88
+ import InputSearch from '../pgo/InputSearch.vue'
89
+ import TextField from '../pgo/inputs/TextField.vue'
90
+ import Select from '../pgo/inputs/Select.vue'
91
+ import Button from '../pgo/Button.vue'
92
+ import Textarea from '../pgo/inputs/Textarea.vue'
93
+ // import rules from '../validations/validationRules'
94
+
95
+ const rules = inject('validationRules')
96
+
97
+ const form = ref(null)
98
+ const isValid = ref(false) // Track form validity
99
+
100
+ const data = ref({
101
+ name: '',
102
+ role: '',
103
+ country: [],
104
+ nid: '',
105
+ nid2: '',
106
+ description: '',
107
+ })
108
+
109
+ const countries = [
110
+ { text: 'Maldives', value: 'mv' },
111
+ { text: 'India', value: 'in' },
112
+ { text: 'Sri Lanka', value: 'lk' },
113
+ ]
114
+
115
+ const submit = async () => {
116
+ const { valid } = await form.value.validate()
117
+ if (!valid) return
118
+
119
+ console.log('FORM OK', data.value)
120
+ }
121
+ </script>
@@ -0,0 +1,8 @@
1
+
2
+
3
+ <template>
4
+ <div>Hello</div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ </script>
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <LayoutContainer>
3
+ <!-- Default slot → Main Content -->
4
+ <template #default>
5
+ <div>
6
+ <h1 class="text-3xl font-bold mb-4">Dashboard</h1>
7
+
8
+ <p class="text-gray-600 mb-6">This is the main content area.</p>
9
+
10
+ <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
11
+ <div v-for="n in 9" :key="n" class="bg-white p-4 rounded shadow">
12
+ <h2 class="font-semibold mb-2">Card {{ n }}</h2>
13
+ <p class="text-sm text-gray-500">
14
+ Example content for card number {{ n }}.
15
+ </p>
16
+ </div>
17
+ </div>
18
+ </div>
19
+
20
+ <div class="flex-1">
21
+ <NavDrawerExample />
22
+ <AppBarExample />
23
+ </div>
24
+
25
+ <div class="container mx-auto p-6">
26
+ <!-- Stacked Table View Example -->
27
+ <StackedTableViewExample />
28
+
29
+ <!-- TextField Example -->
30
+ <TextFieldExample />
31
+
32
+ <!-- Textarea Example -->
33
+ <TextareaExample />
34
+
35
+ <!-- Dropdown Examples -->
36
+ <DropdownExample />
37
+
38
+ <!-- Card Example -->
39
+ <CardExample />
40
+
41
+ <!-- Chips Examples -->
42
+ <ChipExample />
43
+
44
+ <!-- DataTable Example -->
45
+ <TableExample />
46
+
47
+ <!-- Select Example -->
48
+ <!-- <SelectExample /> -->
49
+
50
+ <!-- Banner Example -->
51
+ <BannerExample />
52
+
53
+ <!-- Search Example -->
54
+ <SearchExample />
55
+ </div>
56
+ </template>
57
+
58
+ <!-- Footer slot -->
59
+ <template #footer>
60
+ <div class="text-center text-gray-500 text-sm">© 2025 My Awesome App</div>
61
+ </template>
62
+ </LayoutContainer>
63
+ </template>
64
+
65
+ <script setup lang="ts">
66
+ import AppBarExample from "../examples/AppBarExample.vue";
67
+ import NavDrawerExample from "../examples/NavDrawerExample.vue";
68
+ import ChipExample from "../examples/ChipExample.vue";
69
+ import TableExample from "../examples/TableExample.vue";
70
+ import SelectExample from "../examples/SelectExample.vue";
71
+ import CardExample from "../examples/CardExample.vue";
72
+ import DropdownExample from "../examples/DropdownExample.vue";
73
+ import TextareaExample from "../examples/TextareaExample.vue";
74
+ import TextFieldExample from "../examples/TextFieldExample.vue";
75
+ import BannerExample from "../examples/BannerExample.vue";
76
+ import SearchExample from "../examples/SearchExample.vue";
77
+ import StackedTableViewExample from "../examples/StackedTableViewExample.vue";
78
+
79
+ import LayoutContainer from "../pgo/LayoutContainer.vue";
80
+ </script>