@g1cloud/bluesea 5.0.0-beta.8 → 6.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/bin/install-claude-skill.mjs +74 -0
- package/css/bluesea.css +12 -30478
- package/dist/index.d.ts +10 -130
- package/dist/index.js +13 -0
- package/package.json +41 -59
- package/skills/bluesea-ui/SKILL.md +345 -0
- package/skills/bluesea-ui/references/components.md +196 -0
- package/skills/bluesea-ui/references/grid.md +159 -0
- package/skills/bluesea-ui/references/i18n.md +149 -0
- package/skills/bluesea-ui/references/validation.md +178 -0
- package/css/frame-default.css +0 -703
- package/dist/BSAlertModal-C8PIj5h_.js +0 -52
- package/dist/BSGridColumnSettingModal-D9CI-F_e.js +0 -149
- package/dist/BSRichTextMaximizedModal-DsSYqgSR.js +0 -62
- package/dist/BSYesNoModal-CB_RIKt0.js +0 -57
- package/dist/BSYoutubeInputModal-CwLcWtEI.js +0 -76
- package/dist/ImageInsertModal-lWQeIMu7.js +0 -106
- package/dist/ImageProperties.vue_vue_type_script_setup_true_lang-DDj0Odaa.js +0 -180
- package/dist/ImagePropertiesModal-C6RyT5B5.js +0 -98
- package/dist/LinkPropertiesModal-D5A3Gq2i.js +0 -119
- package/dist/TableInsertModal-B1F5T8qs.js +0 -74
- package/dist/TablePropertiesModal-DUiHSjcT.js +0 -353
- package/dist/VideoInsertModal-R0Bs5E2T.js +0 -106
- package/dist/VideoProperties.vue_vue_type_script_setup_true_lang-BCTNqg94.js +0 -194
- package/dist/VideoPropertiesModal-DQADTS-J.js +0 -98
- package/dist/YoutubeInsertModal-R97l6ge3.js +0 -84
- package/dist/YoutubeProperties.vue_vue_type_script_setup_true_lang-Ce9a5UDA.js +0 -181
- package/dist/YoutubePropertiesModal-BbrU7l5m.js +0 -102
- package/dist/bluesea.css +0 -11278
- package/dist/bluesea.js +0 -223
- package/dist/bluesea.umd.cjs +0 -72221
- package/dist/component/basic/BSButton.vue.d.ts +0 -50
- package/dist/component/basic/BSCalendar.vue.d.ts +0 -68
- package/dist/component/basic/BSCalendarRange.vue.d.ts +0 -57
- package/dist/component/basic/BSConsole.vue.d.ts +0 -36
- package/dist/component/basic/BSDate.vue.d.ts +0 -19
- package/dist/component/basic/BSFormLabel.vue.d.ts +0 -19
- package/dist/component/basic/BSImage.vue.d.ts +0 -44
- package/dist/component/basic/BSLink.vue.d.ts +0 -21
- package/dist/component/basic/BSLoadingIcon.vue.d.ts +0 -2
- package/dist/component/basic/BSPageNavigation.vue.d.ts +0 -52
- package/dist/component/basic/BSPopup.vue.d.ts +0 -70
- package/dist/component/basic/BSPopupButton.vue.d.ts +0 -41
- package/dist/component/basic/BSProgressBar.vue.d.ts +0 -33
- package/dist/component/basic/BSTooltip.vue.d.ts +0 -35
- package/dist/component/global/AddressSearchButton.vue.d.ts +0 -36
- package/dist/component/global/AddressSearchList.gen.d.ts +0 -4
- package/dist/component/global/BSAddressInput.vue.d.ts +0 -72
- package/dist/component/global/BSLocaleSelect.vue.d.ts +0 -35
- package/dist/component/global/BSNameInput.vue.d.ts +0 -80
- package/dist/component/global/BSTelInput.vue.d.ts +0 -88
- package/dist/component/grid/BSDateRangeFilter.vue.d.ts +0 -63
- package/dist/component/grid/BSDateRangeFilters.vue.d.ts +0 -56
- package/dist/component/grid/BSGrid.vue.d.ts +0 -177
- package/dist/component/grid/BSGridCell.vue.d.ts +0 -85
- package/dist/component/grid/BSGridCellCheckbox.vue.d.ts +0 -21
- package/dist/component/grid/BSGridCellDragHandle.vue.d.ts +0 -15
- package/dist/component/grid/BSGridCellEdit.vue.d.ts +0 -21
- package/dist/component/grid/BSGridCellSerialNo.vue.d.ts +0 -15
- package/dist/component/grid/BSGridColumnSettingModal.vue.d.ts +0 -25
- package/dist/component/grid/BSGridControl.vue.d.ts +0 -78
- package/dist/component/grid/BSGridHeaderCell.vue.d.ts +0 -45
- package/dist/component/grid/BSGridHeaderCellCheckbox.vue.d.ts +0 -19
- package/dist/component/grid/BSGridHeaderCellResizeHandle.vue.d.ts +0 -21
- package/dist/component/grid/BSGridHeaderCellSerialNo.vue.d.ts +0 -2
- package/dist/component/grid/BSGridLookup.vue.d.ts +0 -67
- package/dist/component/grid/BSGridRow.vue.d.ts +0 -140
- package/dist/component/grid/BSTextFilter.vue.d.ts +0 -42
- package/dist/component/grid/DateFilterModel.d.ts +0 -19
- package/dist/component/grid/GridExtension.d.ts +0 -17
- package/dist/component/grid/GridLib.d.ts +0 -21
- package/dist/component/grid/GridModel.d.ts +0 -399
- package/dist/component/grid/extension/gridExcelDownloadExtension.d.ts +0 -22
- package/dist/component/grid/vDndSupport.d.ts +0 -18
- package/dist/component/input/BSCheckbox.vue.d.ts +0 -63
- package/dist/component/input/BSCheckboxGroup.vue.d.ts +0 -79
- package/dist/component/input/BSCodeEditor.vue.d.ts +0 -73
- package/dist/component/input/BSColorInput.vue.d.ts +0 -68
- package/dist/component/input/BSDateInput.vue.d.ts +0 -90
- package/dist/component/input/BSDateInputPopup.vue.d.ts +0 -41
- package/dist/component/input/BSDateRange.vue.d.ts +0 -113
- package/dist/component/input/BSDateRangeInputPopup.vue.d.ts +0 -45
- package/dist/component/input/BSDateRangePresets.vue.d.ts +0 -40
- package/dist/component/input/BSHtmlEditor.vue.d.ts +0 -64
- package/dist/component/input/BSImageUpload.vue.d.ts +0 -118
- package/dist/component/input/BSMediaPreview.vue.d.ts +0 -55
- package/dist/component/input/BSMultiImageUpload.vue.d.ts +0 -108
- package/dist/component/input/BSMultiSelect.vue.d.ts +0 -91
- package/dist/component/input/BSNumberInput.vue.d.ts +0 -91
- package/dist/component/input/BSPopupSelect.vue.d.ts +0 -54
- package/dist/component/input/BSPositionedImageUpload.vue.d.ts +0 -97
- package/dist/component/input/BSPriceInput.vue.d.ts +0 -91
- package/dist/component/input/BSRadioButton.vue.d.ts +0 -72
- package/dist/component/input/BSRadioButtonGroup.vue.d.ts +0 -86
- package/dist/component/input/BSSelect.vue.d.ts +0 -95
- package/dist/component/input/BSSelectPopup.vue.d.ts +0 -87
- package/dist/component/input/BSTextArea.vue.d.ts +0 -88
- package/dist/component/input/BSTextInput.vue.d.ts +0 -100
- package/dist/component/input/BSTreeMultiSelect.vue.d.ts +0 -89
- package/dist/component/input/BSTreeSelect.vue.d.ts +0 -90
- package/dist/component/input/BSYesNoGroup.vue.d.ts +0 -55
- package/dist/component/input/BSYesNoSelect.vue.d.ts +0 -51
- package/dist/component/input/BSYoutubeInputModal.vue.d.ts +0 -6
- package/dist/component/input/DateInputLib.d.ts +0 -27
- package/dist/component/input/DateRangePresetModel.d.ts +0 -16
- package/dist/component/input/HtmlEditorModel.d.ts +0 -5
- package/dist/component/input/ImageUploadLib.d.ts +0 -22
- package/dist/component/input/ImageUploadModel.d.ts +0 -12
- package/dist/component/input/ValidationErrors.vue.d.ts +0 -19
- package/dist/component/input/vDragAndDropSupport.d.ts +0 -10
- package/dist/component/layout/BSCardLayout.vue.d.ts +0 -41
- package/dist/component/layout/BSHorizontalLayoutResizer.vue.d.ts +0 -6
- package/dist/component/layout/BSListControl.vue.d.ts +0 -52
- package/dist/component/layout/BSListLayout.vue.d.ts +0 -85
- package/dist/component/layout/BSListLayoutItem.vue.d.ts +0 -82
- package/dist/component/layout/BSTabSheet.vue.d.ts +0 -63
- package/dist/component/layout/BSVerticalLayoutResizer.vue.d.ts +0 -6
- package/dist/component/layout/SlideDownTransition.vue.d.ts +0 -9
- package/dist/component/layout/TabSheetModel.d.ts +0 -49
- package/dist/component/multilang/BSMultiLangExpandButton.vue.d.ts +0 -2
- package/dist/component/multilang/BSMultiLangHtmlEditor.vue.d.ts +0 -84
- package/dist/component/multilang/BSMultiLangImageUpload.vue.d.ts +0 -81
- package/dist/component/multilang/BSMultiLangRichText.vue.d.ts +0 -93
- package/dist/component/multilang/BSMultiLangTextArea.vue.d.ts +0 -96
- package/dist/component/multilang/BSMultiLangTextInput.vue.d.ts +0 -96
- package/dist/component/multilang/multiLangLib.d.ts +0 -6
- package/dist/component/richtext/BSRichText.vue.d.ts +0 -90
- package/dist/component/richtext/BSRichTextMaximizedModal.vue.d.ts +0 -74
- package/dist/component/richtext/RichTextLib.d.ts +0 -15
- package/dist/component/richtext/RichTextModel.d.ts +0 -9
- package/dist/component/richtext/RichTextToolbar.vue.d.ts +0 -36
- package/dist/component/richtext/image/ImageInsertModal.vue.d.ts +0 -22
- package/dist/component/richtext/image/ImageProperties.vue.d.ts +0 -19
- package/dist/component/richtext/image/ImagePropertiesModal.vue.d.ts +0 -17
- package/dist/component/richtext/image/RichTextImage.d.ts +0 -7
- package/dist/component/richtext/image/RichTextImageLib.d.ts +0 -13
- package/dist/component/richtext/image/ToolButtonImage.vue.d.ts +0 -19
- package/dist/component/richtext/link/LinkPropertiesModal.vue.d.ts +0 -17
- package/dist/component/richtext/link/ToolButtonLink.vue.d.ts +0 -19
- package/dist/component/richtext/richTextUtil.d.ts +0 -18
- package/dist/component/richtext/table/RichTextTable.d.ts +0 -8
- package/dist/component/richtext/table/RichTextTableCell.d.ts +0 -1
- package/dist/component/richtext/table/RichTextTableLib.d.ts +0 -23
- package/dist/component/richtext/table/RichTextTableView.d.ts +0 -19
- package/dist/component/richtext/table/TableInsertModal.vue.d.ts +0 -17
- package/dist/component/richtext/table/TablePropertiesModal.vue.d.ts +0 -17
- package/dist/component/richtext/table/ToolButtonTable.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonFontColor.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonFontSize.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonFontStyle.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonHeading.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonListItem.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonMaximize.vue.d.ts +0 -19
- package/dist/component/richtext/tool/ToolButtonTextAlign.vue.d.ts +0 -19
- package/dist/component/richtext/video/RichTextVideo.d.ts +0 -29
- package/dist/component/richtext/video/RichTextVideoLib.d.ts +0 -16
- package/dist/component/richtext/video/ToolButtonVideo.vue.d.ts +0 -19
- package/dist/component/richtext/video/VideoInsertModal.vue.d.ts +0 -22
- package/dist/component/richtext/video/VideoProperties.vue.d.ts +0 -19
- package/dist/component/richtext/video/VideoPropertiesModal.vue.d.ts +0 -17
- package/dist/component/richtext/youtube/RichTextYoutube.d.ts +0 -8
- package/dist/component/richtext/youtube/RichTextYoutubeLib.d.ts +0 -14
- package/dist/component/richtext/youtube/ToolButtonYoutube.vue.d.ts +0 -19
- package/dist/component/richtext/youtube/YoutubeInsertModal.vue.d.ts +0 -17
- package/dist/component/richtext/youtube/YoutubeProperties.vue.d.ts +0 -19
- package/dist/component/richtext/youtube/YoutubePropertiesModal.vue.d.ts +0 -17
- package/dist/component/tree/BSTree.vue.d.ts +0 -104
- package/dist/component/tree/BSTreeControl.vue.d.ts +0 -90
- package/dist/component/tree/BSTreeRow.vue.d.ts +0 -89
- package/dist/component/tree/TreeLib.d.ts +0 -11
- package/dist/component/tree/TreeModel.d.ts +0 -188
- package/dist/component/tree/vTreeDndSupport.d.ts +0 -10
- package/dist/config/config.d.ts +0 -155
- package/dist/contextmenu/BSContextMenu.vue.d.ts +0 -43
- package/dist/contextmenu/BSContextMenuContainer.vue.d.ts +0 -2
- package/dist/contextmenu/contextMenuPlugin.d.ts +0 -43
- package/dist/directive/vClickOutside.d.ts +0 -21
- package/dist/directive/vFocusJump.d.ts +0 -19
- package/dist/directive/vFocusLoop.d.ts +0 -25
- package/dist/directive/vFocusOnLoad.d.ts +0 -4
- package/dist/directive/vT.d.ts +0 -11
- package/dist/directive/vTooltip.d.ts +0 -9
- package/dist/frame/FrameModel.d.ts +0 -82
- package/dist/frame/ShortcutKeyHandler.d.ts +0 -37
- package/dist/frame/default/DefaultBody.vue.d.ts +0 -2
- package/dist/frame/default/DefaultFrameModel.d.ts +0 -107
- package/dist/frame/default/DefaultHeader.vue.d.ts +0 -23
- package/dist/frame/default/HeaderTab.vue.d.ts +0 -17
- package/dist/frame/default/HeaderTabListButton.vue.d.ts +0 -2
- package/dist/frame/default/HeaderTabs.vue.d.ts +0 -15
- package/dist/frame/default/SidebarMenu.vue.d.ts +0 -2
- package/dist/frame/default/SidebarMenuItem.vue.d.ts +0 -25
- package/dist/frame/default/SidebarMenuLink.vue.d.ts +0 -29
- package/dist/frame/default/SidebarMenuSearch.vue.d.ts +0 -28
- package/dist/index-DRs7QwNQ.js +0 -70174
- package/dist/modal/BSAlertModal.vue.d.ts +0 -23
- package/dist/modal/BSModalContainer.vue.d.ts +0 -2
- package/dist/modal/BSModalFrame.vue.d.ts +0 -37
- package/dist/modal/BSModalWrapper.vue.d.ts +0 -17
- package/dist/modal/BSYesNoModal.vue.d.ts +0 -25
- package/dist/modal/modalPlugin.d.ts +0 -73
- package/dist/model/CommonTypes.d.ts +0 -96
- package/dist/model/DefaultImpl.d.ts +0 -8
- package/dist/model/FieldContext.d.ts +0 -15
- package/dist/model/FilterModel.d.ts +0 -114
- package/dist/model/MoneySerializer.d.ts +0 -3
- package/dist/model/PaginatedList.d.ts +0 -29
- package/dist/model/SearchModel.d.ts +0 -22
- package/dist/notification/BSAlarmFrame.vue.d.ts +0 -26
- package/dist/notification/BSNotificationContainer.vue.d.ts +0 -2
- package/dist/notification/notificationPlugin.d.ts +0 -33
- package/dist/savepoint/SavePoint.d.ts +0 -47
- package/dist/text/i18n.d.ts +0 -28
- package/dist/util/alertUtil.d.ts +0 -1
- package/dist/util/componentUtil.d.ts +0 -40
- package/dist/util/debounceUtil.d.ts +0 -16
- package/dist/util/elementUtil.d.ts +0 -58
- package/dist/util/formatUtil.d.ts +0 -70
- package/dist/util/langUtil.d.ts +0 -3
- package/dist/util/multiLangUtil.d.ts +0 -27
- package/dist/util/routeUtil.d.ts +0 -3
- package/dist/util/typeUtil.d.ts +0 -18
- package/dist/util/waitUtil.d.ts +0 -19
- package/dist/validator/FieldValidator.d.ts +0 -45
- package/dist/validator/FormValidator.d.ts +0 -35
- package/scss/bluesea-base.scss +0 -6
- package/scss/bluesea.scss +0 -2
- package/scss/component.scss +0 -515
- package/scss/font.scss +0 -3
- package/scss/frame/default.scss +0 -293
- package/scss/layout.scss +0 -192
- package/scss/reset.scss +0 -68
- package/scss/rich-text-container.scss +0 -113
- package/scss/rich-text-content.scss +0 -137
- package/scss/transition.scss +0 -108
- package/scss/utility.scss +0 -816
- package/scss/variable.scss +0 -347
- package/text/bluesea_text_en.json +0 -956
- package/text/bluesea_text_fr.json +0 -956
- package/text/bluesea_text_ja.json +0 -956
- package/text/bluesea_text_ko.json +0 -956
- package/text/bluesea_text_zh.json +0 -956
package/dist/index.d.ts
CHANGED
|
@@ -1,130 +1,10 @@
|
|
|
1
|
-
export
|
|
2
|
-
export * from '
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
export
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export { default as BSConsole } from './component/basic/BSConsole.vue';
|
|
12
|
-
export { default as BSLoadingIcon } from './component/basic/BSLoadingIcon.vue';
|
|
13
|
-
export { default as BSDate } from './component/basic/BSDate.vue';
|
|
14
|
-
export { default as BSPageNavigation } from './component/basic/BSPageNavigation.vue';
|
|
15
|
-
export { default as BSCalendar } from './component/basic/BSCalendar.vue';
|
|
16
|
-
export { default as BSCalendarRange } from './component/basic/BSCalendarRange.vue';
|
|
17
|
-
export { default as BSNumberInput } from './component/input/BSNumberInput.vue';
|
|
18
|
-
export { default as BSPriceInput } from './component/input/BSPriceInput.vue';
|
|
19
|
-
export { default as BSColorInput } from './component/input/BSColorInput.vue';
|
|
20
|
-
export { default as BSDateInput } from './component/input/BSDateInput.vue';
|
|
21
|
-
export { default as BSDateRange } from './component/input/BSDateRange.vue';
|
|
22
|
-
export { default as BSDateRangePresets } from './component/input/BSDateRangePresets.vue';
|
|
23
|
-
export { default as BSCheckbox } from './component/input/BSCheckbox.vue';
|
|
24
|
-
export { default as BSCheckboxGroup } from './component/input/BSCheckboxGroup.vue';
|
|
25
|
-
export { default as BSRadioButton } from './component/input/BSRadioButton.vue';
|
|
26
|
-
export { default as BSRadioButtonGroup } from './component/input/BSRadioButtonGroup.vue';
|
|
27
|
-
export { default as BSYesNoGroup } from './component/input/BSYesNoGroup.vue';
|
|
28
|
-
export { default as BSSelect } from './component/input/BSSelect.vue';
|
|
29
|
-
export { default as BSMultiSelect } from './component/input/BSMultiSelect.vue';
|
|
30
|
-
export { default as BSTreeSelect } from './component/input/BSTreeSelect.vue';
|
|
31
|
-
export { default as BSTreeMultiSelect } from './component/input/BSTreeMultiSelect.vue';
|
|
32
|
-
export { default as BSPopupSelect } from './component/input/BSPopupSelect.vue';
|
|
33
|
-
export { default as BSTextArea } from './component/input/BSTextArea.vue';
|
|
34
|
-
export { default as BSRichText } from './component/richtext/BSRichText.vue';
|
|
35
|
-
export type * from './component/richtext/RichTextModel';
|
|
36
|
-
export { Editor } from '@tiptap/core';
|
|
37
|
-
export type * from './component/input/ImageUploadModel';
|
|
38
|
-
export * from './component/input/ImageUploadModel';
|
|
39
|
-
export { default as BSImageUpload } from './component/input/BSImageUpload.vue';
|
|
40
|
-
export { default as BSMultiImageUpload } from './component/input/BSMultiImageUpload.vue';
|
|
41
|
-
export { default as BSPositionedImageUpload } from './component/input/BSPositionedImageUpload.vue';
|
|
42
|
-
export { default as BSGrid } from './component/grid/BSGrid.vue';
|
|
43
|
-
export * from './component/grid/GridModel';
|
|
44
|
-
export * from './component/grid/GridExtension';
|
|
45
|
-
export * from './component/grid/extension/gridExcelDownloadExtension';
|
|
46
|
-
export type * from './component/grid/GridModel';
|
|
47
|
-
export { default as BSGridLookup } from './component/grid/BSGridLookup.vue';
|
|
48
|
-
export { default as BSGridControl } from './component/grid/BSGridControl.vue';
|
|
49
|
-
export type * from './component/grid/DateFilterModel';
|
|
50
|
-
export * from './component/grid/DateFilterModel';
|
|
51
|
-
export { default as BSTextFilter } from './component/grid/BSTextFilter.vue';
|
|
52
|
-
export { default as BSDateRangeFilter } from './component/grid/BSDateRangeFilter.vue';
|
|
53
|
-
export { default as BSDateRangeFilters } from './component/grid/BSDateRangeFilters.vue';
|
|
54
|
-
export { default as BSCardLayout } from './component/layout/BSCardLayout.vue';
|
|
55
|
-
export { default as BSTabSheet } from './component/layout/BSTabSheet.vue';
|
|
56
|
-
export { default as BSListLayout } from './component/layout/BSListLayout.vue';
|
|
57
|
-
export { default as BSListControl } from './component/layout/BSListControl.vue';
|
|
58
|
-
export type * from './component/layout/TabSheetModel';
|
|
59
|
-
export * from './component/layout/TabSheetModel';
|
|
60
|
-
export { default as BSHorizontalLayoutResizer } from './component/layout/BSHorizontalLayoutResizer.vue';
|
|
61
|
-
export { default as BSVerticalLayoutResizer } from './component/layout/BSVerticalLayoutResizer.vue';
|
|
62
|
-
export { default as BSTree } from './component/tree/BSTree.vue';
|
|
63
|
-
export type * from './component/tree/TreeModel';
|
|
64
|
-
export * from './component/tree/TreeModel';
|
|
65
|
-
export { default as BSTreeControl } from './component/tree/BSTreeControl.vue';
|
|
66
|
-
export { default as BSMultiLangTextInput } from './component/multilang/BSMultiLangTextInput.vue';
|
|
67
|
-
export { default as BSMultiLangTextArea } from './component/multilang/BSMultiLangTextArea.vue';
|
|
68
|
-
export { default as BSMultiLangRichText } from './component/multilang/BSMultiLangRichText.vue';
|
|
69
|
-
export { default as BSMultiLangExpandButton } from './component/multilang/BSMultiLangExpandButton.vue';
|
|
70
|
-
export { default as BSMultiLangImageUpload } from './component/multilang/BSMultiLangImageUpload.vue';
|
|
71
|
-
export { default as BSMultiLangHtmlEditor } from './component/multilang/BSMultiLangHtmlEditor.vue';
|
|
72
|
-
export * from './component/multilang/multiLangLib';
|
|
73
|
-
export { default as BSLocaleSelect } from './component/global/BSLocaleSelect.vue';
|
|
74
|
-
export { default as BSNameInput } from './component/global/BSNameInput.vue';
|
|
75
|
-
export { default as BSTelInput } from './component/global/BSTelInput.vue';
|
|
76
|
-
export { default as BSAddressInput } from './component/global/BSAddressInput.vue';
|
|
77
|
-
export { default as BSImage } from './component/basic/BSImage.vue';
|
|
78
|
-
export type * from './component/input/ImageUploadModel';
|
|
79
|
-
export { default as BSCodeEditor } from './component/input/BSCodeEditor.vue';
|
|
80
|
-
export { default as BSHtmlEditor } from './component/input/BSHtmlEditor.vue';
|
|
81
|
-
export type * from './component/input/HtmlEditorModel';
|
|
82
|
-
export { default as BSPopup } from './component/basic/BSPopup.vue';
|
|
83
|
-
export { default as BSSelectPopup } from './component/input/BSSelectPopup.vue';
|
|
84
|
-
export { default as BSDateInputPopup } from './component/input/BSDateInputPopup.vue';
|
|
85
|
-
export { default as BSDateRangeInputPopup } from './component/input/BSDateRangeInputPopup.vue';
|
|
86
|
-
export type * from './validator/FormValidator';
|
|
87
|
-
export * from './validator/FormValidator';
|
|
88
|
-
export type * from './validator/FieldValidator';
|
|
89
|
-
export * from './validator/FieldValidator';
|
|
90
|
-
export * from './savepoint/SavePoint';
|
|
91
|
-
export type * from './model/CommonTypes';
|
|
92
|
-
export * from './model/CommonTypes';
|
|
93
|
-
export * from './model/PaginatedList';
|
|
94
|
-
export type * from './model/FilterModel';
|
|
95
|
-
export * from './model/FilterModel';
|
|
96
|
-
export * from './model/SearchModel';
|
|
97
|
-
export type * from './model/SearchModel';
|
|
98
|
-
export * from './model/FieldContext';
|
|
99
|
-
export type * from './model/FieldContext';
|
|
100
|
-
export { default as BSModalContainer } from './modal/BSModalContainer.vue';
|
|
101
|
-
export { default as BSModalFrame } from './modal/BSModalFrame.vue';
|
|
102
|
-
export * from './modal/modalPlugin';
|
|
103
|
-
export type * from './modal/modalPlugin';
|
|
104
|
-
export { default as BSNotificationContainer } from './notification/BSNotificationContainer.vue';
|
|
105
|
-
export * from './notification/notificationPlugin';
|
|
106
|
-
export type * from './notification/notificationPlugin';
|
|
107
|
-
export { default as BSAlarmFrame } from './notification/BSAlarmFrame.vue';
|
|
108
|
-
export { default as BSContextMenuContainer } from './contextmenu/BSContextMenuContainer.vue';
|
|
109
|
-
export * from './contextmenu/contextMenuPlugin';
|
|
110
|
-
export type * from './contextmenu/contextMenuPlugin';
|
|
111
|
-
export * from './frame/FrameModel';
|
|
112
|
-
export type * from './frame/FrameModel';
|
|
113
|
-
export { default as DefaultHeader } from './frame/default/DefaultHeader.vue';
|
|
114
|
-
export { default as DefaultBody } from './frame/default/DefaultBody.vue';
|
|
115
|
-
export type * from './frame/default/DefaultFrameModel';
|
|
116
|
-
export * from './frame/default/DefaultFrameModel';
|
|
117
|
-
export * from './frame/ShortcutKeyHandler';
|
|
118
|
-
export * from './text/i18n';
|
|
119
|
-
export { default as vClickOutside } from './directive/vClickOutside';
|
|
120
|
-
export { default as vT, interpretMultiLangText } from './directive/vT';
|
|
121
|
-
export { default as vTooltip } from './directive/vTooltip';
|
|
122
|
-
export { default as vFocusOnLoad } from './directive/vFocusOnLoad';
|
|
123
|
-
export { default as vFocusJump } from './directive/vFocusJump';
|
|
124
|
-
export { default as vFocusLoop } from './directive/vFocusLoop';
|
|
125
|
-
export * from './util/typeUtil';
|
|
126
|
-
export * from './util/formatUtil';
|
|
127
|
-
export * from './util/waitUtil';
|
|
128
|
-
export * from './util/routeUtil';
|
|
129
|
-
export * from './util/multiLangUtil';
|
|
130
|
-
export * from './util/debounceUtil';
|
|
1
|
+
export * from '@g1cloud/bluesea-core';
|
|
2
|
+
export * from '@g1cloud/bluesea-basic';
|
|
3
|
+
export * from '@g1cloud/bluesea-input';
|
|
4
|
+
export * from '@g1cloud/bluesea-grid';
|
|
5
|
+
export * from '@g1cloud/bluesea-tree';
|
|
6
|
+
export * from '@g1cloud/bluesea-richtext';
|
|
7
|
+
export * from '@g1cloud/bluesea-global';
|
|
8
|
+
export * from '@g1cloud/bluesea-frame';
|
|
9
|
+
export type { DndContext } from '@g1cloud/bluesea-core';
|
|
10
|
+
export { vDragSupport, vDropSupport } from '@g1cloud/bluesea-input';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from "@g1cloud/bluesea-core";
|
|
2
|
+
export * from "@g1cloud/bluesea-basic";
|
|
3
|
+
export * from "@g1cloud/bluesea-input";
|
|
4
|
+
import { vDragSupport, vDropSupport } from "@g1cloud/bluesea-input";
|
|
5
|
+
export * from "@g1cloud/bluesea-grid";
|
|
6
|
+
export * from "@g1cloud/bluesea-tree";
|
|
7
|
+
export * from "@g1cloud/bluesea-richtext";
|
|
8
|
+
export * from "@g1cloud/bluesea-global";
|
|
9
|
+
export * from "@g1cloud/bluesea-frame";
|
|
10
|
+
export {
|
|
11
|
+
vDragSupport,
|
|
12
|
+
vDropSupport
|
|
13
|
+
};
|
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@g1cloud/bluesea",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"description": "Ui Library for g1cloud BackOffice.",
|
|
3
|
+
"version": "6.0.0-alpha.0",
|
|
4
|
+
"description": "Ui Library for g1cloud BackOffice. (meta package — re-exports all bluesea packages)",
|
|
6
5
|
"type": "module",
|
|
7
6
|
"engines": {
|
|
8
7
|
"node": ">= 20.10.0"
|
|
@@ -12,69 +11,52 @@
|
|
|
12
11
|
"files": [
|
|
13
12
|
"dist",
|
|
14
13
|
"css",
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
14
|
+
"!dist/tests",
|
|
15
|
+
"skills",
|
|
16
|
+
"bin"
|
|
18
17
|
],
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"types": "dist/index.d.ts",
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"
|
|
28
|
-
"@tiptap/core": "^2.8.0",
|
|
29
|
-
"@tiptap/extension-color": "^2.8.0",
|
|
30
|
-
"@tiptap/extension-image": "^2.8.0",
|
|
31
|
-
"@tiptap/extension-link": "^2.8.0",
|
|
32
|
-
"@tiptap/extension-table": "^2.8.0",
|
|
33
|
-
"@tiptap/extension-table-cell": "^2.8.0",
|
|
34
|
-
"@tiptap/extension-table-header": "^2.8.0",
|
|
35
|
-
"@tiptap/extension-table-row": "^2.8.0",
|
|
36
|
-
"@tiptap/extension-text-align": "^2.8.0",
|
|
37
|
-
"@tiptap/extension-text-style": "^2.8.0",
|
|
38
|
-
"@tiptap/extension-youtube": "^2.8.0",
|
|
39
|
-
"@tiptap/pm": "^2.8.0",
|
|
40
|
-
"@tiptap/starter-kit": "^2.8.0",
|
|
41
|
-
"@tiptap/vue-3": "^2.8.0",
|
|
42
|
-
"@vue/shared": "^3.5.13",
|
|
43
|
-
"codemirror": "^6.0.1",
|
|
44
|
-
"dayjs": "^1.11.13",
|
|
45
|
-
"tiptap-extension-font-size": "^1.2.0",
|
|
46
|
-
"vue": "^3.5.13",
|
|
47
|
-
"vue-codemirror": "^6.1.1",
|
|
48
|
-
"vue-router": "^4.5.0",
|
|
49
|
-
"xlsx": "^0.18.5"
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"module": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./css/*": "./css/*"
|
|
50
27
|
},
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"@
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"vue-tsc": "^2.2.8"
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@g1cloud/bluesea-tree": "^6.0.0-alpha.0",
|
|
33
|
+
"@g1cloud/bluesea-basic": "^6.0.0-alpha.0",
|
|
34
|
+
"@g1cloud/bluesea-input": "^6.0.0-alpha.0",
|
|
35
|
+
"@g1cloud/bluesea-grid": "^6.0.0-alpha.0",
|
|
36
|
+
"@g1cloud/bluesea-core": "^6.0.0-alpha.0",
|
|
37
|
+
"@g1cloud/bluesea-richtext": "^6.0.0-alpha.0",
|
|
38
|
+
"@g1cloud/bluesea-frame": "^6.0.0-alpha.0",
|
|
39
|
+
"@g1cloud/bluesea-global": "^6.0.0-alpha.0"
|
|
64
40
|
},
|
|
65
41
|
"peerDependencies": {
|
|
66
|
-
"dayjs": "^1.11.11",
|
|
67
42
|
"vue": "^3.5.13",
|
|
68
43
|
"vue-router": "^4.3.2",
|
|
69
|
-
"
|
|
44
|
+
"dayjs": "^1.11.11"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"vue": "^3.5.13",
|
|
48
|
+
"vue-router": "^4.5.0",
|
|
49
|
+
"dayjs": "^1.11.11",
|
|
50
|
+
"@types/node": "^24.0.0",
|
|
51
|
+
"typescript": "~5.9.3",
|
|
52
|
+
"vite": "^7.0.0",
|
|
53
|
+
"vite-plugin-dts": "^5.0.3",
|
|
54
|
+
"vitest": "^4.1.9",
|
|
55
|
+
"vue-tsc": "^3.3.6"
|
|
70
56
|
},
|
|
71
57
|
"scripts": {
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"build:scss": "sass scss/bluesea.scss:css/bluesea.css scss/frame/default.scss:css/frame-default.css --no-source-map",
|
|
76
|
-
"preview": "vite preview",
|
|
77
|
-
"test": "vitest",
|
|
78
|
-
"generate-bluesea-message": "node ./tool/generateBlueseaMessage.js"
|
|
58
|
+
"build": "vue-tsc && vite build",
|
|
59
|
+
"test": "vitest run --passWithNoTests",
|
|
60
|
+
"install-claude-skill": "node bin/install-claude-skill.mjs"
|
|
79
61
|
}
|
|
80
62
|
}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bluesea-ui
|
|
3
|
+
description: Build g1cloud BackOffice UIs with @g1cloud/bluesea Vue 3 v6 — covers app bootstrap (createBluesea + pinia), composables (useBlueseaConfig, useTexts, useNotification, useModal), BS* components (BSButton, BSTextInput, BSGrid, BSSelect, BSModal), FieldValidator/FormValidator pattern, MultiLangText + i18n, SavePoint for inline edits, and DefaultFrame shell. Use this skill whenever the user works in a project that imports from "@g1cloud/bluesea" or mentions any BS* component, BSGrid, BSModal, createBluesea, useBlueseaConfig, useTexts, useNotification, useModal, MultiLangText, FieldValidator, formValidator, ValidationFailedError, SavePoint, or DefaultFrame — even when they only show a Vue snippet without naming the library. Also apply when the user asks about Bluesea, 블루씨, g1cloud BackOffice UI, or pastes code using <BSButton>, <BSTextInput>, <BSGrid>, etc.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# @g1cloud/bluesea v6 — Vue 3 UI library for g1cloud BackOffice
|
|
7
|
+
|
|
8
|
+
Bluesea v6 is an enterprise-focused Vue 3 component library with SSR support via Nuxt and Tailwind CSS v4 styling. Its design goals shape every API in this skill, so read them first — the patterns that look unusual usually follow from here:
|
|
9
|
+
|
|
10
|
+
- **Strict types.** Every component has explicit prop types. Prefer `<script setup lang="ts">` with `defineProps<{...}>()`. Don't invent loose props.
|
|
11
|
+
- **Unidirectional data flow.** Props down, `update:xxx` events up. Two-way binding is always `v-model:xxx`.
|
|
12
|
+
- **i18n-first.** Almost every text prop (caption, placeholder, tooltip, error message) accepts `MultiLangText`, not just `string`. See "MultiLangText" below.
|
|
13
|
+
- **Inversion of control.** Components expose scoped slots + extension hooks. Don't fork the component — fill the slot or pass an extension.
|
|
14
|
+
- **Validation is a first-class concern.** Inputs register themselves with a `FormValidator`. Submit handlers throw `ValidationFailedError`. See "Validation".
|
|
15
|
+
|
|
16
|
+
When you are unsure about a component's props, read the `.vue` file directly at `packages/<package>/src/component/<group>/<Name>.vue` — the `defineProps<{...}>()` block is the source of truth. This is faster and more reliable than guessing. Packages are: core, basic, input, grid, tree, richtext, global, frame.
|
|
17
|
+
|
|
18
|
+
## 1. Project bootstrap
|
|
19
|
+
|
|
20
|
+
### Vite SPA
|
|
21
|
+
|
|
22
|
+
Every Bluesea app calls `createBluesea(...)` after `createPinia()` and before `.mount()`. A realistic `main.ts` looks like this (trim to what you need):
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
import { createApp } from 'vue'
|
|
26
|
+
import { createPinia } from 'pinia'
|
|
27
|
+
import { createBluesea } from '@g1cloud/bluesea'
|
|
28
|
+
import '@g1cloud/bluesea/css/bluesea.css'
|
|
29
|
+
import '@g1cloud/bluesea/css/frame-default.css' // only if you use DefaultFrame
|
|
30
|
+
import App from './App.vue'
|
|
31
|
+
|
|
32
|
+
const app = createApp(App)
|
|
33
|
+
app.use(createPinia()) // Must come before createBluesea
|
|
34
|
+
app.use(createBluesea({
|
|
35
|
+
locales: ['ko', 'en', 'ja'],
|
|
36
|
+
defaultLocale: 'ko',
|
|
37
|
+
currentLocale: 'ko',
|
|
38
|
+
dataLocales: ['ko', 'en', 'ja'], // used by BSMultiLang* inputs
|
|
39
|
+
currentDataLocale: 'ko',
|
|
40
|
+
timeZone: 'Asia/Seoul',
|
|
41
|
+
dateFormat: 'YYYY-MM-DD HH:mm',
|
|
42
|
+
defaultCurrencyCode: 'KRW',
|
|
43
|
+
extended: {
|
|
44
|
+
gridPreferenceStore: new LocalStorageGridPreferenceStore(browserStorage), // persists BSGrid column widths/order
|
|
45
|
+
fileUrlResolver: (url) => url?.startsWith('http') ? url : `https://cdn.example.com/${url}`,
|
|
46
|
+
componentConfig: {
|
|
47
|
+
telInput: { requiredCountryNo: true, countries: [{ code: 'KR', name: 'Korea (+82)' }] },
|
|
48
|
+
addressInput:{ countries: [{ code: 'KR', name: 'Korea' }] },
|
|
49
|
+
calendar: { startYear: '-40', endYear: '+40' }, // relative to this year
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}))
|
|
53
|
+
|
|
54
|
+
app.mount('#app')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
You must also mount the container components somewhere near the app root — they are the portals the plugins render into:
|
|
58
|
+
|
|
59
|
+
```vue
|
|
60
|
+
<template>
|
|
61
|
+
<router-view />
|
|
62
|
+
<BSModalContainer />
|
|
63
|
+
<BSNotificationContainer />
|
|
64
|
+
<BSContextMenuContainer />
|
|
65
|
+
</template>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Global state lives on reactive composables; call `useBlueseaConfig()` to access config and `useBlueseaConfig().setCurrentLocale('en')` to switch language at runtime.
|
|
69
|
+
|
|
70
|
+
### Nuxt 4
|
|
71
|
+
|
|
72
|
+
With Nuxt, one module line handles everything (pinia, plugin, auto-import, CSS, richtext client-only):
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
// nuxt.config.ts
|
|
76
|
+
export default defineNuxtConfig({
|
|
77
|
+
modules: ['@g1cloud/bluesea-nuxt'],
|
|
78
|
+
bluesea: {
|
|
79
|
+
locales: ['ko', 'en', 'ja'],
|
|
80
|
+
defaultLocale: 'ko',
|
|
81
|
+
currentLocale: 'ko',
|
|
82
|
+
timeZone: 'Asia/Seoul',
|
|
83
|
+
dateFormat: 'YYYY-MM-DD HH:mm',
|
|
84
|
+
},
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The containers are auto-mounted. No manual `createBluesea()` call needed — the Nuxt module does it.
|
|
89
|
+
|
|
90
|
+
## 2. MultiLangText (almost every text prop)
|
|
91
|
+
|
|
92
|
+
`MultiLangText` is the union that lets captions be either a plain string, a per-locale record, or an i18n key with args:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
type MultiLangText =
|
|
96
|
+
| string // plain — 'Save'
|
|
97
|
+
| Record<LocaleName, string> // per-locale — { ko: '저장', en: 'Save' }
|
|
98
|
+
| { key: string; args?: unknown[] } // i18n key — { key: 'btn.save' }
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Use i18n keys by default in real apps so the UI follows the user's locale. Register texts with `useTexts()` (or `i18n.addTexts(locale, [...])` on core import) and render them with the `t()` helper or interpolation:
|
|
102
|
+
|
|
103
|
+
```ts
|
|
104
|
+
import { useTexts } from '@g1cloud/bluesea'
|
|
105
|
+
|
|
106
|
+
const { t, addTexts } = useTexts()
|
|
107
|
+
|
|
108
|
+
// Register once in setup
|
|
109
|
+
addTexts('ko', [{ key: 'btn.save', text: '저장' }])
|
|
110
|
+
addTexts('en', [{ key: 'btn.save', text: 'Save' }])
|
|
111
|
+
|
|
112
|
+
// Use the t() helper
|
|
113
|
+
const label = t({ key: 'btn.save' }) // resolves to 'Save' or '저장'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
In templates, use interpolation instead of `v-t` directive (removed in v6 for SSR):
|
|
117
|
+
|
|
118
|
+
```vue
|
|
119
|
+
<span>{{ t({ key: 'label.name' }) }}</span>
|
|
120
|
+
<BSButton :caption="{ key: 'btn.save' }" />
|
|
121
|
+
<input :placeholder="t({ key: 'ph.name' })" />
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
When the user gives you a Korean/English string literal in demo code, pass it through as-is — components accept a plain string too. For library code that will be reused across locales, prefer keys.
|
|
125
|
+
|
|
126
|
+
## 3. Components — what exists and when to reach for it
|
|
127
|
+
|
|
128
|
+
All components come from the single package entry: `import { BSxxx } from '@g1cloud/bluesea'`. There is **no** subpath import. Types and helpers are exported from the same entry.
|
|
129
|
+
|
|
130
|
+
| Need | Component |
|
|
131
|
+
|---|---|
|
|
132
|
+
| Button / link / router-link | `BSButton` (buttonColor: default/blue/red/orange/green/gray; linkUrl, routePath) |
|
|
133
|
+
| Plain text input | `BSTextInput` (validation: required, minLength, maxLength, regExp, extraValidationRules) |
|
|
134
|
+
| Number / price / percent | `BSNumberInput`, `BSPriceInput`, `BSPercentInput` |
|
|
135
|
+
| Date / date range | `BSDateInput`, `BSDateRange`, `BSCalendar`, `BSCalendarRange`, `BSDateRangePresets` |
|
|
136
|
+
| Select | `BSSelect`, `BSMultiSelect`, `BSTreeSelect`, `BSTreeMultiSelect`, `BSPopupSelect`, `BSYesNoSelect` |
|
|
137
|
+
| Checkbox / radio | `BSCheckbox`, `BSCheckboxGroup`, `BSRadioButton`, `BSRadioButtonGroup`, `BSYesNoGroup` |
|
|
138
|
+
| Textarea / rich text / HTML editor / code editor | `BSTextArea`, `BSRichText`, `BSHtmlEditor`, `BSCodeEditor` |
|
|
139
|
+
| File / image upload | `BSFileUpload`, `BSImageUpload`, `BSMultiImageUpload`, `BSPositionedImageUpload` |
|
|
140
|
+
| Data grid | `BSGrid` + `BSGridControl` + `BSGridLookup` (see §6) |
|
|
141
|
+
| Layout | `BSCardLayout`, `BSListLayout`, `BSTabSheet`, `BSHorizontalLayoutResizer`, `BSVerticalLayoutResizer` |
|
|
142
|
+
| Tree | `BSTree`, `BSTreeControl` |
|
|
143
|
+
| Multi-language inputs | `BSMultiLangTextInput`, `BSMultiLangTextArea`, `BSMultiLangRichText`, `BSMultiLangHtmlEditor`, `BSMultiLangImageUpload` |
|
|
144
|
+
| Global entities | `BSNameInput`, `BSTelInput`, `BSAddressInput`, `BSLocaleSelect` |
|
|
145
|
+
| Popup / tooltip | `BSPopup`, `BSPopupButton`, plus `vTooltip` directive (via `createTooltipDirective()`) |
|
|
146
|
+
| Frame shell | `DefaultHeader`, `DefaultBody` (BackOffice app chrome) |
|
|
147
|
+
| Icon | `BSIcon` (SVG-based, replaces icon font) |
|
|
148
|
+
|
|
149
|
+
Prop naming is consistent across inputs: `v-model` for the value, `name` (required for validation), `disabled`, `required`, `width` ('200px' by default), `placeholder`, `viewMode` (read-only display), `hideErrorMessage`. Date inputs add `dateFormat`, `timeZone`. Upload inputs take `StoredFile` / `StoredFile[]`.
|
|
150
|
+
|
|
151
|
+
Typical usage:
|
|
152
|
+
|
|
153
|
+
```vue
|
|
154
|
+
<BSFormLabel label="이름" required />
|
|
155
|
+
<BSTextInput v-model="form.name" name="name" required :max-length="50" />
|
|
156
|
+
|
|
157
|
+
<BSFormLabel label="등급" />
|
|
158
|
+
<BSSelect v-model="form.grade" name="grade"
|
|
159
|
+
:items="grades" :label-provider="g => g.label" :key-provider="g => g.id" />
|
|
160
|
+
|
|
161
|
+
<BSButton :caption="{ key: 'btn.save' }" button-color="blue" @click="handleSave" />
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
When you need a component that this table doesn't list, check `packages/bluesea/src/index.ts` for the full export list before assuming it doesn't exist. Use the demo pages under `packages/bluesea-demo/src/page/guide/BS*Guide.vue` as copy-paste-ready examples — they are the canonical "how do I use this component" reference.
|
|
165
|
+
|
|
166
|
+
## 4. Modals and notifications
|
|
167
|
+
|
|
168
|
+
The modal system is pinia-based. `useModal()` gives you `openModal`, `openAlert`, `openYesNo`; each returns a `RegisteredModalItem` whose `modalHandle.close()` programmatically closes it. Modals are plain Vue components — pass props via `bind`, listen to events via `on`.
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { useModal, useNotification } from '@g1cloud/bluesea'
|
|
172
|
+
|
|
173
|
+
const modal = useModal()
|
|
174
|
+
const { showNotification } = useNotification()
|
|
175
|
+
|
|
176
|
+
modal.openAlert('알림', '저장되었습니다.')
|
|
177
|
+
|
|
178
|
+
modal.openYesNo('삭제', '정말 삭제할까요?',
|
|
179
|
+
async () => { await api.delete(id) },
|
|
180
|
+
() => { /* cancelled */ })
|
|
181
|
+
|
|
182
|
+
// custom component
|
|
183
|
+
const handle = modal.openModal({
|
|
184
|
+
component: EditUserModal,
|
|
185
|
+
style: { width: '600px', resizable: true },
|
|
186
|
+
bind: { userId: 123 },
|
|
187
|
+
on: { submit: (user) => { console.log(user); handle.modalHandle.close() } },
|
|
188
|
+
})
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Inside the modal component, call `useModalHandle()` to get the same handle (`handle.close()`, `setDefaultStyle()`, etc.).
|
|
192
|
+
|
|
193
|
+
Toast-style messages go through `notification.showNotification(message, style, durationMs)` where `style` is `'info' | 'error'`. Longer-lived "alarm" overlays use `notification.showAlarm(component, duration)`. For a global spinner during async work:
|
|
194
|
+
|
|
195
|
+
```ts
|
|
196
|
+
await notification.withLoading(async () => {
|
|
197
|
+
await api.save(form)
|
|
198
|
+
notification.showNotification({ key: 'msg.saved' })
|
|
199
|
+
})
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## 5. Validation (the most distinctive Bluesea pattern)
|
|
203
|
+
|
|
204
|
+
Every input that takes a `name` prop auto-registers a `FieldValidator` on its DOM element. A `FormValidator` walks the DOM of a given root element, collects every registered `FieldValidator`, and runs validation. This means you do **not** wire up validators manually per field — you just give each field a `name` and scope a `FormValidator` to your form root.
|
|
205
|
+
|
|
206
|
+
```vue
|
|
207
|
+
<template>
|
|
208
|
+
<div ref="formEl">
|
|
209
|
+
<BSTextInput v-model="form.email" name="email" required
|
|
210
|
+
reg-exp="^[^@]+@[^@]+$"
|
|
211
|
+
:validation-message-reg-exp="{ key: 'err.email' }" />
|
|
212
|
+
<BSNumberInput v-model="form.age" name="age" :min-value="0" :max-value="150" />
|
|
213
|
+
<BSButton caption="저장" @click="save" />
|
|
214
|
+
</div>
|
|
215
|
+
</template>
|
|
216
|
+
|
|
217
|
+
<script setup lang="ts">
|
|
218
|
+
import { ref } from 'vue'
|
|
219
|
+
import { formValidator, ValidationFailedError, isValidationFailedError } from '@g1cloud/bluesea'
|
|
220
|
+
import { useNotification } from '@g1cloud/bluesea'
|
|
221
|
+
|
|
222
|
+
const formEl = ref<HTMLElement>()
|
|
223
|
+
const form = ref({ email: '', age: 0 })
|
|
224
|
+
const { showNotification } = useNotification()
|
|
225
|
+
|
|
226
|
+
const validator = formValidator({
|
|
227
|
+
element: formEl,
|
|
228
|
+
rules: [
|
|
229
|
+
async () => form.value.age < 18
|
|
230
|
+
? [{ code: 'tooYoung', message: { key: 'err.adultOnly' } }]
|
|
231
|
+
: undefined,
|
|
232
|
+
],
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
async function save() {
|
|
236
|
+
try {
|
|
237
|
+
await validator.validate() // throws ValidationFailedError on failure
|
|
238
|
+
await api.save(form.value)
|
|
239
|
+
showNotification({ key: 'msg.saved' }, 'info')
|
|
240
|
+
} catch (e) {
|
|
241
|
+
if (isValidationFailedError(e)) {
|
|
242
|
+
showNotification({ key: 'err.validationFailed' }, 'error')
|
|
243
|
+
return
|
|
244
|
+
}
|
|
245
|
+
throw e
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
</script>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Built-in rules on inputs: `required`, `minLength` / `maxLength`, `regExp`, `minValue` / `maxValue`, `validation-message-*` overrides for each rule. For custom rules, pass `:extra-validation-rules` — an array of `(value, phase, fieldContext) => ValidationError[] | undefined`. `phase` is `'input' | 'change' | 'blur' | 'form'`, so you can defer expensive async checks to `'blur'` or `'form'` only.
|
|
252
|
+
|
|
253
|
+
`ValidationError` is `{ code: string; message: MultiLangText }`. `ValidationFailedError.errors` is an array that includes the field `name`, so you can highlight specific fields if needed.
|
|
254
|
+
|
|
255
|
+
## 6. BSGrid
|
|
256
|
+
|
|
257
|
+
BSGrid is the workhorse for data tables. Prefer the `createPageGridHandler` factory when you need paging + server-side sorting/filtering — it wires `grid`, `gridEventListener`, `control`, `controlEventListener`, `lookup`, `lookupEventListener` together for you. For simple client-side tables, use `BSGrid` directly with `:columns` + `:data`.
|
|
258
|
+
|
|
259
|
+
```vue
|
|
260
|
+
<BSGridLookup v-bind="gridHandler.lookup" v-on="gridHandler.lookupEventListener" :config="lookupConfig" />
|
|
261
|
+
<BSGridControl v-bind="gridHandler.control" v-on="gridHandler.controlEventListener" />
|
|
262
|
+
<BSGrid v-bind="gridHandler.grid" v-on="gridHandler.gridEventListener">
|
|
263
|
+
<template #name="{ row }"><strong>{{ row.name }}</strong></template>
|
|
264
|
+
<template #status="{ row }"><span class="badge">{{ row.status }}</span></template>
|
|
265
|
+
<template #price.edit="{ row }"><BSNumberInput v-model="row.price" name="price" /></template>
|
|
266
|
+
</BSGrid>
|
|
267
|
+
|
|
268
|
+
<script setup lang="ts">
|
|
269
|
+
import { createPageGridHandler, type Column, type PaginatedList } from '@g1cloud/bluesea'
|
|
270
|
+
|
|
271
|
+
type User = { id: number; name: string; email: string; status: string; price?: number }
|
|
272
|
+
|
|
273
|
+
const columns: Column<User>[] = [
|
|
274
|
+
{ propertyId: 'name', caption: { key: 'col.name' }, width: 160, sortable: true },
|
|
275
|
+
{ propertyId: 'email', caption: { key: 'col.email' }, width: 220 },
|
|
276
|
+
{ propertyId: 'price', caption: '가격', width: 120, cellType: 'NUMBER' },
|
|
277
|
+
{ propertyId: 'status', caption: '상태', width: 100 },
|
|
278
|
+
]
|
|
279
|
+
|
|
280
|
+
const gridHandler = createPageGridHandler<User>({
|
|
281
|
+
gridId: 'user-list', // used by gridPreferenceStore to remember column widths
|
|
282
|
+
getRowKey: (u) => String(u.id),
|
|
283
|
+
editable: true,
|
|
284
|
+
getGridData: async (param): Promise<PaginatedList<User>> => api.users.search(param),
|
|
285
|
+
defaultSorts: [{ property: 'name', direction: 'ASC' }],
|
|
286
|
+
limit: 100,
|
|
287
|
+
limitItems: [100, 300, 500],
|
|
288
|
+
})
|
|
289
|
+
gridHandler.grid.columnSettings = columns.map(c => ({ propertyId: c.propertyId, hidden: false }))
|
|
290
|
+
await gridHandler.loadGridData()
|
|
291
|
+
</script>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Cell customisation uses named slots: `#<propertyId>` for display, `#<propertyId>.edit` for the editor when `editable: true` and the row is in `editingRows`. Use `cellType` to get built-in formatting (`'TEXT' | 'NUMBER' | 'DATE' | 'PERCENTAGE' | 'BOOL' | 'MULTI_LANG_STRING' | 'NAME' | 'TEL' | 'ADDRESS' | 'MONEY'`). For date columns also set `dateFormat: 'DAY' | 'MINUTE' | 'SECOND'` or a dayjs format string.
|
|
295
|
+
|
|
296
|
+
For deeper grid topics (inline add/remove, filters, Excel export, fixed columns, extensions) read the `BSGrid` section in `references/grid.md` and the guide page `packages/bluesea-demo/src/page/guide/BSGridGuide.vue`.
|
|
297
|
+
|
|
298
|
+
## 7. SavePoint (inline-edit modified state)
|
|
299
|
+
|
|
300
|
+
SavePoint lets a form remember its "saved" state and surface a `modified` flag per field. It is automatically injected by `BSTabSheet` and available via `useSavePoint()` — most inputs (`BSTextInput`, etc.) register themselves so the "modified" dot appears without any extra code. You typically only interact with it to `set()` after a successful save or `rollback()` on cancel:
|
|
301
|
+
|
|
302
|
+
```ts
|
|
303
|
+
import { useSavePoint } from '@g1cloud/bluesea'
|
|
304
|
+
const savePoint = useSavePoint()
|
|
305
|
+
|
|
306
|
+
async function save() { await api.save(form.value); savePoint?.set() }
|
|
307
|
+
function cancel() { savePoint?.rollback() }
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Pass `:ignore-save-point="true"` on an input to opt it out of modified-tracking.
|
|
311
|
+
|
|
312
|
+
## 8. Directives
|
|
313
|
+
|
|
314
|
+
- `vTooltip` — show tooltip on hover. Use via `const vTooltip = createTooltipDirective()` and register globally.
|
|
315
|
+
- `vClickOutside` — fire when the user clicks outside the element.
|
|
316
|
+
- `vFocusOnLoad`, `vFocusJump`, `vFocusLoop` — focus management helpers for forms.
|
|
317
|
+
|
|
318
|
+
Import and use ad-hoc or register globally.
|
|
319
|
+
|
|
320
|
+
## 9. Styling with Tailwind v4
|
|
321
|
+
|
|
322
|
+
Bluesea v6 uses Tailwind CSS v4. Key changes from v5:
|
|
323
|
+
- **Utility scale** changed: old 1px scale → 0.25rem scale. `mt-8` (8px) → `mt-2`, `p-16` → `p-4`. Non-multiple-of-4 values use bracket notation: `mr-1` → `mr-[1px]`.
|
|
324
|
+
- **Dark mode** via `.dark` class (not `[data-theme="dark"]`). Toggle with `document.documentElement.classList.toggle('dark', on)`.
|
|
325
|
+
- **Icon font removed** — use `BSIcon name="xyz"` instead of `<span class="font-icon">xyz</span>`.
|
|
326
|
+
- **CSS source**: `@g1cloud/bluesea/css/bluesea.css` (pre-compiled) or integrate theme + component CSS files into your Tailwind build for zero duplication.
|
|
327
|
+
|
|
328
|
+
## 10. DefaultFrame (BackOffice app shell)
|
|
329
|
+
|
|
330
|
+
If the app is a BackOffice application, use `DefaultHeader` + `DefaultBody` for sidebar + tab management. Build a `FrameModel` with your menu tree and tab controller. This is an opinionated shell — skip it for standalone screens. Detailed wiring lives in `references/frame.md` and the `DefaultFrameGuide` demo page.
|
|
331
|
+
|
|
332
|
+
## When to write code vs read the source
|
|
333
|
+
|
|
334
|
+
- For a component's exact prop set, **read the `.vue` file** under `packages/<package>/src/component/`. The `defineProps<{...}>()` block is authoritative; what a docs page says may lag behind.
|
|
335
|
+
- For a real-world wiring example, **open the matching `BS*Guide.vue`** in `packages/bluesea-demo/src/page/guide/`. They cover the common scenarios end-to-end.
|
|
336
|
+
- For types (`MultiLangText`, `StoredFile`, `Money`, `Filter`, `Sort`, `PaginatedList`, `Column`, etc.), the model files in `packages/<package>/src/model/` and grid models are short and worth reading directly.
|
|
337
|
+
|
|
338
|
+
## Reference files
|
|
339
|
+
|
|
340
|
+
- `references/components.md` — fuller prop reference for the most-used components, grouped by category.
|
|
341
|
+
- `references/grid.md` — BSGrid deep-dive: PageGridHandler, filters, inline editing, extensions, Excel export.
|
|
342
|
+
- `references/validation.md` — custom field rules, form-level rules, async validation, and error mapping.
|
|
343
|
+
- `references/i18n.md` — i18n setup, MultiLangText patterns, locale switching, and data vs UI locale.
|
|
344
|
+
|
|
345
|
+
Load a reference file only when the user's question clearly touches that area; keep this file as the default map.
|