@demos-europe/demosplan-ui 0.0.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.
Files changed (133) hide show
  1. package/LICENSE +21 -0
  2. package/buildTokens.js +59 -0
  3. package/components/DpButton/DpButton.stories.mdx +136 -0
  4. package/components/DpButton/DpButton.vue +118 -0
  5. package/components/DpDetails/DpDetails.stories.mdx +55 -0
  6. package/components/DpDetails/DpDetails.vue +58 -0
  7. package/components/DpIcon/DpIcon.stories.mdx +396 -0
  8. package/components/DpIcon/DpIcon.vue +51 -0
  9. package/components/DpIcon/util/iconVariables.js +148 -0
  10. package/components/DpInput/DpInput.stories.mdx +127 -0
  11. package/components/DpInput/DpInput.vue +284 -0
  12. package/components/DpLabel/DpLabel.stories.mdx +103 -0
  13. package/components/DpLabel/DpLabel.vue +112 -0
  14. package/components/DpLoading/DpLoading.stories.mdx +63 -0
  15. package/components/DpLoading/DpLoading.vue +63 -0
  16. package/components/core/DpAccordion.vue +108 -0
  17. package/components/core/DpAnonymizeText.vue +136 -0
  18. package/components/core/DpAutocomplete.vue +133 -0
  19. package/components/core/DpBulkEditHeader.vue +53 -0
  20. package/components/core/DpButtonIcon.vue +47 -0
  21. package/components/core/DpButtonRow.vue +155 -0
  22. package/components/core/DpCard.vue +54 -0
  23. package/components/core/DpChangeStateAtDate.vue +223 -0
  24. package/components/core/DpCheckboxGroup.vue +93 -0
  25. package/components/core/DpContextualHelp.vue +54 -0
  26. package/components/core/DpCopyPasteButton.vue +47 -0
  27. package/components/core/DpDashboardTaskCard.vue +123 -0
  28. package/components/core/DpDataTable/DataTableSearch.js +44 -0
  29. package/components/core/DpDataTable/DpColumnSelector.vue +133 -0
  30. package/components/core/DpDataTable/DpDataTable.vue +647 -0
  31. package/components/core/DpDataTable/DpDataTableExtended.vue +377 -0
  32. package/components/core/DpDataTable/DpResizeHandle.vue +37 -0
  33. package/components/core/DpDataTable/DpSelectPageItemCount.vue +70 -0
  34. package/components/core/DpDataTable/DpTableHeader.vue +197 -0
  35. package/components/core/DpDataTable/DpTableRow.vue +355 -0
  36. package/components/core/DpDataTable/DpWrapTrigger.vue +48 -0
  37. package/components/core/DpDataTable/lib/ResizableColumns.js +83 -0
  38. package/components/core/DpEditableList.vue +161 -0
  39. package/components/core/DpEditor/DpBoilerPlate.vue +140 -0
  40. package/components/core/DpEditor/DpBoilerPlateModal.vue +166 -0
  41. package/components/core/DpEditor/DpEditor.vue +1281 -0
  42. package/components/core/DpEditor/DpLinkModal.vue +117 -0
  43. package/components/core/DpEditor/DpRecommendationModal/DpInsertableRecommendation.vue +137 -0
  44. package/components/core/DpEditor/DpRecommendationModal.vue +283 -0
  45. package/components/core/DpEditor/DpResizableImage.vue +121 -0
  46. package/components/core/DpEditor/DpUploadModal.vue +121 -0
  47. package/components/core/DpEditor/libs/Decoration.js +66 -0
  48. package/components/core/DpEditor/libs/SegmentRangeChangePlugin.js +35 -0
  49. package/components/core/DpEditor/libs/editorAnonymize.js +66 -0
  50. package/components/core/DpEditor/libs/editorBuildSuggestion.js +269 -0
  51. package/components/core/DpEditor/libs/editorCustomDelete.js +32 -0
  52. package/components/core/DpEditor/libs/editorCustomImage.js +100 -0
  53. package/components/core/DpEditor/libs/editorCustomInsert.js +32 -0
  54. package/components/core/DpEditor/libs/editorCustomLink.js +46 -0
  55. package/components/core/DpEditor/libs/editorCustomMark.js +32 -0
  56. package/components/core/DpEditor/libs/editorInsertAtCursorPos.js +41 -0
  57. package/components/core/DpEditor/libs/editorObscure.js +60 -0
  58. package/components/core/DpEditor/libs/editorUnAnonymize.js +56 -0
  59. package/components/core/DpEditor/libs/handleWordPaste.js +360 -0
  60. package/components/core/DpEditor/libs/preventDrop.js +31 -0
  61. package/components/core/DpEditor/libs/preventKeyboardInput.js +27 -0
  62. package/components/core/DpEditor/libs/preventPaste.js +28 -0
  63. package/components/core/DpFlyout.vue +119 -0
  64. package/components/core/DpInlineNotification.vue +116 -0
  65. package/components/core/DpModal.vue +208 -0
  66. package/components/core/DpObscure.vue +29 -0
  67. package/components/core/DpPager.vue +139 -0
  68. package/components/core/DpProgressBar.vue +67 -0
  69. package/components/core/DpRegisterFlyout.vue +58 -0
  70. package/components/core/DpResettableInput.vue +140 -0
  71. package/components/core/DpSkeletonBox.vue +32 -0
  72. package/components/core/DpSlidebar.vue +86 -0
  73. package/components/core/DpSlidingPagination.vue +45 -0
  74. package/components/core/DpSplitButton.vue +77 -0
  75. package/components/core/DpSwitcher.vue +62 -0
  76. package/components/core/DpTableCardList/DpTableCard.vue +61 -0
  77. package/components/core/DpTableCardList/DpTableCardListHeader.vue +83 -0
  78. package/components/core/DpTabs/DpTab.vue +52 -0
  79. package/components/core/DpTabs/DpTabs.vue +165 -0
  80. package/components/core/DpTextWrapper.vue +65 -0
  81. package/components/core/DpToggleForm.vue +72 -0
  82. package/components/core/DpTooltipIcon.vue +52 -0
  83. package/components/core/DpTransitionExpand.vue +87 -0
  84. package/components/core/DpTreeList/DpTreeList.vue +334 -0
  85. package/components/core/DpTreeList/DpTreeListCheckbox.vue +79 -0
  86. package/components/core/DpTreeList/DpTreeListNode.vue +348 -0
  87. package/components/core/DpTreeList/DpTreeListToggle.vue +71 -0
  88. package/components/core/DpTreeList/utils/constants.js +14 -0
  89. package/components/core/DpUpload/DpUpload.vue +223 -0
  90. package/components/core/DpUpload/DpUploadFiles.vue +269 -0
  91. package/components/core/DpUpload/DpUploadedFile.vue +80 -0
  92. package/components/core/DpUpload/DpUploadedFileList.vue +56 -0
  93. package/components/core/DpUpload/utils/GetFileIdsByHash.js +42 -0
  94. package/components/core/DpUpload/utils/UppyTranslations.js +31 -0
  95. package/components/core/DpVideoPlayer.vue +115 -0
  96. package/components/core/HeightLimit.vue +121 -0
  97. package/components/core/MultistepNav.vue +89 -0
  98. package/components/core/form/DpCheckbox.vue +108 -0
  99. package/components/core/form/DpDateRangePicker.vue +186 -0
  100. package/components/core/form/DpDatepicker.vue +160 -0
  101. package/components/core/form/DpDatetimePicker.vue +194 -0
  102. package/components/core/form/DpFormRow.vue +79 -0
  103. package/components/core/form/DpMultiselect.vue +164 -0
  104. package/components/core/form/DpRadio.vue +128 -0
  105. package/components/core/form/DpSearchField.vue +110 -0
  106. package/components/core/form/DpSelect.vue +149 -0
  107. package/components/core/form/DpTextArea.vue +152 -0
  108. package/components/core/form/DpTimePicker.vue +374 -0
  109. package/components/core/form/DpToggle.vue +78 -0
  110. package/components/core/index.js +132 -0
  111. package/components/core/notify/DpNotifyContainer.vue +122 -0
  112. package/components/core/notify/DpNotifyMessage.vue +95 -0
  113. package/components/core/shared/DpStickyElement.vue +95 -0
  114. package/components/index.js +24 -0
  115. package/components/shared/translations.js +15 -0
  116. package/directives/CleanHtml/CleanHtml.js +50 -0
  117. package/directives/CleanHtml/CleanHtml.stories.mdx +64 -0
  118. package/directives/Tooltip/Tooltip.js +40 -0
  119. package/directives/Tooltip/Tooltip.stories.mdx +42 -0
  120. package/directives/index.js +17 -0
  121. package/lib/index.js +14 -0
  122. package/lib/prefixClass.js +47 -0
  123. package/mixins/index.js +14 -0
  124. package/mixins/prefixClassMixin.js +22 -0
  125. package/package.json +52 -0
  126. package/shared/props.js +86 -0
  127. package/style/index.css +7 -0
  128. package/tailwind.config.js +24 -0
  129. package/tokens/color.json +358 -0
  130. package/tokens/color.stories.mdx +45 -0
  131. package/tokens/fontSize.json +100 -0
  132. package/tokens/space.json +33 -0
  133. package/utils/lengthHint.js +69 -0
