@nexxtmove/ui 1.36.0 → 1.38.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.
@@ -1,4 +1,4 @@
1
1
  export declare const customIcons: {
2
- funda: string;
2
+ funda: import('vue').DefineComponent<object, object, unknown>;
3
3
  };
4
4
  export type CustomIconName = keyof typeof customIcons;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The steps the slider can land on, as the class they are stored as and the
3
+ * pixels that class is. Not a scale Tailwind has names for -- `tracking-wide`
4
+ * is an em and moves with the font size, and the editor shows every size in
5
+ * px -- so every step is an arbitrary-value class.
6
+ *
7
+ * The middle step is no class at all: zero is what the text already does, and
8
+ * storing nothing for it keeps the "no class means default" every other
9
+ * setting has. The negative side is there on purpose: tightening a large
10
+ * heading is a real need.
11
+ *
12
+ * The consumer stores these classes and lists them in an `@source inline` rule,
13
+ * so adding or renaming a token is a breaking change even though the component
14
+ * API stays the same.
15
+ */
16
+ export declare const EDITOR_LETTER_SPACING_STEPS: readonly [{
17
+ readonly token: "tracking-[-1px]";
18
+ readonly px: -1;
19
+ }, {
20
+ readonly token: "tracking-[-0.5px]";
21
+ readonly px: -0.5;
22
+ }, {
23
+ readonly token: "tracking-[-0.25px]";
24
+ readonly px: -0.25;
25
+ }, {
26
+ readonly token: null;
27
+ readonly px: 0;
28
+ }, {
29
+ readonly token: "tracking-[0.25px]";
30
+ readonly px: 0.25;
31
+ }, {
32
+ readonly token: "tracking-[0.5px]";
33
+ readonly px: 0.5;
34
+ }, {
35
+ readonly token: "tracking-[1px]";
36
+ readonly px: 1;
37
+ }, {
38
+ readonly token: "tracking-[1.5px]";
39
+ readonly px: 1.5;
40
+ }, {
41
+ readonly token: "tracking-[2px]";
42
+ readonly px: 2;
43
+ }];
44
+ /**
45
+ * The letter spacing as the editor needs it: the Tailwind class itself, so the
46
+ * consumer can put the model value straight on the element it styles. The
47
+ * default step is `null` on the model, not a member of this type.
48
+ */
49
+ export type EditorLetterSpacingValue = NonNullable<(typeof EDITOR_LETTER_SPACING_STEPS)[number]['token']>;
50
+ /** Overridable copy of the value readout. Every key is optional. */
51
+ export interface EditorLetterSpacingMessages {
52
+ /** Unit shown behind the value. Defaults to `'px'`. */
53
+ unit?: string;
54
+ /** Decimal separator of the readout. Defaults to the Dutch `','`. */
55
+ decimalSeparator?: string;
56
+ }
57
+ export interface NexxtEditorLetterSpacingProps {
58
+ /**
59
+ * Header text of the settings block. Defaults to the Dutch
60
+ * `'Letterafstand'`; the library has no i18n layer, so a consumer in another
61
+ * language passes its own copy in.
62
+ */
63
+ label?: string;
64
+ /**
65
+ * Copy of the value readout. Merged per key, so overriding one key keeps the
66
+ * defaults of the others. Copy is never translated inside the component.
67
+ */
68
+ messages?: EditorLetterSpacingMessages;
69
+ }
70
+ declare const _default: typeof __VLS_export;
71
+ export default _default;
72
+ declare const __VLS_export: import('vue').DefineComponent<NexxtEditorLetterSpacingProps & {
73
+ /**
74
+ * The selected letter spacing, as the Tailwind class to apply. `null` -- also
75
+ * what an unset model is -- is the default step: no class at all, zero.
76
+ */
77
+ modelValue?: EditorLetterSpacingValue | null;
78
+ }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
79
+ "update:modelValue": (value: EditorLetterSpacingValue | null) => any;
80
+ pointerup: (event: PointerEvent) => any;
81
+ }, string, import('vue').PublicProps, Readonly<NexxtEditorLetterSpacingProps & {
82
+ /**
83
+ * The selected letter spacing, as the Tailwind class to apply. `null` -- also
84
+ * what an unset model is -- is the default step: no class at all, zero.
85
+ */
86
+ modelValue?: EditorLetterSpacingValue | null;
87
+ }> & Readonly<{
88
+ "onUpdate:modelValue"?: ((value: EditorLetterSpacingValue | null) => any) | undefined;
89
+ onPointerup?: ((event: PointerEvent) => any) | undefined;
90
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The steps the slider can land on, as the class they are stored as and the
3
+ * pixels that class is. The `leading-*` classes are Tailwind's spacing scale
4
+ * (calc of `--spacing`, 4px a step), so `leading-6` really is 24px -- and a
5
+ * line height set here does not scale with the font size; that is the deal the
6
+ * fixed steps make, and nothing here tries to compensate for it.
7
+ *
8
+ * The first step is no class at all: the element keeps its own line height.
9
+ * It has no px of its own, so the readout names it instead of measuring it.
10
+ *
11
+ * The consumer stores these classes and lists them in an `@source inline` rule,
12
+ * so adding or renaming a token is a breaking change even though the component
13
+ * API stays the same.
14
+ */
15
+ export declare const EDITOR_LINE_HEIGHT_STEPS: readonly [{
16
+ readonly token: null;
17
+ readonly px: null;
18
+ }, {
19
+ readonly token: "leading-3";
20
+ readonly px: 12;
21
+ }, {
22
+ readonly token: "leading-4";
23
+ readonly px: 16;
24
+ }, {
25
+ readonly token: "leading-5";
26
+ readonly px: 20;
27
+ }, {
28
+ readonly token: "leading-6";
29
+ readonly px: 24;
30
+ }, {
31
+ readonly token: "leading-7";
32
+ readonly px: 28;
33
+ }, {
34
+ readonly token: "leading-8";
35
+ readonly px: 32;
36
+ }, {
37
+ readonly token: "leading-9";
38
+ readonly px: 36;
39
+ }, {
40
+ readonly token: "leading-10";
41
+ readonly px: 40;
42
+ }, {
43
+ readonly token: "leading-11";
44
+ readonly px: 44;
45
+ }, {
46
+ readonly token: "leading-12";
47
+ readonly px: 48;
48
+ }, {
49
+ readonly token: "leading-14";
50
+ readonly px: 56;
51
+ }, {
52
+ readonly token: "leading-16";
53
+ readonly px: 64;
54
+ }];
55
+ /**
56
+ * The line height as the editor needs it: the Tailwind class itself, so the
57
+ * consumer can put the model value straight on the element it styles. The
58
+ * default step is `null` on the model, not a member of this type.
59
+ */
60
+ export type EditorLineHeightValue = NonNullable<(typeof EDITOR_LINE_HEIGHT_STEPS)[number]['token']>;
61
+ /** Overridable copy of the value readout. Every key is optional. */
62
+ export interface EditorLineHeightMessages {
63
+ /** Unit shown behind the value. Defaults to `'px'`. */
64
+ unit?: string;
65
+ /**
66
+ * Readout of the first step, no class, which has no px size. Defaults to
67
+ * the Dutch `'Standaard'`.
68
+ */
69
+ default?: string;
70
+ }
71
+ export interface NexxtEditorLineHeightProps {
72
+ /**
73
+ * Header text of the settings block. Defaults to the Dutch
74
+ * `'Regelafstand'`; the library has no i18n layer, so a consumer in another
75
+ * language passes its own copy in.
76
+ */
77
+ label?: string;
78
+ /**
79
+ * Copy of the value readout. Merged per key, so overriding one key keeps the
80
+ * defaults of the others. Copy is never translated inside the component.
81
+ */
82
+ messages?: EditorLineHeightMessages;
83
+ }
84
+ declare const _default: typeof __VLS_export;
85
+ export default _default;
86
+ declare const __VLS_export: import('vue').DefineComponent<NexxtEditorLineHeightProps & {
87
+ /**
88
+ * The selected line height, as the Tailwind class to apply. `null` -- also
89
+ * what an unset model is -- is the default step: no class at all.
90
+ */
91
+ modelValue?: EditorLineHeightValue | null;
92
+ }, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
93
+ "update:modelValue": (value: EditorLineHeightValue | null) => any;
94
+ pointerup: (event: PointerEvent) => any;
95
+ }, string, import('vue').PublicProps, Readonly<NexxtEditorLineHeightProps & {
96
+ /**
97
+ * The selected line height, as the Tailwind class to apply. `null` -- also
98
+ * what an unset model is -- is the default step: no class at all.
99
+ */
100
+ modelValue?: EditorLineHeightValue | null;
101
+ }> & Readonly<{
102
+ "onUpdate:modelValue"?: ((value: EditorLineHeightValue | null) => any) | undefined;
103
+ onPointerup?: ((event: PointerEvent) => any) | undefined;
104
+ }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
@@ -6,12 +6,35 @@ export interface NexxtTreeNode {
6
6
  icon?: NexxtIconName;
7
7
  /** A node with children gets a chevron and can be folded. */
8
8
  children?: NexxtTreeNode[];
9
+ /** Whether this node accepts drops when it currently has no children. */
10
+ canHaveChildren?: boolean;
11
+ /** Whether this node can be dragged when the tree's `draggable` prop is enabled. */
12
+ draggable?: boolean;
13
+ }
14
+ export interface NexxtTreeMove {
15
+ /** The node being moved. */
16
+ id: string;
17
+ /** The node that will contain the moved node, or `null` for the tree root. */
18
+ parentId: string | null;
19
+ /** The zero-based position in the target parent's children. */
20
+ index: number;
9
21
  }
