@naptics/vue-collection 0.2.15 → 0.3.1
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/.github/workflows/build.yml +26 -0
- package/.github/workflows/deploy-demo.yml +46 -0
- package/.github/workflows/deploy-lib.yml +59 -0
- package/.gitlab-ci.yml +57 -0
- package/.nvmrc +1 -0
- package/.prettierrc +8 -0
- package/.vscode/extensions.json +10 -0
- package/.vscode/launch.json +23 -0
- package/.vscode/settings.json +13 -0
- package/babel.config.json +3 -0
- package/components/NAlert.d.ts +1 -44
- package/components/NBadge.d.ts +1 -133
- package/components/NBreadcrub.d.ts +2 -106
- package/components/NBreadcrub.js +1 -1
- package/components/NButton.d.ts +2 -118
- package/components/NCheckbox.d.ts +1 -32
- package/components/NCheckboxLabel.d.ts +1 -45
- package/components/NCheckboxLabel.js +1 -1
- package/components/NCrudModal.d.ts +7 -251
- package/components/NCrudModal.js +1 -1
- package/components/NDialog.d.ts +1 -110
- package/components/NDialog.js +1 -1
- package/components/NDropdown.d.ts +1 -69
- package/components/NDropdown.js +1 -1
- package/components/NDropzone.d.ts +1 -115
- package/components/NDropzone.js +1 -1
- package/components/NForm.d.ts +1 -23
- package/components/NFormModal.d.ts +7 -151
- package/components/NIconButton.d.ts +3 -159
- package/components/NIconButton.js +1 -1
- package/components/NIconCircle.d.ts +1 -87
- package/components/NInput.d.ts +1 -164
- package/components/NInput.js +1 -1
- package/components/NInputPhone.d.ts +2 -114
- package/components/NInputPhone.js +1 -1
- package/components/NInputSelect.d.ts +2 -187
- package/components/NInputSelect.js +1 -1
- package/components/NInputSuggestion.d.ts +2 -155
- package/components/NInputSuggestion.js +1 -1
- package/components/NLink.d.ts +6 -70
- package/components/NLink.js +8 -1
- package/components/NList.d.ts +1 -43
- package/components/NList.js +1 -1
- package/components/NLoadingIndicator.d.ts +1 -49
- package/components/NModal.d.ts +12 -250
- package/components/NModal.js +15 -9
- package/components/NPagination.d.ts +1 -63
- package/components/NSearchbar.d.ts +1 -56
- package/components/NSearchbarList.d.ts +3 -63
- package/components/NSearchbarList.js +1 -1
- package/components/NSelect.d.ts +2 -148
- package/components/NSelect.js +1 -1
- package/components/NSuggestionList.d.ts +3 -126
- package/components/NSuggestionList.js +5 -2
- package/components/NTable.d.ts +1 -85
- package/components/NTable.js +12 -6
- package/components/NTableAction.d.ts +2 -46
- package/components/NTableAction.js +1 -1
- package/components/NTextArea.d.ts +2 -181
- package/components/NTextArea.js +1 -1
- package/components/NTooltip.d.ts +1 -105
- package/components/NTooltip.js +1 -1
- package/components/NValInput.d.ts +7 -182
- package/components/NValInput.js +1 -1
- package/env.d.ts +15 -0
- package/eslint.config.cjs +29 -0
- package/index.html +13 -0
- package/package.json +21 -19
- package/postcss.config.js +6 -0
- package/public/favicon.ico +0 -0
- package/scripts/build-lib.sh +52 -0
- package/scripts/sync-node-types.js +70 -0
- package/src/demo/App.css +9 -0
- package/src/demo/App.tsx +5 -0
- package/src/demo/components/ColorGrid.tsx +26 -0
- package/src/demo/components/ComponentGrid.tsx +26 -0
- package/src/demo/components/ComponentSection.tsx +30 -0
- package/src/demo/components/VariantSection.tsx +18 -0
- package/src/demo/i18n/de.ts +7 -0
- package/src/demo/i18n/en.ts +7 -0
- package/src/demo/i18n/index.ts +24 -0
- package/src/demo/main.ts +13 -0
- package/src/demo/router/index.ts +21 -0
- package/src/demo/views/HomeView.tsx +94 -0
- package/src/demo/views/NavigationView.tsx +43 -0
- package/src/demo/views/presentation/AlertView.tsx +40 -0
- package/src/demo/views/presentation/BadgeView.tsx +61 -0
- package/src/demo/views/presentation/BreadcrumbView.tsx +52 -0
- package/src/demo/views/presentation/ButtonView.tsx +49 -0
- package/src/demo/views/presentation/CheckboxView.tsx +59 -0
- package/src/demo/views/presentation/DropdownView.tsx +59 -0
- package/src/demo/views/presentation/DropzoneView.tsx +39 -0
- package/src/demo/views/presentation/IconButtonView.tsx +47 -0
- package/src/demo/views/presentation/IconCircleView.tsx +38 -0
- package/src/demo/views/presentation/InputView.tsx +179 -0
- package/src/demo/views/presentation/LinkView.tsx +60 -0
- package/src/demo/views/presentation/ListView.tsx +29 -0
- package/src/demo/views/presentation/LoadingIndicatorView.tsx +38 -0
- package/src/demo/views/presentation/ModalView.tsx +210 -0
- package/src/demo/views/presentation/PaginationView.tsx +25 -0
- package/src/demo/views/presentation/SearchbarView.tsx +80 -0
- package/src/demo/views/presentation/TableView.tsx +146 -0
- package/src/demo/views/presentation/TooltipView.tsx +86 -0
- package/src/lib/components/NAlert.tsx +85 -0
- package/src/lib/components/NBadge.tsx +75 -0
- package/src/lib/components/NBreadcrub.tsx +97 -0
- package/src/lib/components/NButton.tsx +80 -0
- package/src/lib/components/NCheckbox.tsx +55 -0
- package/src/lib/components/NCheckboxLabel.tsx +51 -0
- package/src/lib/components/NCrudModal.tsx +133 -0
- package/src/lib/components/NDialog.tsx +182 -0
- package/src/lib/components/NDropdown.tsx +167 -0
- package/src/lib/components/NDropzone.tsx +265 -0
- package/src/lib/components/NForm.tsx +32 -0
- package/src/lib/components/NFormModal.tsx +66 -0
- package/src/lib/components/NIconButton.tsx +92 -0
- package/src/lib/components/NIconCircle.tsx +78 -0
- package/src/lib/components/NInput.css +11 -0
- package/src/lib/components/NInput.tsx +139 -0
- package/src/lib/components/NInputPhone.tsx +53 -0
- package/src/lib/components/NInputSelect.tsx +126 -0
- package/src/lib/components/NInputSuggestion.tsx +80 -0
- package/src/lib/components/NLink.tsx +82 -0
- package/src/lib/components/NList.tsx +67 -0
- package/src/lib/components/NLoadingIndicator.css +46 -0
- package/src/lib/components/NLoadingIndicator.tsx +63 -0
- package/src/lib/components/NModal.tsx +243 -0
- package/src/lib/components/NPagination.css +15 -0
- package/src/lib/components/NPagination.tsx +131 -0
- package/src/lib/components/NSearchbar.tsx +78 -0
- package/src/lib/components/NSearchbarList.tsx +47 -0
- package/src/lib/components/NSelect.tsx +128 -0
- package/src/lib/components/NSuggestionList.tsx +216 -0
- package/src/lib/components/NTable.css +3 -0
- package/src/lib/components/NTable.tsx +247 -0
- package/src/lib/components/NTableAction.tsx +49 -0
- package/src/lib/components/NTextArea.tsx +159 -0
- package/src/lib/components/NTooltip.css +37 -0
- package/src/lib/components/NTooltip.tsx +250 -0
- package/src/lib/components/NValInput.tsx +163 -0
- package/src/lib/components/ValidatedForm.ts +71 -0
- package/src/lib/components/__tests__/NButton.spec.tsx +26 -0
- package/src/lib/components/__tests__/NCheckbox.spec.tsx +39 -0
- package/src/lib/i18n/de/vue-collection.json +58 -0
- package/src/lib/i18n/en/vue-collection.json +58 -0
- package/src/lib/i18n/index.ts +54 -0
- package/src/lib/index.ts +2 -0
- package/src/lib/jsx.d.ts +13 -0
- package/src/lib/utils/__tests__/identifiable.spec.ts +72 -0
- package/src/lib/utils/__tests__/validation.spec.ts +92 -0
- package/src/lib/utils/breakpoints.ts +47 -0
- package/src/lib/utils/component.tsx +131 -0
- package/src/lib/utils/deferred.ts +28 -0
- package/src/lib/utils/identifiable.ts +87 -0
- package/src/lib/utils/stringMaxLength.ts +25 -0
- package/src/lib/utils/tailwind.ts +41 -0
- package/src/lib/utils/utils.ts +90 -0
- package/src/lib/utils/vModel.ts +260 -0
- package/src/lib/utils/validation.ts +189 -0
- package/src/lib/utils/vue.ts +25 -0
- package/tailwind.config.js +38 -0
- package/tsconfig.config.json +9 -0
- package/tsconfig.demo.json +19 -0
- package/tsconfig.json +16 -0
- package/tsconfig.lib.json +18 -0
- package/tsconfig.vitest.json +8 -0
- package/utils/breakpoints.d.ts +1 -1
- package/utils/component.d.ts +3 -7
- package/utils/component.js +5 -2
- package/utils/identifiable.js +5 -1
- package/vite.config.ts +28 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createComponent } from '../utils/component'
|
|
2
|
+
import type { TWTextSize } from '../utils/tailwind'
|
|
3
|
+
import type { PropType } from 'vue'
|
|
4
|
+
import NTooltip, { mapTooltipProps, nToolTipPropsForImplementor } from './NTooltip'
|
|
5
|
+
|
|
6
|
+
export const nBadgeProps = {
|
|
7
|
+
/**
|
|
8
|
+
* The text of the badge. Can alternatively be passed in the default slot.
|
|
9
|
+
*/
|
|
10
|
+
text: String,
|
|
11
|
+
/**
|
|
12
|
+
* The text size, a standard tailwind text-size class.
|
|
13
|
+
*/
|
|
14
|
+
textSize: {
|
|
15
|
+
type: String as PropType<TWTextSize>,
|
|
16
|
+
default: 'text-sm',
|
|
17
|
+
},
|
|
18
|
+
/**
|
|
19
|
+
* The color of the badge.
|
|
20
|
+
*/
|
|
21
|
+
color: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: 'primary',
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* The background shade of the badge.
|
|
27
|
+
*/
|
|
28
|
+
shade: {
|
|
29
|
+
type: Number,
|
|
30
|
+
default: 200,
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* The text shade of the badge.
|
|
34
|
+
*/
|
|
35
|
+
textShade: {
|
|
36
|
+
type: Number,
|
|
37
|
+
default: 900,
|
|
38
|
+
},
|
|
39
|
+
/**
|
|
40
|
+
* If set to `true` the badges text is all-caps. Default is `true`.
|
|
41
|
+
*/
|
|
42
|
+
allCaps: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: true,
|
|
45
|
+
},
|
|
46
|
+
/**
|
|
47
|
+
* Adds the classes to the badge.
|
|
48
|
+
* Use this instead of `class` to style the button, because the button is wrapped inside
|
|
49
|
+
* a div for the tooltip and `class` would be applied to the wrapping div.
|
|
50
|
+
*/
|
|
51
|
+
badgeClass: String,
|
|
52
|
+
...nToolTipPropsForImplementor,
|
|
53
|
+
} as const
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The `NBadge` is a styled element to wrap a text.
|
|
57
|
+
*/
|
|
58
|
+
const Component = createComponent('NBadge', nBadgeProps, (props, { slots }) => {
|
|
59
|
+
return () => (
|
|
60
|
+
<NTooltip {...mapTooltipProps(props)}>
|
|
61
|
+
<div
|
|
62
|
+
class={[
|
|
63
|
+
'px-2 py-1 rounded-md font-semibold shadow',
|
|
64
|
+
`${props.textSize} bg-${props.color}-${props.shade} text-${props.color}-${props.textShade}`,
|
|
65
|
+
props.allCaps ? 'uppercase' : '',
|
|
66
|
+
props.badgeClass,
|
|
67
|
+
]}
|
|
68
|
+
>
|
|
69
|
+
{slots.default?.() || props.text}
|
|
70
|
+
</div>
|
|
71
|
+
</NTooltip>
|
|
72
|
+
)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
export { Component as NBadge, Component as default }
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { createComponentWithSlots } from '../utils/component'
|
|
2
|
+
import type { HeroIcon } from '../utils/tailwind'
|
|
3
|
+
import type { TWTextSize } from '../utils/tailwind'
|
|
4
|
+
import { ChevronRightIcon } from '@heroicons/vue/24/solid'
|
|
5
|
+
import type { RouteLocationRaw } from 'vue-router'
|
|
6
|
+
import NLink from './NLink'
|
|
7
|
+
import type { PropType } from 'vue'
|
|
8
|
+
|
|
9
|
+
export const nBreadcrumbProps = {
|
|
10
|
+
/**
|
|
11
|
+
* The items of the breadcrumb.
|
|
12
|
+
*/
|
|
13
|
+
items: {
|
|
14
|
+
type: Array as PropType<BreadcrumbItem[]>,
|
|
15
|
+
default: () => [],
|
|
16
|
+
},
|
|
17
|
+
/**
|
|
18
|
+
* The color of the breadcrumbs text and icons.
|
|
19
|
+
*/
|
|
20
|
+
color: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: 'primary',
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* The text-size of the breadcrumb labels.
|
|
26
|
+
*/
|
|
27
|
+
textSize: {
|
|
28
|
+
type: String as PropType<TWTextSize>,
|
|
29
|
+
default: 'text-base',
|
|
30
|
+
},
|
|
31
|
+
/**
|
|
32
|
+
* The icon which is used as a seperator between two breadcrumb items.
|
|
33
|
+
*/
|
|
34
|
+
icon: {
|
|
35
|
+
type: Function as PropType<HeroIcon>,
|
|
36
|
+
default: ChevronRightIcon,
|
|
37
|
+
},
|
|
38
|
+
/**
|
|
39
|
+
* The size of the icon in tailwind units.
|
|
40
|
+
*/
|
|
41
|
+
iconSize: {
|
|
42
|
+
type: Number,
|
|
43
|
+
default: 5,
|
|
44
|
+
},
|
|
45
|
+
/**
|
|
46
|
+
* Adds the classes to the separator icons.
|
|
47
|
+
*/
|
|
48
|
+
iconClass: String,
|
|
49
|
+
/**
|
|
50
|
+
* A slot the replace the breadcrumb labels.
|
|
51
|
+
*/
|
|
52
|
+
item: Function as PropType<(item: BreadcrumbItem, index: number) => JSX.Element>,
|
|
53
|
+
/**
|
|
54
|
+
* A slot to replace the separators between the breadcrumb labels.
|
|
55
|
+
* The passsed item is the item before the seperator.
|
|
56
|
+
*/
|
|
57
|
+
seperator: Function as PropType<(item: BreadcrumbItem, index: number) => JSX.Element>,
|
|
58
|
+
} as const
|
|
59
|
+
|
|
60
|
+
export type BreadcrumbItem = {
|
|
61
|
+
/**
|
|
62
|
+
* The visible label of the breadcrumb item.
|
|
63
|
+
*/
|
|
64
|
+
label: string
|
|
65
|
+
/**
|
|
66
|
+
* The route the breadcrumb item points to.
|
|
67
|
+
*/
|
|
68
|
+
route: RouteLocationRaw
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* The `NBreadcrumb` is a styled breadcrumb which can be used as a navigation in hierarchical views.
|
|
73
|
+
*/
|
|
74
|
+
const Component = createComponentWithSlots('NBreadcrumb', nBreadcrumbProps, ['seperator', 'item'], props => {
|
|
75
|
+
return () => (
|
|
76
|
+
<div class={`flex flex-wrap items-center`}>
|
|
77
|
+
{props.items.map((item, index) => (
|
|
78
|
+
<>
|
|
79
|
+
{props.item?.(item, index) || (
|
|
80
|
+
<NLink textSize={props.textSize} route={item.route} color={props.color}>
|
|
81
|
+
{item.label}
|
|
82
|
+
</NLink>
|
|
83
|
+
)}
|
|
84
|
+
|
|
85
|
+
{index < props.items.length - 1 &&
|
|
86
|
+
(props.seperator?.(item, index) || (
|
|
87
|
+
<props.icon
|
|
88
|
+
class={`mx-2 w-${props.iconSize} h-${props.iconSize} text-${props.color}-500 ${props.iconClass}`}
|
|
89
|
+
/>
|
|
90
|
+
))}
|
|
91
|
+
</>
|
|
92
|
+
))}
|
|
93
|
+
</div>
|
|
94
|
+
)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
export { Component as NBreadcrumb, Component as default }
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { createComponent } from '../utils/component'
|
|
2
|
+
import { computed, type PropType } from 'vue'
|
|
3
|
+
import NLoadingIndicator from './NLoadingIndicator'
|
|
4
|
+
import NTooltip, { mapTooltipProps, nToolTipPropsForImplementor } from './NTooltip'
|
|
5
|
+
|
|
6
|
+
export const nButtonProps = {
|
|
7
|
+
/**
|
|
8
|
+
* The color of the button.
|
|
9
|
+
*/
|
|
10
|
+
color: {
|
|
11
|
+
type: String,
|
|
12
|
+
default: 'primary',
|
|
13
|
+
},
|
|
14
|
+
/**
|
|
15
|
+
* The html attribute, which indicates the type of the button.
|
|
16
|
+
*/
|
|
17
|
+
type: {
|
|
18
|
+
type: String as PropType<'submit' | 'button' | 'reset'>,
|
|
19
|
+
default: 'button',
|
|
20
|
+
},
|
|
21
|
+
/**
|
|
22
|
+
* If set to `true` the button is disabled and no interaction is possible.
|
|
23
|
+
*/
|
|
24
|
+
disabled: Boolean,
|
|
25
|
+
/**
|
|
26
|
+
* If set to `true` the button will show a loading animation.
|
|
27
|
+
* Setting `loading` to `true` will also disable the button.
|
|
28
|
+
*/
|
|
29
|
+
loading: Boolean,
|
|
30
|
+
/**
|
|
31
|
+
* If set to `true` the button will appear smaller.
|
|
32
|
+
*/
|
|
33
|
+
small: Boolean,
|
|
34
|
+
/**
|
|
35
|
+
* Adds the classes to the button.
|
|
36
|
+
* Use this instead of `class` to style the button, because the button is wrapped inside
|
|
37
|
+
* a div for the tooltip and `class` would be applied to the wrapping div.
|
|
38
|
+
*/
|
|
39
|
+
buttonClass: String,
|
|
40
|
+
/**
|
|
41
|
+
* This is called, when the button is clicked.
|
|
42
|
+
*/
|
|
43
|
+
onClick: Function as PropType<() => void>,
|
|
44
|
+
...nToolTipPropsForImplementor,
|
|
45
|
+
} as const
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The `NButton` is a styled button.
|
|
49
|
+
*/
|
|
50
|
+
const Component = createComponent('NButton', nButtonProps, (props, { slots }) => {
|
|
51
|
+
const isDisabled = computed(() => props.loading || props.disabled)
|
|
52
|
+
|
|
53
|
+
return () => (
|
|
54
|
+
<NTooltip {...mapTooltipProps(props)}>
|
|
55
|
+
<button
|
|
56
|
+
disabled={isDisabled.value}
|
|
57
|
+
type={props.type}
|
|
58
|
+
class={[
|
|
59
|
+
`block w-full font-medium rounded-md focus:outline-none focus-visible:ring-2 shadow text-${props.color}-900 relative`,
|
|
60
|
+
isDisabled.value
|
|
61
|
+
? `bg-${props.color}-100 text-opacity-20 cursor-default`
|
|
62
|
+
: `bg-${props.color}-200 hover:bg-${props.color}-300 focus-visible:ring-${props.color}-500`,
|
|
63
|
+
|
|
64
|
+
props.small ? 'py-1 px-2 text-xs' : 'py-2 px-4 text-sm',
|
|
65
|
+
props.buttonClass,
|
|
66
|
+
]}
|
|
67
|
+
onClick={props.onClick}
|
|
68
|
+
>
|
|
69
|
+
<span class={{ 'opacity-10': props.loading }}>{slots.default?.()}</span>
|
|
70
|
+
{props.loading && (
|
|
71
|
+
<div class="absolute inset-0 flex items-center justify-center opacity-50">
|
|
72
|
+
<NLoadingIndicator color={props.color} size={props.small ? 4 : 6} shade={600} />
|
|
73
|
+
</div>
|
|
74
|
+
)}
|
|
75
|
+
</button>
|
|
76
|
+
</NTooltip>
|
|
77
|
+
)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
export { Component as NButton, Component as default }
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { createComponent } from '../utils/component'
|
|
2
|
+
import { vModelProps } from '../utils/vModel'
|
|
3
|
+
import { nextTick, ref } from 'vue'
|
|
4
|
+
|
|
5
|
+
export const nCheckboxProps = {
|
|
6
|
+
...vModelProps(Boolean),
|
|
7
|
+
/**
|
|
8
|
+
* The color of the checkbox.
|
|
9
|
+
*/
|
|
10
|
+
color: {
|
|
11
|
+
type: String,
|
|
12
|
+
default: 'primary',
|
|
13
|
+
},
|
|
14
|
+
/**
|
|
15
|
+
* If set to `true` the checkbox is disabled and no interaction is possible.
|
|
16
|
+
*/
|
|
17
|
+
disabled: Boolean,
|
|
18
|
+
} as const
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The `NCheckbox` is a styled checkbox.
|
|
22
|
+
*/
|
|
23
|
+
const Component = createComponent('NCheckbox', nCheckboxProps, props => {
|
|
24
|
+
const toggle = () => {
|
|
25
|
+
props.onUpdateValue?.(!props.value)
|
|
26
|
+
forceUpdate()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const checkBoxRef = ref<InstanceType<typeof HTMLElement>>()
|
|
30
|
+
|
|
31
|
+
const updateKey = ref(0)
|
|
32
|
+
const forceUpdate = () => {
|
|
33
|
+
updateKey.value += 1
|
|
34
|
+
nextTick(() => checkBoxRef.value?.focus())
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return () => (
|
|
38
|
+
<input
|
|
39
|
+
type="checkbox"
|
|
40
|
+
ref={checkBoxRef}
|
|
41
|
+
checked={props.value}
|
|
42
|
+
disabled={props.disabled}
|
|
43
|
+
onClick={toggle}
|
|
44
|
+
key={updateKey.value}
|
|
45
|
+
class={[
|
|
46
|
+
`h-5 w-5 border-default-300 rounded focus:outline-none focus:ring-0 focus-visible:ring-2 focus-visible:ring-${props.color}-500`,
|
|
47
|
+
props.disabled
|
|
48
|
+
? `cursor-default bg-default-100 text-${props.color}-200`
|
|
49
|
+
: `cursor-pointer text-${props.color}-400`,
|
|
50
|
+
]}
|
|
51
|
+
/>
|
|
52
|
+
)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
export { Component as NCheckbox, Component as default }
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createComponent } from '../utils/component'
|
|
2
|
+
import NCheckbox, { nCheckboxProps } from './NCheckbox'
|
|
3
|
+
|
|
4
|
+
export const nCheckboxLabelProps = {
|
|
5
|
+
...nCheckboxProps,
|
|
6
|
+
/**
|
|
7
|
+
* The title of the checkbox.
|
|
8
|
+
*/
|
|
9
|
+
title: String,
|
|
10
|
+
/**
|
|
11
|
+
* The description of the checkbox.
|
|
12
|
+
*/
|
|
13
|
+
description: String,
|
|
14
|
+
/**
|
|
15
|
+
* If set to `true`, a smaller margin is applied between the label and the checkbox.
|
|
16
|
+
*/
|
|
17
|
+
compact: Boolean,
|
|
18
|
+
} as const
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The `NCheckboxLabel` is a checkbox with a title and a description.
|
|
22
|
+
*/
|
|
23
|
+
const Component = createComponent('NCheckboxLabel', nCheckboxLabelProps, props => {
|
|
24
|
+
const toggleValue = () => {
|
|
25
|
+
if (!props.disabled) props.onUpdateValue?.(!props.value)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return () => (
|
|
29
|
+
<div class={`flex ${props.description ? 'items-start' : 'items-center'}`}>
|
|
30
|
+
<NCheckbox {...props} class={props.description ? 'mt-1' : ''} />
|
|
31
|
+
<div class={`${props.compact ? 'ml-2' : 'ml-3'} text-sm`}>
|
|
32
|
+
<label
|
|
33
|
+
onClick={toggleValue}
|
|
34
|
+
class={[
|
|
35
|
+
'font-medium select-none',
|
|
36
|
+
props.disabled ? 'text-default-300' : 'text-default-700 cursor-pointer',
|
|
37
|
+
]}
|
|
38
|
+
>
|
|
39
|
+
{props.title}
|
|
40
|
+
</label>
|
|
41
|
+
<p class={props.disabled ? 'text-default-300' : 'text-default-500'}>
|
|
42
|
+
<span onClick={toggleValue} class={['select-none', props.disabled ? '' : 'cursor-pointer']}>
|
|
43
|
+
{props.description}
|
|
44
|
+
</span>
|
|
45
|
+
</p>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
export { Component as NCheckboxLabel, Component as default }
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { trsl } from '../i18n'
|
|
2
|
+
import { createComponentWithSlots } from '../utils/component'
|
|
3
|
+
import { ref, type PropType } from 'vue'
|
|
4
|
+
import NButton from './NButton'
|
|
5
|
+
import type { DialogVariant, NDialogExposed } from './NDialog'
|
|
6
|
+
import NDialog from './NDialog'
|
|
7
|
+
import NFormModal, { nFormModalProps } from './NFormModal'
|
|
8
|
+
|
|
9
|
+
export const nCrudModalProps = {
|
|
10
|
+
...nFormModalProps,
|
|
11
|
+
/**
|
|
12
|
+
* The text of the remove-button.
|
|
13
|
+
*/
|
|
14
|
+
removeText: {
|
|
15
|
+
type: String,
|
|
16
|
+
default: trsl('vue-collection.action.remove'),
|
|
17
|
+
},
|
|
18
|
+
/**
|
|
19
|
+
* The color of the remove-button.
|
|
20
|
+
*/
|
|
21
|
+
removeColor: {
|
|
22
|
+
type: String,
|
|
23
|
+
default: 'red',
|
|
24
|
+
},
|
|
25
|
+
/**
|
|
26
|
+
* If set to `true` the remove-button is disabled.
|
|
27
|
+
*/
|
|
28
|
+
removeDisabled: Boolean,
|
|
29
|
+
/**
|
|
30
|
+
* If set to `true` the ok-button is hidden.
|
|
31
|
+
*/
|
|
32
|
+
hideRemove: Boolean,
|
|
33
|
+
/**
|
|
34
|
+
* If set to `true` the ok-button is disabled.
|
|
35
|
+
*/
|
|
36
|
+
okDisabled: Boolean,
|
|
37
|
+
/**
|
|
38
|
+
* The title of the dialog which appears when clicking on the remove-button.
|
|
39
|
+
*/
|
|
40
|
+
removeDialogTitle: String,
|
|
41
|
+
/**
|
|
42
|
+
* The text of the dialog which appears when clicking on the remove-button.
|
|
43
|
+
*/
|
|
44
|
+
removeDialogText: String,
|
|
45
|
+
/**
|
|
46
|
+
* The variant of the dialog which appears when clicking on the remove-button. Default is `remove`.
|
|
47
|
+
*/
|
|
48
|
+
removeDialogVariant: {
|
|
49
|
+
type: String as PropType<DialogVariant>,
|
|
50
|
+
default: 'remove',
|
|
51
|
+
},
|
|
52
|
+
/**
|
|
53
|
+
* The text of the dialog's ok-button. Is already set by the `removeDialogVariant` but can be overridden.
|
|
54
|
+
*/
|
|
55
|
+
removeDialogOkText: String,
|
|
56
|
+
/**
|
|
57
|
+
* If set to `true` the modal will close itself when `onRemove` is called.
|
|
58
|
+
*/
|
|
59
|
+
closeOnRemove: {
|
|
60
|
+
type: Boolean,
|
|
61
|
+
default: true,
|
|
62
|
+
},
|
|
63
|
+
/**
|
|
64
|
+
* This is called, when the remove-button has been clicked and the dialog has been accepted.
|
|
65
|
+
*/
|
|
66
|
+
onRemove: Function as PropType<() => void>,
|
|
67
|
+
} as const
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The `NCrudModal` is a {@link NFormModal} which has some convenience features for a CRUD-scenario.
|
|
71
|
+
* It has an integrated remove-button with a user-dialog to remove the editing element.
|
|
72
|
+
* When the dialog is accepted `onRemove` is called.
|
|
73
|
+
*/
|
|
74
|
+
const Component = createComponentWithSlots(
|
|
75
|
+
'NCrudModal',
|
|
76
|
+
nCrudModalProps,
|
|
77
|
+
['modal', 'footer', 'header'],
|
|
78
|
+
(props, { slots }) => {
|
|
79
|
+
const removeDialog = ref<NDialogExposed>()
|
|
80
|
+
|
|
81
|
+
const remove = () => {
|
|
82
|
+
removeDialog.value?.show().then(result => {
|
|
83
|
+
if (result) {
|
|
84
|
+
props.onRemove?.()
|
|
85
|
+
if (props.closeOnRemove) props.onUpdateValue?.(false)
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return () => (
|
|
91
|
+
<NFormModal
|
|
92
|
+
{...props}
|
|
93
|
+
footer={
|
|
94
|
+
props.footer ||
|
|
95
|
+
(({ ok, cancel }) => (
|
|
96
|
+
<div class="flex justify-between">
|
|
97
|
+
<div>
|
|
98
|
+
{!props.hideRemove && (
|
|
99
|
+
<NButton color={props.removeColor} onClick={remove} disabled={props.removeDisabled}>
|
|
100
|
+
{props.removeText}
|
|
101
|
+
</NButton>
|
|
102
|
+
)}
|
|
103
|
+
</div>
|
|
104
|
+
<div class="flex justify-end space-x-2">
|
|
105
|
+
{!props.hideCancel && (
|
|
106
|
+
<NButton color={props.cancelColor} onClick={cancel}>
|
|
107
|
+
{props.cancelText}
|
|
108
|
+
</NButton>
|
|
109
|
+
)}
|
|
110
|
+
{!props.hideOk && (
|
|
111
|
+
<NButton color={props.okColor} onClick={ok} disabled={props.okDisabled}>
|
|
112
|
+
{props.okText}
|
|
113
|
+
</NButton>
|
|
114
|
+
)}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
))
|
|
118
|
+
}
|
|
119
|
+
>
|
|
120
|
+
{slots.default?.()}
|
|
121
|
+
<NDialog
|
|
122
|
+
ref={removeDialog}
|
|
123
|
+
variant={props.removeDialogVariant}
|
|
124
|
+
title={props.removeDialogTitle}
|
|
125
|
+
text={props.removeDialogText}
|
|
126
|
+
okText={props.removeDialogOkText}
|
|
127
|
+
/>
|
|
128
|
+
</NFormModal>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
export { Component as NCrudModal, Component as default }
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { deferred, type DeferredPromise } from '../utils/deferred'
|
|
2
|
+
import { createComponent, extractProps } from '../utils/component'
|
|
3
|
+
import { CheckIcon, ExclamationTriangleIcon, LightBulbIcon, TrashIcon } from '@heroicons/vue/24/outline'
|
|
4
|
+
import { computed, ref, type PropType } from 'vue'
|
|
5
|
+
import NIconCircle from './NIconCircle'
|
|
6
|
+
import NModal from './NModal'
|
|
7
|
+
import { DialogTitle } from '@headlessui/vue'
|
|
8
|
+
import type { HeroIcon } from '../utils/tailwind'
|
|
9
|
+
import { trsl } from '../i18n'
|
|
10
|
+
import { vModelForRef } from '../utils/vModel'
|
|
11
|
+
|
|
12
|
+
export type DialogVariant = 'success' | 'info' | 'warning' | 'danger' | 'remove'
|
|
13
|
+
|
|
14
|
+
export const nDialogProps = {
|
|
15
|
+
/**
|
|
16
|
+
* The title of the dialog.
|
|
17
|
+
*/
|
|
18
|
+
title: String,
|
|
19
|
+
/**
|
|
20
|
+
* The text of the dialog.
|
|
21
|
+
*/
|
|
22
|
+
text: String,
|
|
23
|
+
/**
|
|
24
|
+
* The variant of the dialog.
|
|
25
|
+
* This determines the default icon and its color
|
|
26
|
+
* as well as the default text and color of the ok-button.
|
|
27
|
+
*/
|
|
28
|
+
variant: {
|
|
29
|
+
type: String as PropType<DialogVariant>,
|
|
30
|
+
default: 'warning',
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* The icon of the alert. This overrides the `icon` of the `variant`.
|
|
34
|
+
*/
|
|
35
|
+
icon: Function as PropType<HeroIcon>,
|
|
36
|
+
/**
|
|
37
|
+
* The color of the alert's icon. This overrides the `iconColor` of the `variant`.
|
|
38
|
+
*/
|
|
39
|
+
iconColor: String,
|
|
40
|
+
/**
|
|
41
|
+
* The text of the ok-button. This overrides the `okText` of the `variant`.
|
|
42
|
+
*/
|
|
43
|
+
okText: String,
|
|
44
|
+
/**
|
|
45
|
+
* The color of the ok-button. This overrides the `okColor` of the `variant`.
|
|
46
|
+
*/
|
|
47
|
+
okColor: String,
|
|
48
|
+
/**
|
|
49
|
+
* The text of the cancel-button.
|
|
50
|
+
*/
|
|
51
|
+
cancelText: {
|
|
52
|
+
type: String,
|
|
53
|
+
default: trsl('vue-collection.action.cancel'),
|
|
54
|
+
},
|
|
55
|
+
/**
|
|
56
|
+
* The color of the cancel-button.
|
|
57
|
+
*/
|
|
58
|
+
cancelColor: {
|
|
59
|
+
type: String,
|
|
60
|
+
default: 'default',
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* If set to `true` the cancel-button is hidden.
|
|
64
|
+
*/
|
|
65
|
+
hideCancel: Boolean,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type NDialogExposed = {
|
|
69
|
+
/**
|
|
70
|
+
* Shows the alert and returns a promise.
|
|
71
|
+
* When the user interaction occurs the promise is resolved.
|
|
72
|
+
* It is resolved to `true` if the okButton was clicked, `false` if the dialog was cancelled.
|
|
73
|
+
*/
|
|
74
|
+
show(): Promise<boolean>
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A `NDialog` is an element to interact directly with the user.
|
|
79
|
+
* It can be controlled via a ref to prompt the user and to receive their answer.
|
|
80
|
+
* @example
|
|
81
|
+
* const dialogRef = ref<NDialogExposed>()
|
|
82
|
+
* ...
|
|
83
|
+
* const onShowDialog = () => {
|
|
84
|
+
* dialofRef.value?.show().then(result => {
|
|
85
|
+
* if (result) // dialog accepted
|
|
86
|
+
* else // dialog cancelled
|
|
87
|
+
* })
|
|
88
|
+
* }
|
|
89
|
+
* ...
|
|
90
|
+
* <NDialog ref={dialogRef} />
|
|
91
|
+
*/
|
|
92
|
+
const Component = createComponent('NDialog', nDialogProps, (props, context) => {
|
|
93
|
+
const showDialog = ref(false)
|
|
94
|
+
|
|
95
|
+
let deferredPromise: DeferredPromise<boolean> | null = null
|
|
96
|
+
const show = (): Promise<boolean> => {
|
|
97
|
+
if (deferredPromise != null) {
|
|
98
|
+
deferredPromise.reject('show() was called on the open dialog.')
|
|
99
|
+
deferredPromise = null
|
|
100
|
+
}
|
|
101
|
+
showDialog.value = true
|
|
102
|
+
deferredPromise = deferred<boolean>()
|
|
103
|
+
return deferredPromise.promise
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
context.expose({ show })
|
|
107
|
+
|
|
108
|
+
const resolveWith = (result: boolean) => {
|
|
109
|
+
deferredPromise?.resolve(result)
|
|
110
|
+
deferredPromise = null
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const ok = () => resolveWith(true)
|
|
114
|
+
const cancel = () => resolveWith(false)
|
|
115
|
+
|
|
116
|
+
const defaults = computed(() => VARIANT_DEFAULTS[props.variant])
|
|
117
|
+
|
|
118
|
+
return () => (
|
|
119
|
+
<NModal
|
|
120
|
+
{...vModelForRef(showDialog)}
|
|
121
|
+
{...extractProps(props, 'cancelColor', 'cancelText', 'hideCancel')}
|
|
122
|
+
onOk={ok}
|
|
123
|
+
onCancel={cancel}
|
|
124
|
+
okColor={props.okColor || defaults.value.okColor}
|
|
125
|
+
okText={props.okText || defaults.value.okText}
|
|
126
|
+
hideX
|
|
127
|
+
hideHeader
|
|
128
|
+
>
|
|
129
|
+
<div class="flex space-x-4 py-2">
|
|
130
|
+
<div class="flex-grow-0">
|
|
131
|
+
<NIconCircle
|
|
132
|
+
icon={props.icon || defaults.value.icon}
|
|
133
|
+
iconSize={6}
|
|
134
|
+
color={props.iconColor || defaults.value.iconColor}
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
137
|
+
|
|
138
|
+
<div class="flex-grow">
|
|
139
|
+
<DialogTitle as="h4" class="font-medium text-lg text-default-700 mb-1">
|
|
140
|
+
{props.title}
|
|
141
|
+
</DialogTitle>
|
|
142
|
+
{context.slots.default?.() || <p class="text-sm text-default-500">{props.text}</p>}
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</NModal>
|
|
146
|
+
)
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
const VARIANT_DEFAULTS = {
|
|
150
|
+
success: {
|
|
151
|
+
icon: CheckIcon,
|
|
152
|
+
iconColor: 'green',
|
|
153
|
+
okText: trsl('vue-collection.action.all-right'),
|
|
154
|
+
okColor: 'green',
|
|
155
|
+
},
|
|
156
|
+
info: {
|
|
157
|
+
icon: LightBulbIcon,
|
|
158
|
+
iconColor: 'blue',
|
|
159
|
+
okText: trsl('vue-collection.action.all-right'),
|
|
160
|
+
okColor: 'blue',
|
|
161
|
+
},
|
|
162
|
+
warning: {
|
|
163
|
+
icon: ExclamationTriangleIcon,
|
|
164
|
+
iconColor: 'yellow',
|
|
165
|
+
okText: trsl('vue-collection.action.proceed'),
|
|
166
|
+
okColor: 'yellow',
|
|
167
|
+
},
|
|
168
|
+
danger: {
|
|
169
|
+
icon: ExclamationTriangleIcon,
|
|
170
|
+
iconColor: 'red',
|
|
171
|
+
okText: trsl('vue-collection.action.proceed'),
|
|
172
|
+
okColor: 'red',
|
|
173
|
+
},
|
|
174
|
+
remove: {
|
|
175
|
+
icon: TrashIcon,
|
|
176
|
+
iconColor: 'red',
|
|
177
|
+
okText: trsl('vue-collection.action.remove'),
|
|
178
|
+
okColor: 'red',
|
|
179
|
+
},
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export { Component as NDialog, Component as default }
|