@@ -0,0 +1,127 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs'
2
+ import DpInput from './DpInput'
3
+
4
+ <Meta
5
+ title="Components/Input"
6
+ component={DpInput}
7
+ argTypes={{
8
+ maxlength: {
9
+ control: {
10
+ type: 'number'
11
+ }
12
+ }
13
+ }} />
14
+
15
+ # Input
16
+
17
+ The `DpInput` component is used for the following form input fields:
18
+ - text
19
+ - email
20
+ - number
21
+ - password
22
+ - tel
23
+
24
+ export const Template = (args, { argTypes }) => ({
25
+ props: Object.keys(argTypes),
26
+ components: { DpInput },
27
+ template: `<dp-input v-bind="$props" />`
28
+ });
29
+
30
+ ## Examples
31
+
32
+ ### Text input
33
+
34
+ <Canvas>
35
+ <Story
36
+ name="Text input"
37
+ args={{
38
+ id: 'someId',
39
+ label: {
40
+ text: 'First name'
41
+ },
42
+ width: 'u-1-of-2'
43
+ }}>
44
+ {Template.bind({})}
45
+ </Story>
46
+ </Canvas>
47
+
48
+ ### Hint
49
+
50
+ The `hint` property adds the provided string between label and input field.
51
+
52
+ <Canvas>
53
+ <Story
54
+ name="Hint"
55
+ args={{
56
+ id: 'someId',
57
+ label: {
58
+ hint: 'This is a hint that explains what to enter in the input',
59
+ text: 'Contact person'
60
+ },
61
+ width: 'u-1-of-2'
62
+ }}>
63
+ {Template.bind({})}
64
+ </Story>
65
+ </Canvas>
66
+
67
+ ### Required
68
+
69
+ If an input field is `required`, an asterisk will be added to its label.
70
+
71
+ <Canvas>
72
+ <Story
73
+ name="Required"
74
+ args={{
75
+ id: 'someId',
76
+ label: {
77
+ text: 'Phone'
78
+ },
79
+ pattern: '^(\+?)(-| |[0-9]|\(|\))*$',
80
+ required: true,
81
+ type: 'tel',
82
+ width: 'u-1-of-4'
83
+ }}>
84
+ {Template.bind({})}
85
+ </Story>
86
+ </Canvas>
87
+
88
+ ### Disabled
89
+
90
+ <Canvas>
91
+ <Story
92
+ name="Disabled"
93
+ args={{
94
+ disabled: true,
95
+ id: 'someId',
96
+ label: {
97
+ text: 'Email address'
98
+ },
99
+ pattern: '^(\+?)(-| |[0-9]|\(|\))*$',
100
+ type: 'email',
101
+ value: 'yourEmail@example.com',
102
+ width: 'u-1-of-4'
103
+ }}>
104
+ {Template.bind({})}
105
+ </Story>
106
+ </Canvas>
107
+
108
+ ### Tooltip
109
+
110
+ The `tooltip` property adds a contextual help icon that reveals additional information on the input field when the user hovers
111
+ over it with their mouse. It should be used sparingly and only to reveal non-critical information, whereas critical information should be presented immediately.
112
+
113
+ <Canvas>
114
+ <Story
115
+ name="Tooltip"
116
+ args={{
117
+ id: 'someId',
118
+ label: {
119
+ text: 'Last name',
120
+ tooltip: 'This is a text adding some more information on the input field'
121
+ },
122
+ type: 'text',
123
+ width: 'u-1-of-4'
124
+ }}>
125
+ {Template.bind({})}
126
+ </Story>
127
+ </Canvas>
@@ -0,0 +1,284 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <div :class="containerWidth !== '' ? prefixClass(containerWidth) : false">
12
+ <dp-label
13
+ v-if="label.text !== ''"
14
+ v-bind="{
15
+ ...label,
16
+ for: id,
17
+ hint: labelHint,
18
+ required: required
19
+ }" /><!--
20
+ --><input
21
+ :id="id"
22
+ :name="name !== '' ? name : false"
23
+ :class="prefixClass(classes)"
24
+ :data-counter="dataCounter !== '' ? dataCounter : false"
25
+ :data-dp-validate-error="dataDpValidateError || false"
26
+ :data-dp-validate-if="dataDpValidateIf !== '' ? dataDpValidateIf : false"
27
+ :data-dp-validate-should-equal="dataDpValidateShouldEqual !== '' ? dataDpValidateShouldEqual : false"
28
+ :data-cy="dataCy !== '' ? dataCy : false"
29
+ :aria-labelledby="ariaLabelledby"
30
+ :maxlength="maxlength !== '' ? maxlength : false"
31
+ :minlength="minlength !== '' ? minlength : false"
32
+ :type="type"
33
+ :pattern="pattern !== '' ? pattern : false"
34
+ :placeholder="placeholder !== '' ? placeholder : false"
35
+ :disabled="disabled"
36
+ :readonly="readonly"
37
+ :required="required"
38
+ :autocomplete="autocomplete !== '' ? autocomplete : false"
39
+ :size="size ? size : false"
40
+ v-model="currentValue"
41
+ @focus="$emit('focus')"
42
+ @input="$emit('input', currentValue)"
43
+ @keydown.enter="handleEnter">
44
+ </div>
45
+ </template>
46
+
47
+ <script>
48
+ import { exactlengthHint, maxlengthHint, minlengthHint } from '../../utils/lengthHint'
49
+ import DpLabel from '../DpLabel/DpLabel'
50
+ import { length } from '../../shared/props'
51
+ import { prefixClassMixin } from '../../mixins'
52
+
53
+ export default {
54
+ name: 'DpInput',
55
+
56
+ components: {
57
+ DpLabel
58
+ },
59
+
60
+ mixins: [prefixClassMixin],
61
+
62
+ props: {
63
+ /**
64
+ * Reference another element on the page to define an accessible name if there is no label or
65
+ * you want to override the label.
66
+ */
67
+ ariaLabelledby: {
68
+ type: [String, Boolean],
69
+ required: false,
70
+ default: false
71
+ },
72
+
73
+ /**
74
+ * Tell the browser if autocomplete is allowed or not. If enabled the browser is allowed
75
+ * to automatically complete the input. You can also provide a type of data which is expected.
76
+ */
77
+ autocomplete: {
78
+ type: String,
79
+ required: false,
80
+ default: ''
81
+ },
82
+
83
+ dataCounter: {
84
+ type: String,
85
+ required: false,
86
+ default: ''
87
+ },
88
+
89
+ dataCy: {
90
+ type: String,
91
+ required: false,
92
+ default: ''
93
+ },
94
+
95
+ dataDpValidateError: {
96
+ type: String,
97
+ required: false,
98
+ default: ''
99
+ },
100
+
101
+ dataDpValidateIf: {
102
+ type: String,
103
+ required: false,
104
+ default: ''
105
+ },
106
+
107
+ dataDpValidateShouldEqual: {
108
+ type: String,
109
+ required: false,
110
+ default: ''
111
+ },
112
+
113
+ disabled: {
114
+ type: Boolean,
115
+ required: false,
116
+ default: false
117
+ },
118
+
119
+ /**
120
+ * Use: when input field used with Icon || Button, then input field has padding right.
121
+ */
122
+ hasIcon: {
123
+ type: Boolean,
124
+ required: false,
125
+ default: false
126
+ },
127
+
128
+ id: {
129
+ type: String,
130
+ required: true
131
+ },
132
+
133
+ label: {
134
+ type: Object,
135
+ default: () => ({
136
+ bold: true,
137
+ hint: '',
138
+ text: '',
139
+ tooltip: ''
140
+ }),
141
+ validator: (prop) => {
142
+ return Object.keys(prop).every(key => ['bold', 'hint', 'text', 'tooltip'].includes(key))
143
+ }
144
+ },
145
+
146
+ /**
147
+ * Limit the maximum allowed number of characters to the given amount.
148
+ */
149
+ maxlength: length,
150
+
151
+ /**
152
+ * Define the minimum number of characters that need to be given.
153
+ */
154
+ minlength: length,
155
+
156
+ name: {
157
+ type: String,
158
+ required: false,
159
+ default: ''
160
+ },
161
+
162
+ pattern: {
163
+ type: String,
164
+ required: false,
165
+ default: ''
166
+ },
167
+
168
+ placeholder: {
169
+ type: String,
170
+ required: false,
171
+ default: ''
172
+ },
173
+
174
+ /**
175
+ * Set to false to prevent default behavior onEnter.
176
+ */
177
+ preventDefaultOnEnter: {
178
+ type: Boolean,
179
+ required: false,
180
+ default: true
181
+ },
182
+
183
+ readonly: {
184
+ type: Boolean,
185
+ required: false,
186
+ default: false
187
+ },
188
+
189
+ required: {
190
+ type: Boolean,
191
+ required: false,
192
+ default: false
193
+ },
194
+
195
+ /**
196
+ * When setting a number for the `size` prop, this is directly rendered
197
+ * as html attribute on the input element. Also, it is assumed that visual sizing
198
+ * based on that value shall be applied, that is why both container classes
199
+ * and element classes do not define any width styles when a size is set here.
200
+ */
201
+ size: {
202
+ type: Number,
203
+ required: false,
204
+ default: undefined
205
+ },
206
+
207
+ type: {
208
+ type: String,
209
+ required: false,
210
+ default: 'text'
211
+ },
212
+
213
+ value: {
214
+ type: String,
215
+ required: false,
216
+ default: ''
217
+ },
218
+
219
+ /**
220
+ * Full width by default; set to 'auto' to have no width defined.
221
+ * @deprecated Apply width to the parent element of DpInput.
222
+ */
223
+ width: {
224
+ type: String,
225
+ default: 'u-1-of-1'
226
+ }
227
+ },
228
+
229
+ data () {
230
+ return {
231
+ currentValue: this.value
232
+ }
233
+ },
234
+
235
+ computed: {
236
+ classes () {
237
+ let cssClasses = []
238
+ cssClasses = (this.size > 0) ? [] : [...cssClasses, 'u-1-of-1']
239
+ cssClasses = this.readonly || this.disabled ? [...cssClasses, 'bg-color--grey-light-2'] : cssClasses
240
+ cssClasses = this.type !== 'search' ? [...cssClasses, 'o-form__control-input'] : [...cssClasses, 'o-form__control-search']
241
+ cssClasses = this.hasIcon ? [...cssClasses, 'u-pr'] : cssClasses
242
+ return cssClasses.join(' ')
243
+ },
244
+
245
+ containerWidth () {
246
+ return (this.width === 'auto' || this.size > 0) ? '' : this.width
247
+ },
248
+
249
+ labelHint () {
250
+ const hint = typeof this.label.hint !== 'undefined' && this.label.hint !== '' ? [this.label.hint] : []
251
+
252
+ if (this.maxlength && !this.minlength) {
253
+ hint.push(maxlengthHint(this.currentValue.length, this.maxlength))
254
+ } else if (this.minlength && !this.maxlength) {
255
+ hint.push(minlengthHint(this.currentValue.length, this.minlength))
256
+ } else if (this.maxlength && this.minlength) {
257
+ if (this.maxlength === this.minlength) {
258
+ hint.push(exactlengthHint(this.currentValue.length, this.maxlength))
259
+ } else {
260
+ hint.push(maxlengthHint(this.currentValue.length, this.maxlength))
261
+ hint.push(minlengthHint(this.currentValue.length, this.minlength))
262
+ }
263
+ }
264
+
265
+ return hint
266
+ }
267
+ },
268
+
269
+ watch: {
270
+ value: function () {
271
+ this.currentValue = this.value
272
+ }
273
+ },
274
+
275
+ methods: {
276
+ handleEnter (event) {
277
+ if (this.preventDefaultOnEnter === true) {
278
+ event.preventDefault()
279
+ }
280
+ this.$emit('enter')
281
+ }
282
+ }
283
+ }
284
+ </script>
@@ -0,0 +1,103 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs'
2
+ import DpLabel from './DpLabel'
3
+
4
+ <Meta
5
+ title="Components/Label"
6
+ component={DpLabel} />
7
+
8
+ # Label
9
+
10
+ The `DpLabel` component is used to add a label to form controls.
11
+
12
+ It is included in the following <strong><i>demosplan-ui</i></strong> form components:
13
+
14
+ - DpCheckbox
15
+ - DpInput
16
+ - DpRadio
17
+ - DpSelect
18
+ - DpDateTimePicker
19
+ - DpTextarea
20
+ - DpTimePicker
21
+
22
+ If you want to use any of these components, you don't need to import `DpLabel` separately.
23
+
24
+ `DpLabel` is currently not included in the following <strong><i>demosplan-ui</i></strong> form components:
25
+
26
+ - DpMultiselect
27
+ - DpTiptap
28
+ - DpDatepicker
29
+ - DpDateRangePicker
30
+
31
+ If you want to use any of these components, you need to import `DpLabel` separately.
32
+
33
+ export const Template = (args, { argTypes }) => ({
34
+ props: Object.keys(argTypes),
35
+ components: { DpLabel },
36
+ template: `<dp-label v-bind="$props" />`
37
+ });
38
+
39
+ ## Default usage
40
+
41
+ <Canvas>
42
+ <Story
43
+ name="Default usage"
44
+ args={{
45
+ for: 'formControlId',
46
+ text: 'First name',
47
+ width: 'u-1-of-2'
48
+ }}>
49
+ {Template.bind({})}
50
+ </Story>
51
+ </Canvas>
52
+
53
+ ## Required
54
+
55
+ If a form control is `required`, an asterisk will be added to the label.
56
+
57
+ <Canvas>
58
+ <Story
59
+ name="Required"
60
+ args={{
61
+ for: 'formControlId',
62
+ required: true,
63
+ text: 'E-mail address',
64
+ width: 'u-1-of-2'
65
+ }}>
66
+ {Template.bind({})}
67
+ </Story>
68
+ </Canvas>
69
+
70
+ ## Hint
71
+
72
+ The `hint` property adds the provided string below the label.
73
+
74
+ <Canvas>
75
+ <Story
76
+ name="Hint"
77
+ args={{
78
+ for: 'formControlId',
79
+ hint: 'This is a hint that explains what to enter in the corresponding form control',
80
+ text: 'Contact person',
81
+ width: 'u-1-of-2'
82
+ }}>
83
+ {Template.bind({})}
84
+ </Story>
85
+ </Canvas>
86
+
87
+ ## Tooltip
88
+
89
+ The `tooltip` property adds a contextual help icon that reveals additional information on the form control when the user
90
+ hovers over it with their mouse.
91
+
92
+ <Canvas>
93
+ <Story
94
+ name="Tooltip"
95
+ args={{
96
+ for: 'formControlId',
97
+ tooltip: 'This is a text adding some more information on the form control',
98
+ text: 'Authorized users',
99
+ width: 'u-1-of-2'
100
+ }}>
101
+ {Template.bind({})}
102
+ </Story>
103
+ </Canvas>
@@ -0,0 +1,112 @@
1
+ <license>
2
+ (c) 2010-present DEMOS E-Partizipation GmbH.
3
+
4
+ This file is part of the package @demos-europe/demosplan-ui,
5
+ for more information see the license file.
6
+
7
+ All rights reserved
8
+ </license>
9
+
10
+ <template>
11
+ <label
12
+ :class="prefixClass(['o-form__label flex', bold ? 'weight--bold' : 'weight--normal', hints.length > 0 ? 'has-hint' : ''])"
13
+ :for="labelFor">
14
+ <span>
15
+ <span v-cleanhtml="text" /><span v-if="required">*</span>
16
+ <span
17
+ v-if="hints.length > 0"
18
+ :class="prefixClass('display--block font-size-small weight--normal')">
19
+ <span
20
+ :class="prefixClass(['display--inline-block'])"
21
+ :key="i"
22
+ v-for="(h, i) in hints"
23
+ v-cleanhtml="h" />
24
+ </span>
25
+ </span>
26
+ <i
27
+ v-if="tooltip !== ''"
28
+ :class="prefixClass('fa fa-question-circle u-mt-0_125 flex-item-end')"
29
+ :aria-label="ariaLabel"
30
+ v-tooltip="tooltip" />
31
+ </label>
32
+ </template>
33
+
34
+ <script>
35
+ import { CleanHtml } from 'demosplan-ui/directives'
36
+ import { de } from '../shared/translations'
37
+ import { prefixClassMixin } from '../../mixins'
38
+
39
+ export default {
40
+ name: 'DpLabel',
41
+
42
+ directives: {
43
+ cleanhtml: CleanHtml
44
+ },
45
+
46
+ mixins: [prefixClassMixin],
47
+
48
+ props: {
49
+ bold: {
50
+ type: Boolean,
51
+ required: false,
52
+ default: true
53
+ },
54
+
55
+ for: {
56
+ type: String,
57
+ required: true
58
+ },
59
+
60
+ // Can be string or array (the second element being the "maxlength" hint).
61
+ hint: {
62
+ type: [String, Array],
63
+ required: false,
64
+ default: () => []
65
+ },
66
+
67
+ text: {
68
+ type: String,
69
+ required: true
70
+ },
71
+
72
+ tooltip: {
73
+ type: String,
74
+ required: false,
75
+ default: ''
76
+ },
77
+
78
+ required: {
79
+ type: Boolean,
80
+ required: false,
81
+ default: false
82
+ }
83
+ },
84
+
85
+ computed: {
86
+ ariaLabel () {
87
+ return de.contextualHelp
88
+ },
89
+ /**
90
+ * List of Hints
91
+ *
92
+ * @return Array{String}
93
+ */
94
+ hints () {
95
+ if (this.hint) {
96
+ return this.wrapItemIntoArray(this.hint)
97
+ }
98
+ return []
99
+ },
100
+
101
+ labelFor () {
102
+ return this.for
103
+ }
104
+ },
105
+
106
+ methods: {
107
+ wrapItemIntoArray (item) {
108
+ return Array.isArray(item) ? item : [item]
109
+ }
110
+ }
111
+ }
112
+ </script>
@@ -0,0 +1,63 @@
1
+ import { Canvas, Meta, Story } from '@storybook/addon-docs'
2
+ import { action } from '@storybook/addon-actions'
3
+
4
+ import DpLoading from './DpLoading'
5
+
6
+ <Meta
7
+ title="Components/Loading"
8
+ component={DpLoading} />
9
+
10
+ # Loading
11
+
12
+ The `DpLoading` component renders a spinning animation alongside some explanatory text.
13
+
14
+ It indicates background activity and is especially used when components load data on first page load.
15
+
16
+ export const Template = (args, { argTypes }) => ({
17
+ props: Object.keys(argTypes),
18
+ components: { DpLoading },
19
+ template: `<dp-loading v-bind="$props" @click="action" />`,
20
+ methods: {
21
+ action: action('click')
22
+ }
23
+ });
24
+
25
+ ## Default usage
26
+
27
+ <Canvas>
28
+ <Story name="Default">
29
+ {Template.bind({})}
30
+ </Story>
31
+ </Canvas>
32
+
33
+ ## Without label
34
+
35
+ In contexts with limited space, use the `hide-label` prop.
36
+
37
+ <Canvas>
38
+ <Story
39
+ name="hideLabel"
40
+ args={{
41
+ hideLabel: true
42
+ }}>
43
+ {Template.bind({})}
44
+ </Story>
45
+ </Canvas>
46
+
47
+ ## As overlay
48
+
49
+ To block interactions with content that is being refreshed, the `overlay` prop may be used.
50
+
51
+ <Canvas withSource="open">
52
+ <h1>
53
+ Some content that is still present but covered by the loading component,
54
+ which makes it impossible to interact with said content.
55
+ </h1>
56
+ <Story
57
+ name="Overlay"
58
+ args={{
59
+ overlay: true
60
+ }}>
61
+ {Template.bind({})}
62
+ </Story>
63
+ </Canvas>