10
22
  export interface NexxtTreeProps {
11
23
  /** The top-level nodes; nest `children` for deeper levels. */
12
24
  nodes: NexxtTreeNode[];
13
25
  /** Accessible name for the tree, e.g. the heading above it. */
14
26
  label: string;
27
+ /** Enables native drag-and-drop for rows and emits the intended new position. */
28
+ draggable?: boolean;
29
+ /**
30
+ * Decides per spot whether the dragged node may land there, on top of the built-in rules (no
31
+ * drop into its own subtree, only into nodes that can have children). Gets the same shape as
32
+ * the `move` payload. A refused spot shows no ghost row and drops nothing, like letting go
33
+ * outside the tree. It runs on every `dragover` — which the browser keeps firing while the
34
+ * pointer rests — and on every touch move, so keep it cheap and pure: the same spot must always
35
+ * get the same answer.
36
+ */
37
+ canDrop?: (target: NexxtTreeMove) => boolean;
15
38
  }
16
39
  export type NexxtTreeSlots = {
17
40
  /** Actions at the end of a row, e.g. a delete button. Hidden until the row is hovered or holds focus, and always shown on a coarse pointer. Clicks and keys inside it never reach the tree, so they neither select the row nor move focus. Put `tabindex` on every focusable element in it: it is `0` only on the row that is the tree's tab stop, which keeps one extra Tab stop for the whole tree. Keep the content at most 24px high, or the rows grow. */
@@ -31,9 +54,11 @@ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
31
54
  declare const __VLS_base: import('vue').DefineComponent<__VLS_PublicProps, {
32
55
  focusNode: (id: string) => Promise<boolean>;
33
56
  }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
57
+ move: (move: NexxtTreeMove) => any;
34
58
  "update:selected": (value: string | null) => any;
35
59
  "update:collapsed": (value: string[]) => any;
36
60
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
61
+ onMove?: ((move: NexxtTreeMove) => any) | undefined;
37
62
  "onUpdate:selected"?: ((value: string | null) => any) | undefined;
38
63
  "onUpdate:collapsed"?: ((value: string[]) => any) | undefined;
39
64
  }>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
