@naptics/vue-collection 0.2.15 → 0.3.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/.github/workflows/build.yml +26 -0
- package/.github/workflows/deploy-demo.yml +46 -0
- package/.github/workflows/deploy-lib.yml +65 -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 +1 -70
- 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 +50 -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 +68 -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,146 @@
|
|
|
1
|
+
import NBadge from '@/lib/components/NBadge'
|
|
2
|
+
import NIconButton from '@/lib/components/NIconButton'
|
|
3
|
+
import NTable, { type TableHeading } from '@/lib/components/NTable'
|
|
4
|
+
import NTableAction from '@/lib/components/NTableAction'
|
|
5
|
+
import ComponentSection from '@/demo/components/ComponentSection'
|
|
6
|
+
import VariantSection from '@/demo/components/VariantSection'
|
|
7
|
+
import { createView } from '@/lib/utils/component'
|
|
8
|
+
import { PencilIcon, MagnifyingGlassIcon } from '@heroicons/vue/24/solid'
|
|
9
|
+
|
|
10
|
+
export default createView('TableView', () => {
|
|
11
|
+
const headings: TableHeading[] = [
|
|
12
|
+
{ key: 'id', label: 'ID' },
|
|
13
|
+
{ key: 'username', label: 'Username', emph: true },
|
|
14
|
+
{ key: 'email', label: 'Email', breakpoint: 'md' },
|
|
15
|
+
{ key: 'phone', label: 'Phone', breakpoint: 'lg' },
|
|
16
|
+
{ key: 'state', label: 'State', breakpoint: 'sm' },
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
const details: TableHeading[] = [
|
|
20
|
+
{ key: 'address', label: 'Addresse', isDetail: true },
|
|
21
|
+
{ key: 'zip', label: 'PLZ', isDetail: true },
|
|
22
|
+
{ key: 'place', label: 'Ort', isDetail: true },
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
const data = [
|
|
26
|
+
{
|
|
27
|
+
id: 1,
|
|
28
|
+
username: 'herbert',
|
|
29
|
+
email: 'herbert@naptics.ch',
|
|
30
|
+
phone: '+41 76 810 29 21',
|
|
31
|
+
state: 'unknown',
|
|
32
|
+
address: 'Hugentoblergasse 132',
|
|
33
|
+
zip: '8400',
|
|
34
|
+
place: 'Winterthur',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 2,
|
|
38
|
+
username: 'franziska',
|
|
39
|
+
email: 'franzsika@naptics.ch',
|
|
40
|
+
phone: '+41 76 810 28 22',
|
|
41
|
+
state: 'registered',
|
|
42
|
+
address: 'Hugentoblergasse 132',
|
|
43
|
+
zip: '8400',
|
|
44
|
+
place: 'Winterthur',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 3,
|
|
48
|
+
username: 'frank',
|
|
49
|
+
email: 'frank@naptics.ch',
|
|
50
|
+
phone: '+41 76 810 27 23',
|
|
51
|
+
state: 'registered',
|
|
52
|
+
address: 'Hugentoblergasse 132',
|
|
53
|
+
zip: '8400',
|
|
54
|
+
place: 'Winterthur',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 4,
|
|
58
|
+
username: 'prünhilde',
|
|
59
|
+
email: 'pruenhilde@naptics.ch',
|
|
60
|
+
phone: '+41 76 810 26 24',
|
|
61
|
+
state: 'banned',
|
|
62
|
+
address: 'Hugentoblergasse 132',
|
|
63
|
+
zip: '8400',
|
|
64
|
+
place: 'Winterthur',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 5,
|
|
68
|
+
username: 'gertrud',
|
|
69
|
+
email: 'gertrud@naptics.ch',
|
|
70
|
+
phone: '+41 76 810 25 25',
|
|
71
|
+
state: 'registered',
|
|
72
|
+
address: 'Hugentoblergasse 132',
|
|
73
|
+
zip: '8400',
|
|
74
|
+
place: 'Winterthur',
|
|
75
|
+
},
|
|
76
|
+
]
|
|
77
|
+
|
|
78
|
+
return () => (
|
|
79
|
+
<ComponentSection
|
|
80
|
+
title="Tables"
|
|
81
|
+
subtitle="Tables are perfect to display a lot of data in an orderly way."
|
|
82
|
+
id="tables"
|
|
83
|
+
>
|
|
84
|
+
<VariantSection
|
|
85
|
+
title="Basic Table"
|
|
86
|
+
subtitle="If nothing needs to be customized, the data can be displayed directly as text."
|
|
87
|
+
>
|
|
88
|
+
<NTable headings={headings} items={data} />
|
|
89
|
+
</VariantSection>
|
|
90
|
+
|
|
91
|
+
<VariantSection
|
|
92
|
+
title="Customization"
|
|
93
|
+
subtitle="Individual columns can be customized to use other elements."
|
|
94
|
+
>
|
|
95
|
+
<NTable
|
|
96
|
+
headings={headings}
|
|
97
|
+
items={data.map(item => ({
|
|
98
|
+
...item,
|
|
99
|
+
state: () => (
|
|
100
|
+
<NBadge
|
|
101
|
+
textSize="text-xs"
|
|
102
|
+
color={
|
|
103
|
+
item.state == 'registered' ? 'green' : item.state == 'banned' ? 'red' : 'default'
|
|
104
|
+
}
|
|
105
|
+
>
|
|
106
|
+
{item.state}
|
|
107
|
+
</NBadge>
|
|
108
|
+
),
|
|
109
|
+
}))}
|
|
110
|
+
/>
|
|
111
|
+
</VariantSection>
|
|
112
|
+
|
|
113
|
+
<VariantSection
|
|
114
|
+
title="With Details"
|
|
115
|
+
subtitle="If there is a lot of information to display, a details section can be added."
|
|
116
|
+
>
|
|
117
|
+
<NTable headings={[...headings, ...details]} items={data} />
|
|
118
|
+
</VariantSection>
|
|
119
|
+
|
|
120
|
+
<VariantSection
|
|
121
|
+
title="Actions"
|
|
122
|
+
subtitle="Table Actions can be added to either trigger an action or navigate to a route."
|
|
123
|
+
>
|
|
124
|
+
<NTable
|
|
125
|
+
headings={headings}
|
|
126
|
+
items={data.map(item => ({
|
|
127
|
+
...item,
|
|
128
|
+
username: () => <NTableAction route={`/`} text={item.username} />,
|
|
129
|
+
action: () => (
|
|
130
|
+
<>
|
|
131
|
+
<NIconButton
|
|
132
|
+
icon={PencilIcon}
|
|
133
|
+
onClick={() => alert(`You will edit ${item.username}.`)}
|
|
134
|
+
/>
|
|
135
|
+
<NIconButton
|
|
136
|
+
icon={MagnifyingGlassIcon}
|
|
137
|
+
onClick={() => alert(`You will lookup ${item.username}.`)}
|
|
138
|
+
/>
|
|
139
|
+
</>
|
|
140
|
+
),
|
|
141
|
+
}))}
|
|
142
|
+
/>
|
|
143
|
+
</VariantSection>
|
|
144
|
+
</ComponentSection>
|
|
145
|
+
)
|
|
146
|
+
})
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import NBadge from '@/lib/components/NBadge'
|
|
2
|
+
import NButton from '@/lib/components/NButton'
|
|
3
|
+
import NIconButton from '@/lib/components/NIconButton'
|
|
4
|
+
import NInput from '@/lib/components/NInput'
|
|
5
|
+
import NTooltip from '@/lib/components/NTooltip'
|
|
6
|
+
import ComponentGrid from '@/demo/components/ComponentGrid'
|
|
7
|
+
import ComponentSection from '@/demo/components/ComponentSection'
|
|
8
|
+
import VariantSection from '@/demo/components/VariantSection'
|
|
9
|
+
import { createView } from '@/lib/utils/component'
|
|
10
|
+
import { ArrowTopRightOnSquareIcon } from '@heroicons/vue/24/solid'
|
|
11
|
+
|
|
12
|
+
export default createView('TooltipView', () => {
|
|
13
|
+
return () => (
|
|
14
|
+
<ComponentSection
|
|
15
|
+
id="tooltips"
|
|
16
|
+
title="Tooltips"
|
|
17
|
+
subtitle="Tooltips can be added to all components to display small explanations or tips to the user."
|
|
18
|
+
>
|
|
19
|
+
<VariantSection
|
|
20
|
+
title="Customization"
|
|
21
|
+
subtitle="The content of a tooltip can be a simple text or there is a slot available for customization. More properties like placement, maximum width and more can be configured."
|
|
22
|
+
>
|
|
23
|
+
<ComponentGrid cols={4}>
|
|
24
|
+
<div class="flex">
|
|
25
|
+
<NTooltip text="Hello tooltip!">
|
|
26
|
+
<NBadge text="Hover me" />
|
|
27
|
+
</NTooltip>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<div class="flex">
|
|
31
|
+
<NTooltip
|
|
32
|
+
content={() => (
|
|
33
|
+
<div>
|
|
34
|
+
<h2 class="font-medium text-base"> The importance of tooltips</h2>
|
|
35
|
+
<p>
|
|
36
|
+
Tooltips are very important as they allow the display information conditionally
|
|
37
|
+
on the screen.
|
|
38
|
+
</p>
|
|
39
|
+
</div>
|
|
40
|
+
)}
|
|
41
|
+
>
|
|
42
|
+
<NBadge text="Hover me" />
|
|
43
|
+
</NTooltip>
|
|
44
|
+
</div>
|
|
45
|
+
|
|
46
|
+
<div class="flex">
|
|
47
|
+
<NTooltip text="Tooltip placed at «top-start»." placement="top-start">
|
|
48
|
+
<NBadge text="Hover me" />
|
|
49
|
+
</NTooltip>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div class="flex">
|
|
53
|
+
<NTooltip
|
|
54
|
+
text="I don't go away, but I am a multiline text in a tooltip. I wrap around multiple lines."
|
|
55
|
+
placement="bottom-start"
|
|
56
|
+
>
|
|
57
|
+
<NBadge text="Hover me" />
|
|
58
|
+
</NTooltip>
|
|
59
|
+
</div>
|
|
60
|
+
</ComponentGrid>
|
|
61
|
+
</VariantSection>
|
|
62
|
+
|
|
63
|
+
<VariantSection
|
|
64
|
+
title="Out of the box"
|
|
65
|
+
subtitle="The following components contain integrated tooltips out of the box."
|
|
66
|
+
>
|
|
67
|
+
<ComponentGrid cols={4}>
|
|
68
|
+
<div class="flex items-center">
|
|
69
|
+
<NIconButton
|
|
70
|
+
icon={ArrowTopRightOnSquareIcon}
|
|
71
|
+
tooltipText="Icon Buttons have integrated tooltips."
|
|
72
|
+
/>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="flex items-center">
|
|
75
|
+
<NButton tooltipText="Buttons have integrated tooltips."> Button </NButton>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="flex items-center">
|
|
78
|
+
<NBadge text="Badge" tooltipText="Badges have integrated tooltips." />
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<NInput name="Disabled" disabled tooltipText="Inputs have integrated tooltips." />
|
|
82
|
+
</ComponentGrid>
|
|
83
|
+
</VariantSection>
|
|
84
|
+
</ComponentSection>
|
|
85
|
+
)
|
|
86
|
+
})
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { HeroIcon } from '../utils/tailwind'
|
|
2
|
+
import { createComponent } from '../utils/component'
|
|
3
|
+
import { CheckCircleIcon, ExclamationCircleIcon, InformationCircleIcon, XMarkIcon } from '@heroicons/vue/24/solid'
|
|
4
|
+
import { computed, type PropType } from 'vue'
|
|
5
|
+
import NIconButton from './NIconButton'
|
|
6
|
+
import NLoadingIndicator from './NLoadingIndicator'
|
|
7
|
+
|
|
8
|
+
export type AlertVariant = 'success' | 'info' | 'warning' | 'error' | 'loading'
|
|
9
|
+
|
|
10
|
+
export const nAlertProps = {
|
|
11
|
+
/**
|
|
12
|
+
* The variant of the alert. This defines its color and icon.
|
|
13
|
+
*/
|
|
14
|
+
variant: {
|
|
15
|
+
type: String as PropType<AlertVariant>,
|
|
16
|
+
default: 'success',
|
|
17
|
+
},
|
|
18
|
+
/**
|
|
19
|
+
* The text of the alert.
|
|
20
|
+
*/
|
|
21
|
+
text: String,
|
|
22
|
+
/**
|
|
23
|
+
* If set to `true` the X-button of the alert is hidden.
|
|
24
|
+
*/
|
|
25
|
+
hideX: Boolean,
|
|
26
|
+
/**
|
|
27
|
+
* This is called, when the X-button is clicked.
|
|
28
|
+
*/
|
|
29
|
+
onDismiss: Function as PropType<() => void>,
|
|
30
|
+
} as const
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The `NAlert` is a fully styled alert with multiple variants.
|
|
34
|
+
* It can be used as a normal blocking element or as part of an alert queue.
|
|
35
|
+
*/
|
|
36
|
+
const Component = createComponent('NAlert', nAlertProps, (props, { slots }) => {
|
|
37
|
+
const variant = computed(() => VARIANTS[props.variant])
|
|
38
|
+
|
|
39
|
+
return () => (
|
|
40
|
+
<div class={`rounded-md p-3 shadow-lg bg-${variant.value.color}-50`}>
|
|
41
|
+
<div class="flex items-center">
|
|
42
|
+
<div class="flex flex-shrink-0 items-center">{variant.value.icon()}</div>
|
|
43
|
+
|
|
44
|
+
<div class="ml-3 flex-grow">
|
|
45
|
+
<p class={`text-sm font-medium text-${variant.value.color}-900`}>
|
|
46
|
+
{slots.default?.() ?? props.text}
|
|
47
|
+
</p>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
{!props.hideX && (
|
|
51
|
+
<div class="flex items-center flex-shrink-0 ml-3">
|
|
52
|
+
<NIconButton color={variant.value.color} size={5} icon={XMarkIcon} onClick={props.onDismiss} />
|
|
53
|
+
</div>
|
|
54
|
+
)}
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
const icon = (icon: HeroIcon, color: string) => () => <icon class={`h-5 w-5 text-${color}-500`} />
|
|
61
|
+
|
|
62
|
+
const VARIANTS = {
|
|
63
|
+
success: {
|
|
64
|
+
icon: icon(CheckCircleIcon, 'green'),
|
|
65
|
+
color: 'green',
|
|
66
|
+
},
|
|
67
|
+
info: {
|
|
68
|
+
icon: icon(InformationCircleIcon, 'blue'),
|
|
69
|
+
color: 'blue',
|
|
70
|
+
},
|
|
71
|
+
warning: {
|
|
72
|
+
icon: icon(ExclamationCircleIcon, 'yellow'),
|
|
73
|
+
color: 'yellow',
|
|
74
|
+
},
|
|
75
|
+
error: {
|
|
76
|
+
icon: icon(ExclamationCircleIcon, 'red'),
|
|
77
|
+
color: 'red',
|
|
78
|
+
},
|
|
79
|
+
loading: {
|
|
80
|
+
icon: () => <NLoadingIndicator color="blue" size={7} shade={500} />,
|
|
81
|
+
color: 'blue',
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { Component as NAlert, Component as default }
|
|
@@ -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 }
|