@webx-ui/module-admin 0.9.0 → 0.11.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.
@@ -5,6 +5,9 @@
5
5
  *
6
6
  * Sections come first, then the groups the server declared — "System" for what keeps the
7
7
  * panel running — each as a branch that opens on its own when a section under it is current.
8
+ *
9
+ * A group names its own icon; the gear is what it falls back to, because that is the picture
10
+ * every group had before groups could carry one.
8
11
  */
9
12
  type __VLS_Props = {
10
13
  collapsed?: boolean;
@@ -19,7 +19,7 @@ type __VLS_Props = {
19
19
  size?: ActionSize;
20
20
  };
21
21
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
22
- size: ActionSize;
23
22
  label: string;
23
+ size: ActionSize;
24
24
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
25
25
  export default _default;
@@ -13,11 +13,17 @@ import { DateLike } from './dates';
13
13
  type __VLS_Props = {
14
14
  /** What the server sent. `null` is a date that never happened, not a missing one. */
15
15
  value: DateLike;
16
+ /**
17
+ * The column form: the time for today, a short month for the rest of the year, digits before
18
+ * that. What it leaves out is in the tip, which is the whole point of having one.
19
+ */
20
+ compact?: boolean;
16
21
  size?: TextSize;
17
22
  tone?: TextTone;
18
23
  };
19
24
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
20
25
  size: TextSize;
21
26
  tone: TextTone;
27
+ compact: boolean;
22
28
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
23
29
  export default _default;
@@ -0,0 +1,18 @@
1
+ import { AppliedFilter } from './types';
2
+ /**
3
+ * What the filters are set to, in the head of every list of the panel.
4
+ *
5
+ * The table gives the strip its place and its spacing (`#applied`); this gives every section the
6
+ * same chip. Written once because the alternative is what the panel already learned about
7
+ * headings: five sections each answering "what does an applied filter look like" gives five
8
+ * answers, and a reader who learns one list should already know the next.
9
+ *
10
+ * A chip takes one filter off. Taking all of them off lives with the fields it resets, inside
11
+ * the panel the funnel opens — beside the chips it reads as one more chip, and it is the only
12
+ * control in that row that does not remove exactly one thing.
13
+ */
14
+ type __VLS_Props = {
15
+ filters: AppliedFilter[];
16
+ };
17
+ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
18
+ export default _default;
@@ -23,9 +23,9 @@ type __VLS_Props = {
23
23
  width?: number | string;
24
24
  };
25
25
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
26
- title: string;
27
- size: ActionSize;
28
26
  label: string;
27
+ size: ActionSize;
28
+ title: string;
29
29
  width: number | string;
30
30
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
31
31
  export default _default;
@@ -1,4 +1,6 @@
1
1
  import { CardPadding, TabItem, TabValue } from '@webx-ui/core';
2
+ import { RouteLocationRaw } from 'vue-router';
3
+ import { ScreenAction } from './types';
2
4
  /**
3
5
  * The frame every list of the panel is drawn in.
4
6
  *
@@ -13,12 +15,27 @@ import { CardPadding, TabItem, TabValue } from '@webx-ui/core';
13
15
  * and the line above says which section (§19). The search stays inside the table, where it is
14
16
  * a property of the rows rather than of the screen (§10).
15
17
  *
18
+ * That first line is `WxScreenHead`, the same one an editor carries: a list and the record it
19
+ * opens are two screens of one panel, and a head that differs between them is a head the
20
+ * reader has to read twice.
21
+ *
16
22
  * What it deliberately does not do is fetch, filter or page. It is a frame; the section still
17
23
  * owns its data, and the tabs only say which view is open.
18
24
  */
19
25
  type __VLS_Props = {
20
26
  /** The section's name. The one heading on the screen. */
21
27
  title?: string;
28
+ /** The line under it, when the name alone does not say which list this is. */
29
+ subtitle?: string;
30
+ /** Where the list goes back to, for one that stands under another screen. */
31
+ back?: RouteLocationRaw;
32
+ /** What the arrow's tooltip says. The panel's own word for it when not given. */
33
+ backLabel?: string;
34
+ /**
35
+ * What the section offers: `New article`, `Check an address`. The one it exists for is
36
+ * `primary`, and it is the one that survives a narrow screen.
37
+ */
38
+ actions?: ScreenAction[];
22
39
  /**
23
40
  * The views of the same list — "All / Drafts / Published", "Rules / Redirects". Not a
24
41
  * navigation between screens: everything under them is the same table.
@@ -42,16 +59,18 @@ declare function __VLS_template(): {
42
59
  /** The rows: a table, a grid of cards, a manager. */
43
60
  default?: () => unknown;
44
61
  /**
45
- * The screen's buttons, beside the heading. One of them — the reason the section exists —
46
- * is a filled primary button with a word on it; everything else is outlined or an icon.
62
+ * Controls beside the heading that are not one-word actions and so cannot be declared —
63
+ * a switch, a picker. Everything a button can say belongs in `actions`, which is what folds
64
+ * into the `···` on a phone; what is written here stays drawn at every width.
47
65
  */
48
66
  actions?: () => unknown;
49
67
  }> & {
50
68
  /** The rows: a table, a grid of cards, a manager. */
51
69
  default?: () => unknown;
52
70
  /**
53
- * The screen's buttons, beside the heading. One of them — the reason the section exists —
54
- * is a filled primary button with a word on it; everything else is outlined or an icon.
71
+ * Controls beside the heading that are not one-word actions and so cannot be declared —
72
+ * a switch, a picker. Everything a button can say belongs in `actions`, which is what folds
73
+ * into the `···` on a phone; what is written here stays drawn at every width.
55
74
  */
56
75
  actions?: () => unknown;
57
76
  };
@@ -64,12 +83,16 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_PublicProps,
64
83
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
65
84
  "onUpdate:view"?: ((value: TabValue | undefined) => any) | undefined;
66
85
  }>, {
86
+ fill: boolean;
67
87
  title: string;
88
+ actions: ScreenAction[];
89
+ subtitle: string;
90
+ back: RouteLocationRaw;
91
+ backLabel: string;
92
+ collapseBelow: number;
68
93
  views: TabItem[];
69
94
  card: boolean;
70
95
  padding: CardPadding;
71
- fill: boolean;
72
- collapseBelow: number;
73
96
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
74
97
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
75
98
  export default _default;
@@ -25,11 +25,11 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
25
25
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
26
26
  onRename?: ((name: string) => any) | undefined;
27
27
  }>, {
28
- size: ActionSize;
29
- label: string;
30
- placeholder: string;
31
28
  name: string;
29
+ label: string;
30
+ size: ActionSize;
32
31
  disabled: boolean;
32
+ placeholder: string;
33
33
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
34
34
  field: ({
35
35
  $: import('vue').ComponentInternalInstance;
@@ -68,7 +68,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
68
68
  $root: import('vue').ComponentPublicInstance | null;
69
69
  $parent: import('vue').ComponentPublicInstance | null;
70
70
  $host: Element | null;
71
- $emit: ((event: "input", value: string) => void) & ((event: "focus", event: FocusEvent) => void) & ((event: "clear") => void) & ((event: "blur", event: FocusEvent) => void) & ((event: "change", value: string) => void) & ((event: "update:modelValue", value: import('@webx-ui/core').InputModelValue) => void);
71
+ $emit: ((event: "clear") => void) & ((event: "input", value: string) => void) & ((event: "focus", event: FocusEvent) => void) & ((event: "blur", event: FocusEvent) => void) & ((event: "change", value: string) => void) & ((event: "update:modelValue", value: import('@webx-ui/core').InputModelValue) => void);
72
72
  $el: any;
73
73
  $options: import('vue').ComponentOptionsBase<Readonly<{
74
74
  modelValue?: import('@webx-ui/core').InputModelValue;
@@ -148,7 +148,7 @@ declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {
148
148
  onClear?: (() => any) | undefined;
149
149
  onBlur?: ((event: FocusEvent) => any) | undefined;
150
150
  onFocus?: ((event: FocusEvent) => any) | undefined;
151
- }>, "type" | "size" | "ariaLabel" | "input" | "select" | "placeholder" | "disabled" | "readonly" | "status" | "id" | "localized" | "focus" | "blur" | "clearable" | "maxlength" | "showCount" | "autocomplete"> & {
151
+ }>, "size" | "type" | "disabled" | "id" | "ariaLabel" | "placeholder" | "input" | "select" | "readonly" | "status" | "localized" | "focus" | "blur" | "clearable" | "maxlength" | "showCount" | "autocomplete"> & {
152
152
  focus: () => void | undefined;
153
153
  blur: () => void | undefined;
154
154
  select: () => void | undefined;
package/dist/RowMenu.d.ts CHANGED
@@ -1,19 +1,5 @@
1
1
  import { ActionSize } from '@webx-ui/core';
2
2
  import { RowAction } from './types';
3
- /**
4
- * What one record offers, in every list of the panel: a `···` at the end of the row.
5
- *
6
- * Always a menu, even for a single action. The panel used to have three answers to this —
7
- * a menu on `Pages`, a bare red bin on `SEO`, a toolbar over the selection in the library —
8
- * and the cost of that is not the extra click, it is that nobody knows where to look. A
9
- * menu also has room for the word: an unlabelled icon says what it does only to whoever has
10
- * already learned it (§20).
11
- *
12
- * Two rules it keeps for every list rather than leaving to each one. The destructive action
13
- * goes last, behind a rule, in red — it is never the thing the reader meant to hit. And what
14
- * somebody may not do is left out, not shown greyed: a menu is a list of what is possible,
15
- * and a row of dead entries teaches nothing.
16
- */
17
3
  type __VLS_Props = {
18
4
  /** What may be done, in the order it should read. */
19
5
  actions: RowAction[];
@@ -22,7 +8,7 @@ type __VLS_Props = {
22
8
  size?: ActionSize;
23
9
  };
24
10
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
25
- size: ActionSize;
26
11
  label: string;
12
+ size: ActionSize;
27
13
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
28
14
  export default _default;
@@ -0,0 +1,112 @@
1
+ import { HeadingLevel } from '@webx-ui/core';
2
+ import { RouteLocationRaw } from 'vue-router';
3
+ import { ScreenAction } from './types';
4
+ /**
5
+ * The first line of every screen in the panel: where the reader is, what it is called, and
6
+ * what can be done with it.
7
+ *
8
+ * Every screen used to answer that on its own, and eight screens gave eight answers — a
9
+ * heading at three different sizes, the way out as an arrow on four of them and as a line of
10
+ * breadcrumbs on the rest, the row of buttons folding into a `···` on two editors and simply
11
+ * wrapping onto a third line everywhere else. None of it is a screen's business: a reader who
12
+ * has learned one screen already knows where to look on the next, and that only holds if there
13
+ * is one head rather than one per section.
14
+ *
15
+ * The shape is four things, in this order: the way out, the name (with the state said beside
16
+ * it), the line under it that says which record this is, and the actions at the other end.
17
+ *
18
+ * Actions are declared rather than drawn, because the same action has to appear as a button on
19
+ * a desktop and as a line of a menu on a phone — and one vnode cannot be mounted in two places
20
+ * (CLAUDE.md §4). Written as markup they had to be written twice, which is what the page and
21
+ * article editors did; written as data they are written once and this decides. Two rules it
22
+ * keeps rather than leaving to each screen: the destructive action is never a button in the
23
+ * head — it lives in the `···`, where it is a word rather than a red rectangle beside the
24
+ * name — and the one action the screen exists for (`primary`) is the one that survives a
25
+ * narrow screen, with everything else folded behind the menu (§18.3).
26
+ *
27
+ * What it does not do is scroll with anything, stick to anything or know what saving means.
28
+ * A screen that has something to save carries `WxActionBar` along its bottom, and on the
29
+ * screens where the head never leaves the window that bar is the only place the save lives
30
+ * (§3.3) — the head does not duplicate it.
31
+ */
32
+ type __VLS_Props = {
33
+ /** What the screen is called. The one heading on it (§19). */
34
+ title?: string;
35
+ /** The line under the name: which record this is — a slug, a form, a count. */
36
+ subtitle?: string;
37
+ /**
38
+ * The way out of the screen. A route draws a link; `true` draws the same arrow and emits
39
+ * `back` instead, which is what a pane inside `WxListDetail` needs — on a phone the drawer
40
+ * carries no close of its own and the pane has to bring one (CLAUDE.md §4).
41
+ */
42
+ back?: RouteLocationRaw | boolean;
43
+ /** What the arrow's tooltip says. The panel's own word for it when not given. */
44
+ backLabel?: string;
45
+ /** `2` for a screen, `3` for a pane standing inside one. */
46
+ level?: HeadingLevel;
47
+ /** What can be done here, in the order it should read. */
48
+ actions?: ScreenAction[];
49
+ /** Width of the head below which the actions fold into the `···`. */
50
+ collapseBelow?: number;
51
+ /**
52
+ * Draws a rule under the head. For a screen exactly as tall as the window, where the head
53
+ * never scrolls away and needs an edge of its own; a head that scrolls does not.
54
+ */
55
+ divider?: boolean;
56
+ };
57
+ declare function __VLS_template(): {
58
+ attrs: Partial<{}>;
59
+ slots: Readonly<{
60
+ /** Above the name: breadcrumbs, when the screen stands somewhere in a tree. */
61
+ trail?: () => unknown;
62
+ /** Beside the name: the state of the record — a status badge, the way to rename it. */
63
+ 'title-after'?: () => unknown;
64
+ /** The line under the name, when it is more than a string. */
65
+ subtitle?: () => unknown;
66
+ /**
67
+ * Controls that are not one-word actions and stay whatever the width — the pair of arrows
68
+ * that walks a pile of records one at a time, say.
69
+ */
70
+ extra?: () => unknown;
71
+ }> & {
72
+ /** Above the name: breadcrumbs, when the screen stands somewhere in a tree. */
73
+ trail?: () => unknown;
74
+ /** Beside the name: the state of the record — a status badge, the way to rename it. */
75
+ 'title-after'?: () => unknown;
76
+ /** The line under the name, when it is more than a string. */
77
+ subtitle?: () => unknown;
78
+ /**
79
+ * Controls that are not one-word actions and stay whatever the width — the pair of arrows
80
+ * that walks a pile of records one at a time, say.
81
+ */
82
+ extra?: () => unknown;
83
+ };
84
+ refs: {
85
+ root: HTMLDivElement;
86
+ };
87
+ rootEl: HTMLDivElement;
88
+ };
89
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
90
+ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
91
+ back: () => any;
92
+ }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
93
+ onBack?: (() => any) | undefined;
94
+ }>, {
95
+ title: string;
96
+ actions: ScreenAction[];
97
+ subtitle: string;
98
+ back: RouteLocationRaw | boolean;
99
+ backLabel: string;
100
+ level: HeadingLevel;
101
+ collapseBelow: number;
102
+ divider: boolean;
103
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
104
+ root: HTMLDivElement;
105
+ }, HTMLDivElement>;
106
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
107
+ export default _default;
108
+ type __VLS_WithTemplateSlots<T, S> = T & {
109
+ new (): {
110
+ $slots: S;
111
+ };
112
+ };
package/dist/dates.d.ts CHANGED
@@ -7,6 +7,15 @@ export interface Dates {
7
7
  * "16 September 2025", "never".
8
8
  */
9
9
  short(value: DateLike): string;
10
+ /**
11
+ * The same moment, as narrow as a column can take it: the time alone for today, the day and a
12
+ * short month for the rest of this year, digits for anything older.
13
+ *
14
+ * A column is scanned, not read — and the full line is the reason a date column had to be 185px
15
+ * wide in Russian and wider in German. What it drops is in the tip, which is where "when
16
+ * exactly" was always answered.
17
+ */
18
+ compact(value: DateLike): string;
10
19
  /**
11
20
  * Everything there is, down to the second — what the tip holds when the short line is not
12
21
  * precise enough to settle an argument. Empty when there is no date.
package/dist/index.d.ts CHANGED
@@ -8,13 +8,16 @@ export { errorText, useErrorText } from './errors';
8
8
  export { createNotesApi, type EntityNote, type NoteAuthor, type NotesApi } from './notes';
9
9
  export { createHttp, readCookie, HttpError, type Http, type HttpOptions, type RequestOptions, } from './http';
10
10
  export { adminTypes } from './screenTypes';
11
- export type { AdminModule, AdminStatus, AdminUser, Manifest, ManifestModule, NavEntry, PickedImage, RowAction, } from './types';
11
+ export type { AdminModule, AdminStatus, AdminUser, Manifest, ManifestModule, NavEntry, PickedImage, RowAction, ScreenAction, AppliedFilter, } from './types';
12
12
  export { default as AdminShell } from './AdminShell';
13
13
  export { default as AdminNav } from './AdminNav';
14
14
  export { default as AdminLanding } from './AdminLanding';
15
15
  export { default as WxScreen } from './Screen';
16
16
  export { default as WxListScreen } from './ListScreen';
17
+ export { default as WxScreenHead } from './ScreenHead';
18
+ export { rowMenuWidth } from './rowMenu';
17
19
  export { default as WxRowMenu } from './RowMenu';
20
+ export { default as WxFilterChips } from './FilterChips';
18
21
  export { default as WxBackButton } from './BackButton';
19
22
  export { default as WxRenameButton } from './RenameButton';
20
23
  export { default as WxHelpButton } from './HelpButton';