@@ -0,0 +1,81 @@
1
+ import { NexxtTreeNode } from './Tree.vue';
2
+ /** A visible row of the tree, in document order. */
3
+ export interface TreeRow {
4
+ node: NexxtTreeNode;
5
+ depth: number;
6
+ parentId: string | null;
7
+ expandable: boolean;
8
+ canHaveChildren: boolean;
9
+ draggable: boolean;
10
+ expanded: boolean;
11
+ /** One-based position among its siblings. */
12
+ position: number;
13
+ setSize: number;
14
+ }
15
+ export type DropMarker = 'before' | 'inside' | 'after';
16
+ export interface TreeDrop {
17
+ /** The row the pointer was over when this spot was picked. */
18
+ rowId: string;
19
+ parentId: string | null;
20
+ index: number;
21
+ marker: DropMarker;
22
+ }
23
+ /**
24
+ * Where a row sits with the ghost row taken out, relative to the top of the tree. `bottom` takes
25
+ * in the gap below the row: a gap belongs to the row above it, so moving across it never reads
26
+ * as leaving the tree.
27
+ */
28
+ export interface RestSlot {
29
+ id: string;
30
+ top: number;
31
+ height: number;
32
+ bottom: number;
33
+ }
34
+ export interface DropLayout {
35
+ slots: RestSlot[];
36
+ /** The ghost row as it is laid out now, gap included; `null` while there is none. */
37
+ ghost: {
38
+ top: number;
39
+ bottom: number;
40
+ } | null;
41
+ }
42
+ /** `keep` leaves the current spot as it is: the pointer is on the ghost row, or there are no rows. */
43
+ export type DropHit = {
44
+ kind: 'keep';
45
+ } | {
46
+ kind: 'row';
47
+ id: string;
48
+ ratio: number;
49
+ };
50
+ export declare const containsNode: (node: NexxtTreeNode, id: string) => boolean;
51
+ export declare const findNode: (nodes: NexxtTreeNode[], id: string) => NexxtTreeNode | null;
52
+ /**
53
+ * Reads the pointer against where the rows land without the ghost row, not against what is under
54
+ * it now. The ghost pushes rows aside, so reading what is under the pointer would find a shifted
55
+ * row or the ghost itself, pick another spot, move the ghost and flicker. Measured this way the
56
+ * same pointer always gives the same answer, however the ghost moves.
57
+ *
58
+ * @param layout - The rows at rest and the ghost row as it is laid out now.
59
+ * @param y - The pointer, relative to the top of the tree.
60
+ */
61
+ export declare const hitTest: ({ slots, ghost }: DropLayout, y: number) => DropHit;
62
+ /**
63
+ * The spot a pointer at `ratio` of `row` stands for. A group splits into before (top 30%),
64
+ * inside and after (bottom 30%), a leaf into before and after at the middle. Inside always lands
65
+ * as the first child, right under the group row, so the ghost shows up next to the pointer. The
66
+ * dragged node and everything inside it are no target at all.
67
+ */
68
+ export declare const resolveDrop: (row: TreeRow, ratio: number, moving: NexxtTreeNode) => TreeDrop | null;
69
+ /** A spot where the dragged row already is: dropping there changes nothing, so it is no target. */
70
+ export declare const isNoOp: (drop: TreeDrop, source: TreeRow) => boolean;
71
+ /** Two spots are the same when they land the node in the same place, whichever row picked them. */
72
+ export declare const samePlace: (a: TreeDrop | null, b: TreeDrop | null) => boolean;
73
+ /**
74
+ * Where the ghost row goes among the visible rows, and how deep. Right before the row of the
75
+ * sibling now at `index`, or after the last visible row inside the parent when `index` is past
76
+ * its last child. `null` for a spot inside a collapsed group: that group row marks itself.
77
+ */
78
+ export declare const ghostSlot: (rows: TreeRow[], nodes: NexxtTreeNode[], drop: TreeDrop | null) => {
79
+ at: number;
80
+ depth: number;
81
+ } | null;
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type { NexxtTabItem } from './components/molecules/Tabs/Tabs.vue';
8
8
  export type { NexxtPageCardProps, NexxtPageCardSlots, } from './components/molecules/PageCard/PageCard.vue';
