@bagelink/vue 1.14.13 → 1.14.15
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/dist/components/AddressSearch.vue.d.ts +6 -7
- package/dist/components/Alert.vue.d.ts.map +1 -1
- package/dist/components/Avatar.vue.d.ts.map +1 -1
- package/dist/components/Btn.vue.d.ts +1 -1
- package/dist/components/Card.vue.d.ts.map +1 -1
- package/dist/components/Carousel.vue.d.ts +0 -11
- package/dist/components/Dropdown.vue.d.ts +0 -2
- package/dist/components/Filter.vue.d.ts +30 -0
- package/dist/components/Filter.vue.d.ts.map +1 -0
- package/dist/components/FilterQuery.vue.d.ts +8 -3
- package/dist/components/Image.vue.d.ts.map +1 -1
- package/dist/components/ImportData.vue.d.ts.map +1 -1
- package/dist/components/Modal.vue.d.ts +0 -1
- package/dist/components/Pill.vue.d.ts.map +1 -1
- package/dist/components/QueryFilter.vue.d.ts +30 -0
- package/dist/components/QueryFilter.vue.d.ts.map +1 -0
- package/dist/components/Swiper.vue.d.ts +6 -12
- package/dist/components/Toast.vue.d.ts.map +1 -1
- package/dist/components/analytics/PieChart.vue.d.ts +2 -2
- package/dist/components/calendar/CalendarPopover.vue.d.ts +8 -4
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/calendar/CalendarTypes.d.ts +0 -10
- package/dist/components/calendar/Index.vue.d.ts +4 -20
- package/dist/components/calendar/views/WeekView.vue.d.ts +1 -9
- package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ArrayInput.vue.d.ts +2 -4
- package/dist/components/form/inputs/CheckInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/Checkbox.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/CodeEditor/Index.vue.d.ts +0 -54
- package/dist/components/form/inputs/ColorInput.vue.d.ts +1 -3
- package/dist/components/form/inputs/DateInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/DatePicker.vue.d.ts +0 -1
- package/dist/components/form/inputs/EmailInput.vue.d.ts +2 -5
- package/dist/components/form/inputs/JSONInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/MarkdownEditor.vue.d.ts +2 -7
- package/dist/components/form/inputs/NumberInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/OTP.vue.d.ts +1 -2
- package/dist/components/form/inputs/PasswordInput.vue.d.ts +10 -16
- package/dist/components/form/inputs/RadioGroup.vue.d.ts +1 -3
- package/dist/components/form/inputs/RangeInput.vue.d.ts +1 -6
- package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -2
- package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/media.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectBtn.vue.d.ts +2 -2
- package/dist/components/form/inputs/SelectInput.vue.d.ts +13 -20
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/SignaturePad.vue.d.ts +1 -6
- package/dist/components/form/inputs/TableField.vue.d.ts +1 -2
- package/dist/components/form/inputs/TelInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/TextInput.vue.d.ts +2 -3
- package/dist/components/form/inputs/ToggleInput.vue.d.ts +1 -2
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts +6 -27
- package/dist/components/form/inputs/Upload/upload.d.ts +1 -1
- package/dist/components/form/inputs/index.d.ts +0 -1
- package/dist/components/index.d.ts +1 -3
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/layout/AppContent.vue.d.ts +1 -1
- package/dist/components/layout/AppLayout.vue.d.ts +0 -2
- package/dist/components/layout/AppSidebar.vue.d.ts +1 -5
- package/dist/components/layout/Skeleton.vue.d.ts.map +1 -1
- package/dist/components/layout/TabsNav.vue.d.ts +1 -12
- package/dist/dialog/Dialog.vue.d.ts.map +1 -1
- package/dist/dialog/DialogConfirm.vue.d.ts.map +1 -1
- package/dist/form-flow/MultiStepForm.vue.d.ts +1 -6
- package/dist/form-flow/form-flow.d.ts +1 -24
- package/dist/i18n/index.d.ts +0 -838
- package/dist/index.cjs +193 -166
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +47586 -53496
- package/dist/plugins/bagel.d.ts.map +1 -1
- package/dist/style.css +1 -2
- package/dist/types/BagelForm.d.ts +1 -10
- package/dist/types/NavLink.d.ts +1 -2
- package/dist/types/TableSchema.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/BagelFormUtils.d.ts +0 -1
- package/dist/utils/calendar/dateUtils.d.ts +2 -2
- package/dist/utils/calendar/dateUtils.d.ts.map +1 -1
- package/dist/utils/date.d.ts +116 -0
- package/dist/utils/date.d.ts.map +1 -0
- package/dist/utils/fetch.d.ts +29 -0
- package/dist/utils/fetch.d.ts.map +1 -0
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/string.d.ts +7 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/useSearch.d.ts +1 -1
- package/package.json +1 -5
- package/src/components/AccordionItem.vue +5 -5
- package/src/components/Alert.vue +3 -2
- package/src/components/Avatar.vue +2 -1
- package/src/components/BglVideo.vue +4 -4
- package/src/components/Btn.vue +39 -39
- package/src/components/Card.vue +7 -6
- package/src/components/Dropdown.vue +2 -2
- package/src/components/FieldSetVue.vue +2 -2
- package/src/components/FilterQuery.vue +2 -2
- package/src/components/Image.vue +2 -1
- package/src/components/ImportData.vue +12 -12
- package/src/components/JSONSchema.vue +2 -2
- package/src/components/JsonBuilder.vue +2 -2
- package/src/components/ListItem.vue +1 -1
- package/src/components/MapEmbed/Index.vue +8 -8
- package/src/components/Pill.vue +17 -16
- package/src/components/Spreadsheet/Index.vue +3 -3
- package/src/components/Spreadsheet/SpreadsheetTable.vue +10 -10
- package/src/components/Toast.vue +34 -28
- package/src/components/calendar/CalendarPopover.vue +1 -1
- package/src/components/calendar/Index.vue +1 -1
- package/src/components/calendar/views/AgendaView.vue +2 -2
- package/src/components/calendar/views/DayView.vue +1 -1
- package/src/components/calendar/views/MonthView.vue +5 -5
- package/src/components/dataTable/DataTable.vue +68 -10
- package/src/components/form/FieldArray.vue +5 -5
- package/src/components/form/inputs/ArrayInput.vue +1 -1
- package/src/components/form/inputs/CheckInput.vue +6 -6
- package/src/components/form/inputs/Checkbox.vue +5 -4
- package/src/components/form/inputs/CodeEditor/Index.vue +1 -1
- package/src/components/form/inputs/ColorInput.vue +5 -5
- package/src/components/form/inputs/DatePicker.vue +3 -3
- package/src/components/form/inputs/EmailInput.vue +14 -14
- package/src/components/form/inputs/NumberInput.vue +10 -10
- package/src/components/form/inputs/OTP.vue +2 -2
- package/src/components/form/inputs/PasswordInput.vue +3 -3
- package/src/components/form/inputs/RadioGroup.vue +1 -1
- package/src/components/form/inputs/RichText/editor.css +4 -4
- package/src/components/form/inputs/RichText/index.vue +39 -39
- package/src/components/form/inputs/RichText/utils/media.ts +1 -92
- package/src/components/form/inputs/RichText/utils/table.ts +4 -4
- package/src/components/form/inputs/SelectBtn.vue +1 -1
- package/src/components/form/inputs/SelectInput.vue +13 -13
- package/src/components/form/inputs/SignaturePad.vue +6 -6
- package/src/components/form/inputs/TableField.vue +7 -7
- package/src/components/form/inputs/TelInput.vue +11 -11
- package/src/components/form/inputs/TextInput.vue +10 -10
- package/src/components/form/inputs/ToggleInput.vue +11 -11
- package/src/components/form/inputs/Upload/upload.css +14 -14
- package/src/components/index.ts +0 -3
- package/src/components/layout/AppSidebar.vue +3 -3
- package/src/components/layout/BottomMenu.vue +1 -1
- package/src/components/layout/Skeleton.vue +5 -4
- package/src/components/layout/TabsNav.vue +18 -18
- package/src/index.ts +0 -1
- package/src/plugins/bagel.ts +0 -15
- package/src/styles/app-layout.css +231 -0
- package/src/styles/appearance.css +179 -21
- package/src/styles/bagel.css +103 -97
- package/src/styles/buttons.css +8 -8
- package/src/styles/colors.css +0 -103
- package/src/styles/dark.css +25 -26
- package/src/styles/input-variants.css +11 -11
- package/src/styles/inputs.css +43 -60
- package/src/styles/layout.css +445 -1258
- package/src/styles/loginCard.css +1 -1
- package/src/styles/mobilLayout.css +153 -28
- package/src/styles/text.css +500 -1508
- package/src/styles/theme.css +199 -435
- package/src/styles/transitions.css +4 -4
- package/src/types/TableSchema.ts +1 -0
- package/src/types/index.ts +0 -5
- package/src/utils/calendar/dateUtils.ts +2 -3
- package/src/utils/date.ts +482 -0
- package/src/utils/fetch.ts +128 -0
- package/src/utils/index.ts +35 -0
- package/src/utils/string.ts +56 -0
- package/bin/generateFormSchema.ts +0 -1035
- package/bin/utils.ts +0 -223
- package/src/components/Modal.vue +0 -184
- package/src/components/ModalConfirm.vue +0 -42
- package/src/components/ModalForm.vue +0 -102
- package/src/plugins/modalTypes.ts +0 -61
- package/src/plugins/useModal.ts +0 -225
- package/src/styles/modal.css +0 -120
- package/src/styles/pillColors.css +0 -0
package/bin/utils.ts
DELETED
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs'
|
|
2
|
-
|
|
3
|
-
import { join } from 'node:path'
|
|
4
|
-
import { cwd as _cwd, env, argv } from 'node:process'
|
|
5
|
-
import { ESLint } from 'eslint'
|
|
6
|
-
import * as prettier from 'prettier'
|
|
7
|
-
import { loadEnv } from 'vite'
|
|
8
|
-
|
|
9
|
-
const cwd = _cwd()
|
|
10
|
-
|
|
11
|
-
export async function formatAndWriteCode(outPath: string, code: string) {
|
|
12
|
-
const prettyCode = await prettier.format(code, { parser: 'typescript' })
|
|
13
|
-
fs.writeFileSync(outPath, prettyCode)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export async function runEsLintOnDir(dir: string) {
|
|
17
|
-
// ! only run if eslint.config.js exists
|
|
18
|
-
if (!fs.existsSync(join(cwd, 'eslint.config.js'))) {
|
|
19
|
-
console.log('no eslint.config.js found, skipping eslint')
|
|
20
|
-
return
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const eslint = new ESLint({ fix: true, overrideConfigFile: join(cwd, 'eslint.config.js'), cwd })
|
|
24
|
-
const results = await eslint.lintFiles(`${dir}/**/*.ts`)
|
|
25
|
-
|
|
26
|
-
await ESLint.outputFixes(results)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// =============================================================================
|
|
30
|
-
// TYPES
|
|
31
|
-
// =============================================================================
|
|
32
|
-
|
|
33
|
-
interface ParsedConfig {
|
|
34
|
-
readonly baseUrl: string
|
|
35
|
-
readonly openApiUrl: string
|
|
36
|
-
readonly schemaId?: string
|
|
37
|
-
readonly outputFile?: string
|
|
38
|
-
readonly useUtilityFunctions?: boolean
|
|
39
|
-
readonly useTableSchema?: boolean
|
|
40
|
-
readonly verbose?: boolean
|
|
41
|
-
readonly cwd: string
|
|
42
|
-
env: Partial<Record<string, string>>
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interface ConfigOptions {
|
|
46
|
-
readonly schemaId: string | undefined
|
|
47
|
-
readonly defaultOutputFile?: string
|
|
48
|
-
readonly allowedFlags?: readonly string[]
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// =============================================================================
|
|
52
|
-
// ARGUMENT PARSING UTILITIES
|
|
53
|
-
// =============================================================================
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Parse command line flags (arguments starting with --)
|
|
57
|
-
*/
|
|
58
|
-
function parseFlags(args: string[]): Set<string> {
|
|
59
|
-
return new Set(
|
|
60
|
-
args
|
|
61
|
-
.filter(arg => arg.startsWith('--'))
|
|
62
|
-
.map(arg => arg.slice(2)) // Remove '--' prefix
|
|
63
|
-
)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Parse command line arguments that are key-value pairs (--key=value)
|
|
68
|
-
*/
|
|
69
|
-
function parseKeyValueArgs(args: string[]): Record<string, string> {
|
|
70
|
-
const keyValuePairs: Record<string, string> = {}
|
|
71
|
-
|
|
72
|
-
args
|
|
73
|
-
.filter(arg => arg.startsWith('--') && arg.includes('='))
|
|
74
|
-
.forEach((arg) => {
|
|
75
|
-
const [key, ...valueParts] = arg.slice(2).split('=')
|
|
76
|
-
if (key && valueParts.length > 0) {
|
|
77
|
-
keyValuePairs[key] = valueParts.join('=')
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
return keyValuePairs
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// /**
|
|
85
|
-
// * Parse positional arguments (non-flag arguments)
|
|
86
|
-
// */
|
|
87
|
-
// function parsePositionalArgs(args: string[]): string[] {
|
|
88
|
-
// return args.filter(arg => !arg.startsWith('--'))
|
|
89
|
-
// }
|
|
90
|
-
|
|
91
|
-
// =============================================================================
|
|
92
|
-
// MAIN PARSING FUNCTION
|
|
93
|
-
// =============================================================================
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Parse command line arguments and environment variables into a structured configuration
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```bash
|
|
100
|
-
* # Basic usage
|
|
101
|
-
* node script.js
|
|
102
|
-
*
|
|
103
|
-
* # With directory
|
|
104
|
-
* node script.js
|
|
105
|
-
*
|
|
106
|
-
* # With flags
|
|
107
|
-
* node script.js --verbose
|
|
108
|
-
*
|
|
109
|
-
* # With key-value pairs
|
|
110
|
-
* node script.js --schema-id=UserResponse --output=src/forms/user.ts
|
|
111
|
-
*
|
|
112
|
-
* # Combined
|
|
113
|
-
* node script.js --schema-id=UserResponse --output=src/forms/user.ts
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
export function parseConfig(options: ConfigOptions): ParsedConfig {
|
|
117
|
-
const {
|
|
118
|
-
schemaId,
|
|
119
|
-
defaultOutputFile,
|
|
120
|
-
allowedFlags = [
|
|
121
|
-
'verbose',
|
|
122
|
-
'utility-functions',
|
|
123
|
-
'table-schema'
|
|
124
|
-
]
|
|
125
|
-
} = options
|
|
126
|
-
|
|
127
|
-
// Load environment variables
|
|
128
|
-
const currentCwd = cwd
|
|
129
|
-
const environment = loadEnv('', currentCwd)
|
|
130
|
-
|
|
131
|
-
// Parse command line arguments
|
|
132
|
-
const args = argv.slice(2) // Remove 'node' and script path
|
|
133
|
-
const flags = parseFlags(args)
|
|
134
|
-
const keyValueArgs = parseKeyValueArgs(args)
|
|
135
|
-
// const positionalArgs = parsePositionalArgs(args)
|
|
136
|
-
|
|
137
|
-
// Validate flags
|
|
138
|
-
const invalidFlags = Array.from(flags).filter(flag => !allowedFlags.includes(flag) && !flag.includes('=')
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
if (invalidFlags.length > 0) {
|
|
142
|
-
console.warn(`Warning: Unknown flags detected: ${invalidFlags.join(', ')}`)
|
|
143
|
-
console.warn(`Allowed flags: ${allowedFlags.join(', ')}`)
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Build configuration
|
|
147
|
-
const baseUrl = keyValueArgs.baseurl || keyValueArgs['base-url'] || 'http://localhost:8000'
|
|
148
|
-
|
|
149
|
-
const config: ParsedConfig = {
|
|
150
|
-
// URLs and paths
|
|
151
|
-
baseUrl,
|
|
152
|
-
openApiUrl: `${baseUrl}/openapi.json`,
|
|
153
|
-
|
|
154
|
-
// Flags
|
|
155
|
-
useUtilityFunctions: flags.has('utility-functions'),
|
|
156
|
-
useTableSchema: flags.has('table-schema'),
|
|
157
|
-
verbose: flags.has('verbose'),
|
|
158
|
-
|
|
159
|
-
// Key-value arguments with fallbacks
|
|
160
|
-
schemaId: keyValueArgs['schema-id'] || keyValueArgs.schemaId || keyValueArgs.schema || schemaId,
|
|
161
|
-
outputFile: keyValueArgs.output || keyValueArgs.out || defaultOutputFile,
|
|
162
|
-
|
|
163
|
-
// System info
|
|
164
|
-
cwd: currentCwd,
|
|
165
|
-
env: { ...environment, ...env } // Merge loaded env with process.env
|
|
166
|
-
} as const
|
|
167
|
-
|
|
168
|
-
// Log configuration if verbose
|
|
169
|
-
if (config.verbose) {
|
|
170
|
-
console.log('Parsed configuration:', {
|
|
171
|
-
...config,
|
|
172
|
-
env: '[hidden]' // Don't log environment variables
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return config
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// =============================================================================
|
|
180
|
-
// UTILITY HELPERS
|
|
181
|
-
// =============================================================================
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Print help message for command line usage
|
|
185
|
-
*/
|
|
186
|
-
export function printHelp(scriptName: string = 'script'): void {
|
|
187
|
-
console.log(`
|
|
188
|
-
Usage: ${scriptName} [directory] [options]
|
|
189
|
-
|
|
190
|
-
Arguments:
|
|
191
|
-
directory Target directory (default: .bagelink)
|
|
192
|
-
|
|
193
|
-
Options:
|
|
194
|
-
--verbose Enable verbose logging
|
|
195
|
-
--utility-functions Use utility functions in generated code
|
|
196
|
-
--table-schema Generate table schema instead of form schema
|
|
197
|
-
--baseurl=<url> Specify base URL (default: http://localhost:8000)
|
|
198
|
-
--schema-id=<id> Specify schema ID to process
|
|
199
|
-
--output=<path> Specify output file path
|
|
200
|
-
|
|
201
|
-
Examples:
|
|
202
|
-
${scriptName} # Use defaults
|
|
203
|
-
${scriptName} # Custom directory
|
|
204
|
-
${scriptName} --verbose # With flags
|
|
205
|
-
${scriptName} --baseurl=https://api.example.com # Custom base URL
|
|
206
|
-
${scriptName} --schema-id=UserResponse # With schema ID
|
|
207
|
-
${scriptName} --output=forms.ts # Combined usage
|
|
208
|
-
`)
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
* Validate required configuration values
|
|
213
|
-
*/
|
|
214
|
-
export function validateConfig(config: ParsedConfig, required: (keyof ParsedConfig)[] = []): void {
|
|
215
|
-
const missing = required.filter((key) => {
|
|
216
|
-
const value = config[key]
|
|
217
|
-
return value === undefined || value === null || value === ''
|
|
218
|
-
})
|
|
219
|
-
|
|
220
|
-
if (missing.length > 0) {
|
|
221
|
-
throw new Error(`Missing required configuration: ${missing.join(', ')}`)
|
|
222
|
-
}
|
|
223
|
-
}
|
package/src/components/Modal.vue
DELETED
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
<!-- eslint-disable vue/multi-word-component-names -->
|
|
2
|
-
<script lang="ts" setup>
|
|
3
|
-
import type { BtnOptions } from '@bagelink/vue'
|
|
4
|
-
import type { SetupContext } from 'vue'
|
|
5
|
-
import {
|
|
6
|
-
Btn,
|
|
7
|
-
Card,
|
|
8
|
-
Title
|
|
9
|
-
} from '@bagelink/vue'
|
|
10
|
-
import {
|
|
11
|
-
computed,
|
|
12
|
-
ref,
|
|
13
|
-
useSlots,
|
|
14
|
-
watch
|
|
15
|
-
} from 'vue'
|
|
16
|
-
import '../styles/modal.css'
|
|
17
|
-
|
|
18
|
-
interface ModalProps {
|
|
19
|
-
thin?: boolean
|
|
20
|
-
mobileThin?: boolean
|
|
21
|
-
side?: boolean
|
|
22
|
-
title?: string
|
|
23
|
-
width?: string
|
|
24
|
-
dismissable?: boolean
|
|
25
|
-
actions?: BtnOptions[]
|
|
26
|
-
visible?: boolean
|
|
27
|
-
zIndex?: number
|
|
28
|
-
closePlacement?: 'header' | 'header-end' | 'overlay' | 'overlay-end' | 'none' | 'footer'
|
|
29
|
-
}
|
|
30
|
-
const props = withDefaults(defineProps<ModalProps>(), {
|
|
31
|
-
thin: false,
|
|
32
|
-
side: false,
|
|
33
|
-
dismissable: true,
|
|
34
|
-
visible: false,
|
|
35
|
-
zIndex: 100,
|
|
36
|
-
closePlacement: 'header'
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const emit = defineEmits(['update:visible'])
|
|
40
|
-
|
|
41
|
-
const slots: SetupContext['slots'] = useSlots()
|
|
42
|
-
|
|
43
|
-
const isVisible = ref<boolean>(false)
|
|
44
|
-
|
|
45
|
-
watch(
|
|
46
|
-
() => props.visible,
|
|
47
|
-
(val) => {
|
|
48
|
-
if (val === isVisible.value || val === undefined) { return }
|
|
49
|
-
if (val) { openModal() }
|
|
50
|
-
else { closeModal() }
|
|
51
|
-
},
|
|
52
|
-
{ immediate: true },
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
const maxWidth = computed(() => {
|
|
56
|
-
const { width } = props
|
|
57
|
-
if (width?.match(/px|em|rem|vw|vh|%/)) { return { 'max-width': width } }
|
|
58
|
-
if (width?.match(/\d+/)) { return { 'max-width': `${width}px` } }
|
|
59
|
-
return { 'max-width': '720px' }
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// Computed properties for close button placement
|
|
63
|
-
const isOverlay = computed(() => props.closePlacement === 'overlay' || props.closePlacement === 'overlay-end')
|
|
64
|
-
const isHeader = computed(() => props.closePlacement === 'header' || props.closePlacement === 'header-end')
|
|
65
|
-
const isFooter = computed(() => props.closePlacement === 'footer')
|
|
66
|
-
|
|
67
|
-
const overlayCloseClass = computed(() => {
|
|
68
|
-
if (props.closePlacement === 'overlay-end') { return 'top-1 end-1' }
|
|
69
|
-
return 'top-1 start-1'
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
function closeModal() {
|
|
73
|
-
isVisible.value = false
|
|
74
|
-
setTimeout(() => { emit('update:visible', false) }, 200)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
defineExpose({ closeModal })
|
|
78
|
-
|
|
79
|
-
function openModal() {
|
|
80
|
-
setTimeout(() => (isVisible.value = true), 1)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Note: ESC key handling is now done centrally in ModalPlugin for proper stacking behavior
|
|
84
|
-
</script>
|
|
85
|
-
|
|
86
|
-
<template>
|
|
87
|
-
<div
|
|
88
|
-
class="bg-dark" :style="{ zIndex }" :class="{ 'is-side': side, 'is-active': isVisible, 'bg-lignt': false }"
|
|
89
|
-
@click="() => (dismissable ? closeModal() : '')" @keydown.esc="closeModal"
|
|
90
|
-
>
|
|
91
|
-
<!-- Overlay close button -->
|
|
92
|
-
<Btn
|
|
93
|
-
v-if="dismissable && isOverlay" icon="close" icon-mobile-size="1.4" class="fixed"
|
|
94
|
-
:class="overlayCloseClass" @click="closeModal"
|
|
95
|
-
/>
|
|
96
|
-
|
|
97
|
-
<Card
|
|
98
|
-
class="modal m_pt-0" :style="{ ...maxWidth, '--bgl-box-bg': 'var(--bgl-popup-bg)' }" :thin="thin"
|
|
99
|
-
:class="{ 'pt-0': thin, 'pt-1': !thin, 'm_mt-5': isOverlay, 'display-flex column': side, 'm_px-1 m_pb-1': mobileThin }" @click.stop
|
|
100
|
-
>
|
|
101
|
-
<header v-if="slots.toolbar || title" class="tool-bar w-100p flex space-between sticky z-3 py-1">
|
|
102
|
-
<!-- Header close button -->
|
|
103
|
-
<Btn
|
|
104
|
-
v-if="dismissable && isHeader && closePlacement === 'header'" :style="{ float: side ? '' : '' }"
|
|
105
|
-
flat icon="close" thin icon-mobile-size="1.4" @click="closeModal"
|
|
106
|
-
/>
|
|
107
|
-
<slot name="toolbar" />
|
|
108
|
-
<Title
|
|
109
|
-
v-if="title" class="modal-title txt-center txt20 medium my-0 w-100p ellipsis-1" tag="h3"
|
|
110
|
-
:label="title"
|
|
111
|
-
:class="{ 'me-1-5': isHeader && dismissable && closePlacement === 'header', 'ms-1-5': isHeader && dismissable && closePlacement === 'header-end' }"
|
|
112
|
-
/>
|
|
113
|
-
<!-- Header-end close button -->
|
|
114
|
-
<Btn
|
|
115
|
-
v-if="dismissable && isHeader && closePlacement === 'header-end'"
|
|
116
|
-
:style="{ float: side ? '' : '' }" flat icon="close" thin icon-mobile-size="1.4"
|
|
117
|
-
@click="closeModal"
|
|
118
|
-
/>
|
|
119
|
-
</header>
|
|
120
|
-
|
|
121
|
-
<header
|
|
122
|
-
v-else class="tool-bar w-100p flex space-between sticky z-3"
|
|
123
|
-
:class="{ 'py-1': !isOverlay, 'pt-1': isOverlay }"
|
|
124
|
-
>
|
|
125
|
-
<!-- Header close button (no title) -->
|
|
126
|
-
<Btn
|
|
127
|
-
v-if="dismissable && isHeader && closePlacement === 'header'" :style="{ float: side ? '' : '' }"
|
|
128
|
-
flat icon="close" thin icon-mobile-size="1.4" @click="closeModal"
|
|
129
|
-
/>
|
|
130
|
-
<slot name="toolbar" />
|
|
131
|
-
<!-- Header-end close button (no title) -->
|
|
132
|
-
<Btn
|
|
133
|
-
v-if="dismissable && isHeader && closePlacement === 'header-end'"
|
|
134
|
-
:style="{ float: side ? '' : '' }" flat icon="close" thin icon-mobile-size="1.4" class="ms-auto"
|
|
135
|
-
@click="closeModal"
|
|
136
|
-
/>
|
|
137
|
-
</header>
|
|
138
|
-
|
|
139
|
-
<slot />
|
|
140
|
-
<footer
|
|
141
|
-
v-if="slots.footer || actions?.length" class="modal-footer gap-1 flex space-between"
|
|
142
|
-
:class="{ 'mt-1': !side, 'mt-auto': side }"
|
|
143
|
-
>
|
|
144
|
-
<Btn v-for="(action, i) in actions" :key="i" color="gray" v-bind="action" @click="closeModal" />
|
|
145
|
-
<slot name="footer" />
|
|
146
|
-
<!-- Footer close button -->
|
|
147
|
-
</footer>
|
|
148
|
-
<Btn
|
|
149
|
-
v-if="dismissable && isFooter" icon="close" label="Close"
|
|
150
|
-
class="mx-auto absolute start-0 end-0 modalFooterBtn" @click="closeModal"
|
|
151
|
-
/>
|
|
152
|
-
</Card>
|
|
153
|
-
</div>
|
|
154
|
-
</template>
|
|
155
|
-
|
|
156
|
-
<style>
|
|
157
|
-
.modal {
|
|
158
|
-
color: var(--bgl-popup-text);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
.modal .bgl_btn.bgl_btn_flat {
|
|
162
|
-
color: var(--bgl-popup-text) !important;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.modal .rich-text-editor .bgl_btn.bgl_btn_flat.active {
|
|
166
|
-
color: var(--bgl-white) !important;
|
|
167
|
-
}
|
|
168
|
-
.modal-footer>div {
|
|
169
|
-
gap: 1rem;
|
|
170
|
-
display: flex;
|
|
171
|
-
justify-content: space-between;
|
|
172
|
-
align-items: center;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
.modal-no-title {
|
|
176
|
-
width: calc(100% + 2rem);
|
|
177
|
-
border-radius: var(--card-border-radius);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.modalFooterBtn {
|
|
181
|
-
bottom: calc(var(--btn-height) / 2 * -1);
|
|
182
|
-
|
|
183
|
-
}
|
|
184
|
-
</style>
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import type { ThemeType } from '@bagelink/vue'
|
|
3
|
-
import { Btn, Modal, useI18n } from '@bagelink/vue'
|
|
4
|
-
import { computed } from 'vue'
|
|
5
|
-
|
|
6
|
-
const props = defineProps<{
|
|
7
|
-
title?: string
|
|
8
|
-
message?: string
|
|
9
|
-
confirmText?: string
|
|
10
|
-
confirmBtnColor?: ThemeType
|
|
11
|
-
cancelBtnColor?: ThemeType
|
|
12
|
-
cancelText?: string
|
|
13
|
-
resolve: (value: boolean) => void
|
|
14
|
-
}>()
|
|
15
|
-
|
|
16
|
-
const emit = defineEmits(['update:visible'])
|
|
17
|
-
const { $t } = useI18n()
|
|
18
|
-
|
|
19
|
-
function select(val: boolean) {
|
|
20
|
-
props.resolve(val)
|
|
21
|
-
emit('update:visible')
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const title = computed(() => props.title || $t('modalConfirm.title'))
|
|
25
|
-
const message = computed(() => props.message || $t('modalConfirm.message'))
|
|
26
|
-
const confirmText = computed(() => props.confirmText || $t('modalConfirm.confirm'))
|
|
27
|
-
const cancelText = computed(() => props.cancelText || $t('modalConfirm.cancel'))
|
|
28
|
-
const confirmBtnColor = computed((): ThemeType => props.confirmBtnColor || 'green')
|
|
29
|
-
const cancelBtnColor = computed((): ThemeType => props.cancelBtnColor || 'gray')
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<template>
|
|
33
|
-
<Modal :title="title" width="380px" :dismissable="false" class="txt-center" :zIndex="9999">
|
|
34
|
-
<p class="pb-05 pretty">
|
|
35
|
-
{{ message }}
|
|
36
|
-
</p>
|
|
37
|
-
<template #footer>
|
|
38
|
-
<Btn :color="cancelBtnColor" :value="cancelText" @click="select(false)" />
|
|
39
|
-
<Btn :color="confirmBtnColor" :value="confirmText" @click="select(true)" />
|
|
40
|
-
</template>
|
|
41
|
-
</Modal>
|
|
42
|
-
</template>
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
<script lang="ts" setup generic="T extends {[key:string]:any}, P extends Path<T>">
|
|
2
|
-
import type { Path } from '@bagelink/vue'
|
|
3
|
-
import type { ComponentExposed } from 'vue-component-type-helpers'
|
|
4
|
-
import type { ModalFormOptions } from '../plugins/modalTypes'
|
|
5
|
-
import { Btn, Modal, BagelForm } from '@bagelink/vue'
|
|
6
|
-
import { ref } from 'vue'
|
|
7
|
-
|
|
8
|
-
// eslint-disable-next-line vue/prop-name-casing
|
|
9
|
-
const props = withDefaults(defineProps<ModalFormOptions<T>>(), {
|
|
10
|
-
visible: true,
|
|
11
|
-
dismissable: true,
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
const emit = defineEmits<{
|
|
15
|
-
'update:modelValue': [value: T]
|
|
16
|
-
'update:visible': [value: boolean]
|
|
17
|
-
}>()
|
|
18
|
-
|
|
19
|
-
const modal = ref<ComponentExposed<typeof Modal>>()
|
|
20
|
-
|
|
21
|
-
const formData = defineModel<T>('modelValue', {
|
|
22
|
-
default: {} as Partial<T>,
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
type BagelFormT = ComponentExposed<typeof BagelForm<T, P>>
|
|
26
|
-
|
|
27
|
-
const form = ref<BagelFormT>()
|
|
28
|
-
const closeModal = () => modal.value?.closeModal()
|
|
29
|
-
|
|
30
|
-
const submitting = ref(false)
|
|
31
|
-
|
|
32
|
-
async function runSubmit() {
|
|
33
|
-
if (submitting.value) { return }
|
|
34
|
-
if (form.value?.validateForm() === false) { return }
|
|
35
|
-
submitting.value = true
|
|
36
|
-
try {
|
|
37
|
-
await props.onSubmit?.(formData.value)
|
|
38
|
-
closeModal()
|
|
39
|
-
} catch (err: any) {
|
|
40
|
-
submitting.value = false
|
|
41
|
-
if (props.onError) {
|
|
42
|
-
props.onError(err)
|
|
43
|
-
} else {
|
|
44
|
-
console.error('[ModalForm] Submit error:', err)
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function runDelete() {
|
|
50
|
-
props.onDelete?.(formData.value)
|
|
51
|
-
closeModal()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function setFormValues(values: { [key: string]: any }) {
|
|
55
|
-
Object.assign(formData, values)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
defineExpose({ setFormValues })
|
|
59
|
-
</script>
|
|
60
|
-
|
|
61
|
-
<template>
|
|
62
|
-
<Modal
|
|
63
|
-
ref="modal" :side :width :visible="visible" :dismissable :title
|
|
64
|
-
@update:visible="($event: boolean) => emit('update:visible', $event)"
|
|
65
|
-
>
|
|
66
|
-
<template #toolbar>
|
|
67
|
-
<slot name="toolbar" />
|
|
68
|
-
</template>
|
|
69
|
-
<BagelForm
|
|
70
|
-
v-if="visible" ref="form" v-model="formData" :schema="schema"
|
|
71
|
-
@update:modelValue="emit('update:modelValue', $event)" @submit="runSubmit"
|
|
72
|
-
/>
|
|
73
|
-
<template v-if="onDelete || onSubmit" #footer>
|
|
74
|
-
<div class="flex gap-0">
|
|
75
|
-
<Btn thin flat :value="cancelText || 'Cancel'" @click="closeModal" />
|
|
76
|
-
<Btn
|
|
77
|
-
v-if="onDelete" thin icon="delete" flat :value="deleteText || 'Delete'" color="red"
|
|
78
|
-
@click="runDelete"
|
|
79
|
-
/>
|
|
80
|
-
</div>
|
|
81
|
-
<div class="flex gap-05">
|
|
82
|
-
<Btn
|
|
83
|
-
v-if="onDuplicate" outline class="px-1" icon="copy_all" flat :value="duplicateText || 'Duplicate'"
|
|
84
|
-
@click="onDuplicate?.(formData)"
|
|
85
|
-
/>
|
|
86
|
-
<Btn v-if="onSubmit" :value="submitText || 'Submit'" @click="runSubmit" />
|
|
87
|
-
</div>
|
|
88
|
-
</template>
|
|
89
|
-
</Modal>
|
|
90
|
-
</template>
|
|
91
|
-
|
|
92
|
-
<style scoped>
|
|
93
|
-
.modal-title {
|
|
94
|
-
margin-top: 0.5rem;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
@media screen and (max-width: 910px) {
|
|
98
|
-
.modal-title {
|
|
99
|
-
margin-top: 1rem;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
</style>
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { MaybeRefOrGetter } from 'vue'
|
|
2
|
-
import type { BtnOptions, ThemeType } from '../types'
|
|
3
|
-
import type { BglFormSchemaT } from '../types/BagelForm'
|
|
4
|
-
|
|
5
|
-
export interface ModalOptions {
|
|
6
|
-
title?: string
|
|
7
|
-
dismissable?: boolean
|
|
8
|
-
side?: boolean
|
|
9
|
-
width?: string
|
|
10
|
-
actions?: BtnOptions[]
|
|
11
|
-
class?: string
|
|
12
|
-
visible?: boolean
|
|
13
|
-
zIndex?: number
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ModalConfirmOptions {
|
|
17
|
-
'title': string
|
|
18
|
-
'message': string
|
|
19
|
-
'confirmText'?: string
|
|
20
|
-
'confirmBtnColor'?: ThemeType
|
|
21
|
-
'cancelText'?: string
|
|
22
|
-
'cancelBtnColor'?: ThemeType
|
|
23
|
-
'resolve': (val: boolean) => void
|
|
24
|
-
'onUpdate:visible': () => void
|
|
25
|
-
'visible': boolean
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export type ModalType = 'modal' | 'modalForm' | 'confirmModal'
|
|
29
|
-
export type ConfirmModalUserOptions = string | {
|
|
30
|
-
title: string
|
|
31
|
-
message: string
|
|
32
|
-
confirmText?: string
|
|
33
|
-
cancelText?: string
|
|
34
|
-
confirmBtnColor?: string
|
|
35
|
-
cancelBtnColor?: string
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface ModalComponentProps<T extends { [key: string]: any }> {
|
|
39
|
-
componentSlots: { [key: string]: any }
|
|
40
|
-
modalType: ModalType
|
|
41
|
-
modalOptions: ModalOptions | ModalFormOptions<T> | ModalConfirmOptions
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface ModalFormComponentProps<T extends { [key: string]: any }> extends ModalComponentProps<T> {
|
|
45
|
-
modalType: 'modalForm'
|
|
46
|
-
modalOptions: ModalFormOptions<T>
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface ModalFormOptions<T> extends ModalOptions {
|
|
50
|
-
'schema': MaybeRefOrGetter<BglFormSchemaT<T>>
|
|
51
|
-
'modelValue'?: T
|
|
52
|
-
'onUpdate:modelValue'?: (val: T) => void
|
|
53
|
-
'onSubmit'?: (formData: T) => any
|
|
54
|
-
'onDelete'?: (formData: T) => Promise<void>
|
|
55
|
-
'onDuplicate'?: (formData: T) => Promise<void>
|
|
56
|
-
'submitText'?: string
|
|
57
|
-
'cancelText'?: string
|
|
58
|
-
'deleteText'?: string
|
|
59
|
-
'duplicateText'?: string
|
|
60
|
-
'onError'?: (err: any) => void
|
|
61
|
-
}
|