@nexxtmove/ui 1.43.0 → 1.45.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/components/editor/atoms/EditorDimensionField/EditorDimensionField.vue.d.ts +12 -2
- package/dist/components/editor/molecules/EditorMaxWidth/EditorMaxWidth.vue.d.ts +6 -0
- package/dist/components/editor/molecules/EditorSize/EditorSize.vue.d.ts +11 -7
- package/dist/components/editor/molecules/EditorSizeLimit/EditorSizeLimit.vue.d.ts +5 -0
- package/dist/index.js +184 -179
- package/dist/ui.css +1 -1
- package/package.json +1 -1
- package/src/components/editor/atoms/EditorDimensionField/EditorDimensionField.vue +19 -3
- package/src/components/editor/molecules/EditorMaxWidth/EditorMaxWidth.vue +6 -0
- package/src/components/editor/molecules/EditorSize/EditorSize.vue +7 -4
- package/src/components/editor/molecules/EditorSizeLimit/EditorSizeLimit.vue +5 -0
- package/src/components/molecules/Tree/Tree.vue +30 -10
package/dist/ui.css
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
input[data-snap][data-v-5d3904ac]{animation:snap-in-5d3904ac .18s var(--ease-out-strong)}input[data-snap=up][data-v-5d3904ac]{--snap-from:2px}input[data-snap=down][data-v-5d3904ac]{--snap-from:-2px}@keyframes snap-in-5d3904ac{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-5d3904ac]{animation:1ms snap-hold-5d3904ac}@keyframes snap-hold-5d3904ac{0%,to{opacity:1}}}input[data-snap][data-v-
|
|
1
|
+
input[data-snap][data-v-5d3904ac]{animation:snap-in-5d3904ac .18s var(--ease-out-strong)}input[data-snap=up][data-v-5d3904ac]{--snap-from:2px}input[data-snap=down][data-v-5d3904ac]{--snap-from:-2px}@keyframes snap-in-5d3904ac{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-5d3904ac]{animation:1ms snap-hold-5d3904ac}@keyframes snap-hold-5d3904ac{0%,to{opacity:1}}}input[data-snap][data-v-15feed8b]{animation:snap-in-15feed8b .18s var(--ease-out-strong)}input[data-snap=up][data-v-15feed8b]{--snap-from:2px}input[data-snap=down][data-v-15feed8b]{--snap-from:-2px}@keyframes snap-in-15feed8b{0%{opacity:0;transform:translateY(var(--snap-from))}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion:reduce){input[data-snap][data-v-15feed8b]{animation:1ms snap-hold-15feed8b}@keyframes snap-hold-15feed8b{0%,to{opacity:1}}}rect[data-v-0a5d9b21]{animation-duration:4s;animation-timing-function:cubic-bezier(.77,0,.175,1);animation-iteration-count:infinite}rect[data-v-0a5d9b21]:first-child{animation-name:load-1-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(2){animation-name:load-2-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(3){animation-name:load-3-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(4){animation-name:load-4-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(5){animation-name:load-5-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(6){animation-name:load-6-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(7){animation-name:load-7-0a5d9b21}rect[data-v-0a5d9b21]:nth-child(8){animation-name:load-8-0a5d9b21}@media (prefers-reduced-motion:reduce){rect[data-v-0a5d9b21]{animation:none}svg[data-v-0a5d9b21]{animation:2.5s ease-in-out infinite pulse-0a5d9b21}}@keyframes pulse-0a5d9b21{0%,to{opacity:1}50%{opacity:.65}}@keyframes load-1-0a5d9b21{0%,80%{transform:translate(0)}5%,20%,60%,75%{transform:translate(-25px,25px)}30%,50%{transform:translate(-75px,75px)}}@keyframes load-2-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(50px)}30%,50%{transform:translateY(50px)}}@keyframes load-3-0a5d9b21{10%,70%{transform:translate(0%)}15%,65%{transform:translateY(-50px)}20%,60%{fill:var(--color-sapphire-500);transform:translateY(-50px)}30%,50%{fill:var(--color-purple-500);transform:translate(-50px)}}@keyframes load-4-0a5d9b21{20%,60%{transform:translate(0%)}30%,50%{transform:translate(50px,-50px)}}@keyframes load-5-0a5d9b21{0%,80%{transform:translate(0%)}5%,20%,60%,75%{transform:translateY(50px)}30%,50%{transform:translate(50px)}}@keyframes load-6-0a5d9b21{5%,75%{transform:translate(0%)}10%,20%,60%,70%{transform:translate(-50px)}30%,50%{transform:translateY(-50px)}}@keyframes load-7-0a5d9b21{10%,70%{transform:translate(0%)}15%,20%,60%,65%{transform:translate(50px)}30%,50%{transform:translate(100px,-50px)}}@keyframes load-8-0a5d9b21{15%,65%{transform:translate(0%)}20%,60%{transform:translateY(-50px)}30%,50%{transform:translate(50px,-100px)}}.timer-circle[data-v-7e3c5bda]{stroke-dashoffset:0;animation:linear forwards toast-timer-7e3c5bda}@keyframes toast-timer-7e3c5bda{to{stroke-dashoffset:var(--fa0d20de)}}
|
|
2
2
|
/*$vite$:1*/
|
package/package.json
CHANGED
|
@@ -97,7 +97,12 @@ const emit = defineEmits<{
|
|
|
97
97
|
commit: []
|
|
98
98
|
}>()
|
|
99
99
|
|
|
100
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* The dimension, or `null` for none. A `null` from outside -- another element
|
|
102
|
+
* selected, an undo -- resets the unit to the first of `units`; a field the
|
|
103
|
+
* user emptied keeps the unit picked in it. A value from outside brings its
|
|
104
|
+
* own unit.
|
|
105
|
+
*/
|
|
101
106
|
const model = defineModel<EditorDimensionValue | null>({ default: null })
|
|
102
107
|
|
|
103
108
|
const copy = computed(() => ({ ...DEFAULT_MESSAGES, ...messages }))
|
|
@@ -109,10 +114,20 @@ const copy = computed(() => ({ ...DEFAULT_MESSAGES, ...messages }))
|
|
|
109
114
|
*/
|
|
110
115
|
const unit = ref<EditorDimensionUnit>(model.value?.unit ?? units[0])
|
|
111
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Set while the field's own `null` is on its way through the model. Without
|
|
119
|
+
* it, the user emptying the field could not be told apart from a `null` from
|
|
120
|
+
* outside, and only the latter resets the unit.
|
|
121
|
+
*/
|
|
122
|
+
let emptiedHere = false
|
|
123
|
+
|
|
112
124
|
watch(
|
|
113
|
-
() => model.value
|
|
125
|
+
() => model.value,
|
|
114
126
|
(next) => {
|
|
115
|
-
if (next) unit.value = next
|
|
127
|
+
if (next) unit.value = next.unit
|
|
128
|
+
else if (!emptiedHere) unit.value = units[0]
|
|
129
|
+
|
|
130
|
+
emptiedHere = false
|
|
116
131
|
},
|
|
117
132
|
)
|
|
118
133
|
|
|
@@ -183,6 +198,7 @@ const write = (next: EditorDimensionValue | null) => {
|
|
|
183
198
|
)
|
|
184
199
|
return false
|
|
185
200
|
|
|
201
|
+
emptiedHere = next === null
|
|
186
202
|
model.value = next
|
|
187
203
|
return true
|
|
188
204
|
}
|
|
@@ -37,6 +37,12 @@ export interface EditorMaxWidthMessages {
|
|
|
37
37
|
unit?: string
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Sets a width on Tailwind's `max-w-*` steps, stored as the class.
|
|
42
|
+
*
|
|
43
|
+
* @deprecated Use `NexxtEditorSizeLimit`: a free maximum in px or % that can
|
|
44
|
+
* be none.
|
|
45
|
+
*/
|
|
40
46
|
export interface NexxtEditorMaxWidthProps {
|
|
41
47
|
/**
|
|
42
48
|
* Header text of the settings block. Defaults to the Dutch
|
|
@@ -21,7 +21,9 @@ export interface EditorSizeValue {
|
|
|
21
21
|
mode: EditorSizeMode
|
|
22
22
|
/**
|
|
23
23
|
* The fixed dimension. Kept when another mode is picked, so switching back
|
|
24
|
-
* to `'fixed'` restores it; it only applies while `mode` is `'fixed'`.
|
|
24
|
+
* to `'fixed'` restores it; it only applies while `mode` is `'fixed'`. The
|
|
25
|
+
* app always fills it with the measured size of the element, so picking
|
|
26
|
+
* `'fixed'` starts from that size.
|
|
25
27
|
*/
|
|
26
28
|
fixed?: EditorDimensionValue
|
|
27
29
|
}
|
|
@@ -119,9 +121,10 @@ const emit = defineEmits<{
|
|
|
119
121
|
}>()
|
|
120
122
|
|
|
121
123
|
/**
|
|
122
|
-
* The size.
|
|
123
|
-
*
|
|
124
|
-
*
|
|
124
|
+
* The size. Fill `fixed` with the measured size of the element, as the app
|
|
125
|
+
* always does. Without it, picking `'fixed'` writes `{ mode: 'fixed' }` and
|
|
126
|
+
* commits straight away, leaving a fixed mode without a size until a value is
|
|
127
|
+
* typed; with the measured size, that state does not come up.
|
|
125
128
|
*/
|
|
126
129
|
const model = defineModel<EditorSizeValue>({ required: true })
|
|
127
130
|
|
|
@@ -7,6 +7,11 @@ import type {
|
|
|
7
7
|
/** Overridable copy of the field. Every key is optional. */
|
|
8
8
|
export type EditorSizeLimitMessages = EditorDimensionFieldMessages
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* A free minimum or maximum of an element's size, in px or %, that can be
|
|
12
|
+
* none. Replaces the deprecated `NexxtEditorMaxWidth`, which offers only
|
|
13
|
+
* Tailwind's `max-w-*` steps.
|
|
14
|
+
*/
|
|
10
15
|
export interface NexxtEditorSizeLimitProps {
|
|
11
16
|
/** Visible label above the field, and its accessible name, as in `'Maximale breedte'`. */
|
|
12
17
|
label: string
|
|
@@ -80,7 +80,7 @@ const selected = defineModel<string | null>('selected', { default: null })
|
|
|
80
80
|
/** Ids of the nodes whose children are hidden. Tracking the collapsed ones makes "everything open" the default. */
|
|
81
81
|
const collapsed = defineModel<string[]>('collapsed', { default: () => [] })
|
|
82
82
|
|
|
83
|
-
const INDENT =
|
|
83
|
+
const INDENT = 8
|
|
84
84
|
|
|
85
85
|
const root = useTemplateRef<HTMLElement>('root')
|
|
86
86
|
const focusedId = ref<string | null>(null)
|
|
@@ -890,7 +890,7 @@ defineExpose({ focusNode })
|
|
|
890
890
|
<!-- The drop indicator: where the dragged node lands, at the depth it lands on. Out of
|
|
891
891
|
the accessibility tree and without `data-tree-id`, so it is no row to the keyboard,
|
|
892
892
|
the tab stop or the highlight. One element for the whole drag, that changes spots. -->
|
|
893
|
-
<div v-if="item.ghost" aria-hidden="true" class="mb-
|
|
893
|
+
<div v-if="item.ghost" aria-hidden="true" class="mb-1.5" data-tree-ghost>
|
|
894
894
|
<div
|
|
895
895
|
class="flex rounded-md bg-cornflower-blue-50 py-1 pr-2 pl-1 small-normal text-gray-700 outline-1 -outline-offset-1 outline-cornflower-blue-600 transition-[margin-left] duration-200 ease-in-out-strong outline-dashed motion-reduce:transition-none"
|
|
896
896
|
:style="{ marginLeft: `${item.depth * INDENT}px` }"
|
|
@@ -918,7 +918,7 @@ defineExpose({ focusNode })
|
|
|
918
918
|
:data-tree-id="item.row.node.id"
|
|
919
919
|
:data-tree-drop="collapsedTargetId === item.row.node.id ? 'inside' : undefined"
|
|
920
920
|
:draggable="item.row.draggable"
|
|
921
|
-
class="group mb-
|
|
921
|
+
class="group mb-1.5 flex items-center gap-1.5 overflow-x-clip rounded-md py-1 pr-2 small-normal transition-[color,background-color,outline-color,opacity] duration-150 select-none focus-visible:outline-2 focus-visible:outline-cornflower-blue-500 motion-reduce:transition-none"
|
|
922
922
|
:class="rowClasses(item.row)"
|
|
923
923
|
:style="{ paddingLeft: `${item.row.depth * INDENT + 4}px` }"
|
|
924
924
|
@click="onRowClick(item.row.node.id)"
|
|
@@ -955,19 +955,39 @@ defineExpose({ focusNode })
|
|
|
955
955
|
class="shrink-0 transition-colors duration-150 motion-reduce:transition-none"
|
|
956
956
|
:class="selected === item.row.node.id ? 'text-cornflower-blue-600' : 'text-gray-600'"
|
|
957
957
|
/>
|
|
958
|
-
<span :id="labelId(item.row.node.id)" class="truncate">{{
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
958
|
+
<span :id="labelId(item.row.node.id)" data-tree-label class="min-w-0 flex-1 truncate">{{
|
|
959
|
+
item.row.node.label
|
|
960
|
+
}}</span>
|
|
961
|
+
|
|
962
|
+
<!-- Only the selected row has actions: the track grows from 0 to their width and pushes
|
|
963
|
+
its label in, while their start, pinned to it, slides them in from the row's end.
|
|
964
|
+
The clip hides what has not slid in yet; the row's `overflow-x-clip` keeps them out
|
|
965
|
+
of the panel's scroll width meanwhile. Inert on every other row, so what cannot be
|
|
966
|
+
seen cannot be focused or read either; `undefined` rather than `false`, so no
|
|
967
|
+
`inert="false"` lands where the DOM has no such property. Pulled into the row's padding so a 24px
|
|
968
|
+
button leaves the row at 28px, and into the row's gap so a label without actions
|
|
969
|
+
runs to the row's end. Stopping here keeps the row's click and the tree's keys away
|
|
970
|
+
from the actions. -->
|
|
963
971
|
<div
|
|
964
972
|
v-if="slots['node-actions']"
|
|
965
973
|
data-tree-actions
|
|
966
|
-
class="-my-0.5 ml-
|
|
974
|
+
class="-my-0.5 -ml-1.5 grid shrink-0 transition-[grid-template-columns] duration-200 ease-in-out-strong [clip-path:inset(-0.5rem_-0.25rem)] motion-reduce:transition-none"
|
|
975
|
+
:class="
|
|
976
|
+
selected === item.row.node.id
|
|
977
|
+
? 'grid-cols-[minmax(0,1fr)]'
|
|
978
|
+
: 'grid-cols-[minmax(0,0fr)]'
|
|
979
|
+
"
|
|
980
|
+
:inert="selected !== item.row.node.id || undefined"
|
|
967
981
|
@click.stop
|
|
968
982
|
@keydown.stop
|
|
969
983
|
>
|
|
970
|
-
<
|
|
984
|
+
<div
|
|
985
|
+
data-tree-actions-content
|
|
986
|
+
class="flex w-max items-center pl-1.5 transition-opacity duration-150 ease-out motion-reduce:transition-none"
|
|
987
|
+
:class="selected === item.row.node.id ? 'opacity-100' : 'opacity-0'"
|
|
988
|
+
>
|
|
989
|
+
<NodeActions :node="item.row.node" :tabindex="tabindexOf(item.row.node.id)" />
|
|
990
|
+
</div>
|
|
971
991
|
</div>
|
|
972
992
|
</div>
|
|
973
993
|
</template>
|