9
9
  export type { NexxtPageMockupType } from './components/molecules/PageMockup/PageMockup.vue';
10
10
  export type { NexxtPickerGroupData, NexxtPickerItemData, } from './components/molecules/PickerList/PickerList.vue';
11
- export type { NexxtTreeNode, NexxtTreeProps, NexxtTreeSlots, } from './components/molecules/Tree/Tree.vue';
11
+ export type { NexxtTreeMove, NexxtTreeNode, NexxtTreeProps, NexxtTreeSlots, } from './components/molecules/Tree/Tree.vue';
12
12
  export type { NexxtPlaceholderGroup, NexxtPlaceholderInputMessages, NexxtPlaceholderInputProps, } from './components/molecules/PlaceholderInput/PlaceholderInput.vue';
13
13
  export type { EditorAlignItemsMessages, EditorAlignItemsValue, } from './components/editor/molecules/EditorAlignItems/EditorAlignItems.vue';
14
14
  export type { EditorBackgroundSizeMessages, EditorBackgroundSizeValue, } from './components/editor/molecules/EditorBackgroundSize/EditorBackgroundSize.vue';
@@ -23,6 +23,10 @@ export type { EditorTextAlignMessages, EditorTextAlignValue, } from './component
23
23
  export type { EditorJustifyContentMessages, EditorJustifyContentValue, } from './components/editor/molecules/EditorJustifyContent/EditorJustifyContent.vue';
