@nexxtmove/ui 1.30.0 → 1.31.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/dist/nuxt.js CHANGED
@@ -33,6 +33,7 @@ var s = {
33
33
  NexxtPageMockup: "components/molecules/PageMockup/PageMockup.vue",
34
34
  NexxtPageTypeTile: "components/molecules/PageTypeTile/PageTypeTile.vue",
35
35
  NexxtPagination: "components/molecules/Pagination/Pagination.vue",
36
+ NexxtPlaceholderInput: "components/molecules/PlaceholderInput/PlaceholderInput.vue",
36
37
  NexxtPropertyCard: "components/molecules/PropertyCard/PropertyCard.vue",
37
38
  NexxtSelect: "components/molecules/Select/Select.vue",
38
39
  NexxtSidebarMenuItem: "components/molecules/SidebarMenuItem/SidebarMenuItem.vue",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nexxtmove/ui",
3
3
  "type": "module",
4
- "version": "1.30.0",
4
+ "version": "1.31.0",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -0,0 +1,121 @@
1
+ <script lang="ts">
2
+ export interface NexxtPlaceholderGroup {
3
+ /** Heading of the group, shown when there is more than one group. */
4
+ label: string
5
+ /** Placeholder keys, inserted as `{{key}}`. */
6
+ items: string[]
7
+ }
8
+
9
+ export interface NexxtPlaceholderInputMessages {
10
+ /** Accessible name and tooltip of the pen button. */
11
+ insert?: string
12
+ }
13
+
14
+ export interface NexxtPlaceholderInputProps {
15
+ placeholders: NexxtPlaceholderGroup[]
16
+ label?: string
17
+ placeholder?: string
18
+ disabled?: boolean
19
+ error?: boolean
20
+ errorMessage?: string
21
+ required?: boolean
22
+ messages?: NexxtPlaceholderInputMessages
23
+ }
24
+ </script>
25
+
26
+ <script lang="ts" setup>
27
+ import { computed, nextTick, useTemplateRef } from 'vue'
28
+ import NexxtFloatingPanel from '../../atoms/FloatingPanel/FloatingPanel.vue'
29
+ import NexxtIcon from '../../atoms/Icon/Icon.vue'
30
+ import NexxtTooltip from '../../atoms/Tooltip/Tooltip.vue'
31
+ import NexxtInputField from '../InputField/InputField.vue'
32
+
33
+ defineOptions({ name: 'NexxtPlaceholderInput' })
34
+
35
+ const { placeholders, disabled = false, messages } = defineProps<NexxtPlaceholderInputProps>()
36
+
37
+ /** The text, with placeholders written as `{{key}}`. */
38
+ const model = defineModel<string>({ default: '' })
39
+
40
+ const insertLabel = computed(() => messages?.insert ?? 'Placeholder invoegen')
41
+
42
+ // A single group has nothing to be told apart from, so its heading is left out
43
+ const grouped = computed(() => placeholders.length > 1)
44
+
45
+ const field = useTemplateRef<InstanceType<typeof NexxtInputField>>('field')
46
+
47
+ // Inserts at the caret, or appends when the field was never focused
48
+ const insert = (key: string, close: () => void) => {
49
+ const el = field.value?.inputEl ?? null
50
+ const token = `{{${key}}}`
51
+ const start = el?.selectionStart ?? model.value.length
52
+ const end = el?.selectionEnd ?? start
53
+
54
+ model.value = model.value.slice(0, start) + token + model.value.slice(end)
55
+ close()
56
+
57
+ nextTick(() => {
58
+ el?.focus()
59
+ el?.setSelectionRange(start + token.length, start + token.length)
60
+ })
61
+ }
62
+ </script>
63
+
64
+ <template>
65
+ <NexxtInputField
66
+ ref="field"
67
+ v-model="model"
68
+ :label="label"
69
+ :placeholder="placeholder"
70
+ :error="error"
71
+ :error-message="errorMessage"
72
+ :required="required"
73
+ :disabled="disabled"
74
+ >
75
+ <template #right>
76
+ <NexxtFloatingPanel surface placement="bottom-end">
77
+ <template #trigger="{ open }">
78
+ <NexxtTooltip>
79
+ <button
80
+ type="button"
81
+ class="flex h-10 w-9 shrink-0 cursor-pointer items-center justify-center text-gray-400 transition-colors hover:text-cornflower-blue-600 focus:outline-none focus-visible:text-cornflower-blue-600 disabled:cursor-default disabled:opacity-50"
82
+ :disabled="disabled"
83
+ :aria-label="insertLabel"
84
+ @click="open"
85
+ >
86
+ <NexxtIcon name="pen" aria-hidden="true" />
87
+ </button>
88
+ <template #tooltip>{{ insertLabel }}</template>
89
+ </NexxtTooltip>
90
+ </template>
91
+
92
+ <template #content="{ close }">
93
+ <div
94
+ class="flex max-h-96 w-80 flex-col gap-4 overflow-y-auto p-4"
95
+ role="listbox"
96
+ :aria-label="insertLabel"
97
+ >
98
+ <div v-for="group in placeholders" :key="group.label" class="flex flex-col gap-1">
99
+ <span
100
+ v-if="grouped"
101
+ class="pb-2 extra-small-semibold text-cornflower-blue-500 uppercase"
102
+ >
103
+ {{ group.label }}
104
+ </span>
105
+ <button
106
+ v-for="key in group.items"
107
+ :key="key"
108
+ type="button"
109
+ role="option"
110
+ class="cursor-pointer rounded-lg px-2 py-1 text-left small-normal text-gray-950 transition-colors hover:bg-cornflower-blue-50"
111
+ @click="insert(key, close)"
112
+ >
113
+ {{ key }}
114
+ </button>
115
+ </div>
116
+ </div>
117
+ </template>
118
+ </NexxtFloatingPanel>
119
+ </template>
120
+ </NexxtInputField>
121
+ </template>
@@ -30,6 +30,7 @@
30
30
  "NexxtPageMockup": "components/molecules/PageMockup/PageMockup.vue",
31
31
  "NexxtPageTypeTile": "components/molecules/PageTypeTile/PageTypeTile.vue",
32
32
  "NexxtPagination": "components/molecules/Pagination/Pagination.vue",
33
+ "NexxtPlaceholderInput": "components/molecules/PlaceholderInput/PlaceholderInput.vue",
33
34
  "NexxtPropertyCard": "components/molecules/PropertyCard/PropertyCard.vue",
34
35
  "NexxtSelect": "components/molecules/Select/Select.vue",
35
36
  "NexxtSidebarMenuItem": "components/molecules/SidebarMenuItem/SidebarMenuItem.vue",
package/src/index.ts CHANGED
@@ -19,6 +19,11 @@ export type {
19
19
  } from './components/molecules/PageCard/PageCard.vue'
20
20
  export type { NexxtPageMockupType } from './components/molecules/PageMockup/PageMockup.vue'
21
21
  export type { NexxtTreeNode, NexxtTreeProps } from './components/molecules/Tree/Tree.vue'
22
+ export type {
23
+ NexxtPlaceholderGroup,
24
+ NexxtPlaceholderInputMessages,
25
+ NexxtPlaceholderInputProps,
26
+ } from './components/molecules/PlaceholderInput/PlaceholderInput.vue'
22
27
  export type {
23
28
  EditorAlignItemsMessages,
24
29
  EditorAlignItemsValue,
@@ -117,6 +122,7 @@ export { default as NexxtPageContainer } from './components/molecules/PageContai
117
122
  export { default as NexxtPageMockup } from './components/molecules/PageMockup/PageMockup.vue'
118
123
  export { default as NexxtPageTypeTile } from './components/molecules/PageTypeTile/PageTypeTile.vue'
119
124
  export { default as NexxtPagination } from './components/molecules/Pagination/Pagination.vue'
125
+ export { default as NexxtPlaceholderInput } from './components/molecules/PlaceholderInput/PlaceholderInput.vue'
120
126
  export { default as NexxtPresenceIndicator } from './components/atoms/PresenceIndicator/PresenceIndicator.vue'
121
127
  export { default as NexxtProgressBar } from './components/organisms/ProgressBar/ProgressBar.vue'
122
128
  export { default as NexxtPropertyCard } from './components/molecules/PropertyCard/PropertyCard.vue'