24
24
  export { EDITOR_MAX_WIDTH_STEPS } from './components/editor/molecules/EditorMaxWidth/EditorMaxWidth.vue';
25
25
  export type { EditorMaxWidthMessages, EditorMaxWidthValue, } from './components/editor/molecules/EditorMaxWidth/EditorMaxWidth.vue';
26
+ export { EDITOR_LINE_HEIGHT_STEPS } from './components/editor/molecules/EditorLineHeight/EditorLineHeight.vue';
27
+ export type { EditorLineHeightMessages, EditorLineHeightValue, } from './components/editor/molecules/EditorLineHeight/EditorLineHeight.vue';
28
+ export { EDITOR_LETTER_SPACING_STEPS } from './components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.vue';
29
+ export type { EditorLetterSpacingMessages, EditorLetterSpacingValue, } from './components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.vue';
26
30
  export type { EditorPaddingMessages } from './components/editor/molecules/EditorPadding/EditorPadding.vue';
27
31
  export type { NexxtTemplateCardContentFeature, NexxtTemplateCardProps, NexxtTemplateCardSlots, } from './components/molecules/TemplateCard/TemplateCard.vue';
28
32
  export { default as NexxtAnimatedNumber } from './components/atoms/AnimatedNumber/AnimatedNumber.vue';
@@ -50,6 +54,8 @@ export { default as NexxtEditorFlexDirection } from './components/editor/molecul
50
54
  export { default as NexxtEditorGap } from './components/editor/molecules/EditorGap/EditorGap.vue';
51
55
  export { default as NexxtEditorHeadingType } from './components/editor/molecules/EditorHeadingType/EditorHeadingType.vue';
52
56
  export { default as NexxtEditorJustifyContent } from './components/editor/molecules/EditorJustifyContent/EditorJustifyContent.vue';
57
+ export { default as NexxtEditorLetterSpacing } from './components/editor/molecules/EditorLetterSpacing/EditorLetterSpacing.vue';
58
+ export { default as NexxtEditorLineHeight } from './components/editor/molecules/EditorLineHeight/EditorLineHeight.vue';
53
59
  export { default as NexxtEditorMaxWidth } from './components/editor/molecules/EditorMaxWidth/EditorMaxWidth.vue';
54
60
  export { default as NexxtEditorPadding } from './components/editor/molecules/EditorPadding/EditorPadding.vue';
55
61
  export { default as NexxtEditorRadius } from './components/editor/molecules/EditorRadius/EditorRadius.vue';