mnfst 0.5.68 → 0.5.70

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/README.md CHANGED
@@ -14,7 +14,7 @@ Manifest is a frontend framework extending HTML for rapid, feature-rich website
14
14
 
15
15
  ## 💾 Setup
16
16
 
17
- Get [CDN links](https://manifestjs.org/getting-started/setup) for existing projects or try the [starter project](https://manifestjs.org/getting-started/starter-project) for new ones.
17
+ Get [CDN links](https://manifestx.dev/getting-started/setup) for existing projects or try the [starter project](https://manifestx.dev/getting-started/starter-project) for new ones.
18
18
 
19
19
  <br>
20
20
 
@@ -38,7 +38,7 @@ Get [CDN links](https://manifestjs.org/getting-started/setup) for existing proje
38
38
 
39
39
  ## 📚 Documentation
40
40
 
41
- For full documentation visit [manifestjs.org](https://manifestjs.org).
41
+ For full documentation visit [manifestx.dev](https://manifestx.dev).
42
42
 
43
43
  <br>
44
44
 
@@ -17,8 +17,8 @@
17
17
  margin-bottom: calc(var(--spacing, 0.25rem) * 4)
18
18
  }
19
19
 
20
- &> :not(summary, hr, .divider) {
21
- padding: var(--spacing-field-padding, 0.625rem) 0
20
+ &>:last-child {
21
+ margin-bottom: calc(var(--spacing, 0.25rem) * 8)
22
22
  }
23
23
 
24
24
  /* Content */
@@ -27,6 +27,7 @@
27
27
  display: flex;
28
28
  justify-content: space-between;
29
29
  align-items: center;
30
+ padding: var(--spacing-field-padding, 0.625rem) 0;
30
31
  font-weight: bold;
31
32
  color: var(--color-content-stark, oklch(16.6% 0.026 267));
32
33
  user-select: none;
@@ -959,7 +959,7 @@ function initializeAuthMagic() {
959
959
  return false;
960
960
  }
961
961
 
962
- // Add $auth magic method (like $locale, $theme)
962
+ // Add $auth magic method (like $locale, $colors)
963
963
  Alpine.magic('auth', () => {
964
964
  const store = Alpine.store('auth');
965
965
  if (!store) {
@@ -1,6 +1,6 @@
1
1
  /* Manifest Code CSS
2
2
  /* By Andrew Matlock under MIT license
3
- /* https://manifestjs.org/styles/code
3
+ /* https://manifestx.dev/styles/code
4
4
  */
5
5
 
6
6
  @import url('https://fonts.googleapis.com/css2?family=Gabarito:wght@400..900&family=IBM+Plex+Mono:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=Lexend+Exa&display=swap');
package/lib/manifest.css CHANGED
@@ -1,6 +1,6 @@
1
1
  /* Manifest CSS
2
2
  /* By Andrew Matlock under MIT license
3
- /* https://manifestjs.org
3
+ /* https://manifestx.dev
4
4
  /* Modify referenced variables in manifest.theme.css
5
5
  */
6
6
 
@@ -393,8 +393,8 @@
393
393
  margin-bottom: calc(var(--spacing, 0.25rem) * 4)
394
394
  }
395
395
 
396
- &> :not(summary, hr, .divider) {
397
- padding: var(--spacing-field-padding, 0.625rem) 0
396
+ &>:last-child {
397
+ margin-bottom: calc(var(--spacing, 0.25rem) * 8)
398
398
  }
399
399
 
400
400
  /* Content */
@@ -403,6 +403,7 @@
403
403
  display: flex;
404
404
  justify-content: space-between;
405
405
  align-items: center;
406
+ padding: var(--spacing-field-padding, 0.625rem) 0;
406
407
  font-weight: bold;
407
408
  color: var(--color-content-stark, oklch(16.6% 0.026 267));
408
409
  user-select: none;
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Manifest ambient type declarations.
3
+ * https://manifestx.dev
4
+ *
5
+ * This file gives editors (VS Code, Cursor, JetBrains) and AI coding assistants
6
+ * type information for Manifest's magic globals and data-source state. It is
7
+ * intended to live in the project root and is regenerated by `npx mnfst-types`
8
+ * to add project-specific augmentations to ManifestSources from manifest.json.
9
+ *
10
+ * Hand-edits below the AUGMENTATION marker will be overwritten on regeneration.
11
+ */
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Data-source state and operators (attached to every $x.<source>)
15
+ // ---------------------------------------------------------------------------
16
+
17
+ /** Appwrite-style query expression returned by helper builders. */
18
+ export type ManifestQueryExpr = string;
19
+
20
+ /** Appwrite-style query helpers used with `$query([...])`. */
21
+ export interface ManifestQuery {
22
+ equal(field: string, value: unknown): ManifestQueryExpr;
23
+ notEqual(field: string, value: unknown): ManifestQueryExpr;
24
+ lessThan(field: string, value: number | string): ManifestQueryExpr;
25
+ lessThanEqual(field: string, value: number | string): ManifestQueryExpr;
26
+ greaterThan(field: string, value: number | string): ManifestQueryExpr;
27
+ greaterThanEqual(field: string, value: number | string): ManifestQueryExpr;
28
+ between(field: string, start: number | string, end: number | string): ManifestQueryExpr;
29
+ contains(field: string, value: string | string[]): ManifestQueryExpr;
30
+ startsWith(field: string, value: string): ManifestQueryExpr;
31
+ endsWith(field: string, value: string): ManifestQueryExpr;
32
+ search(field: string, value: string): ManifestQueryExpr;
33
+ isNull(field: string): ManifestQueryExpr;
34
+ isNotNull(field: string): ManifestQueryExpr;
35
+ select(fields: string[]): ManifestQueryExpr;
36
+ orderAsc(field: string): ManifestQueryExpr;
37
+ orderDesc(field: string): ManifestQueryExpr;
38
+ limit(value: number): ManifestQueryExpr;
39
+ offset(value: number): ManifestQueryExpr;
40
+ cursorAfter(id: string): ManifestQueryExpr;
41
+ cursorBefore(id: string): ManifestQueryExpr;
42
+ }
43
+
44
+ /** State flags exposed on every data source (array or object). */
45
+ export interface ManifestSourceState {
46
+ /** True while the source is fetching for the first time or after a mutation. */
47
+ readonly $loading: boolean;
48
+ /** Last error from a load or mutation, or null. */
49
+ readonly $error: Error | string | null;
50
+ /** True once initial load has completed (success or failure). */
51
+ readonly $ready: boolean;
52
+ }
53
+
54
+ /** Operators available on array-shaped sources (CSV tabular, JSON arrays, Appwrite tables). */
55
+ export interface ManifestArrayOps<T> {
56
+ /** Substring match across the given fields. Returns matching items. */
57
+ $search(term: string, ...fields: (keyof T & string)[]): T[];
58
+ /**
59
+ * Local sources: filter by an array of `Manifest.query.*` expressions and array methods.
60
+ * Appwrite sources: server-side query, returns a Promise.
61
+ */
62
+ $query(expressions: ManifestQueryExpr[]): T[] | Promise<T[]>;
63
+ /** Look up a single row whose `id` matches the current route param, if any. */
64
+ $route(path?: string): T | undefined;
65
+ }
66
+
67
+ /** Mutations available on Appwrite-table sources. */
68
+ export interface ManifestAppwriteTableOps<T> {
69
+ $create(values: Partial<T>): Promise<T>;
70
+ $update(id: string, values: Partial<T>): Promise<T>;
71
+ $delete(id: string): Promise<void>;
72
+ $duplicate(id: string, overrides?: Partial<T>): Promise<T>;
73
+ }
74
+
75
+ /** Operations available on Appwrite-bucket (storage) sources. */
76
+ export interface ManifestAppwriteBucketOps {
77
+ $url(fileId: string): string;
78
+ $preview(fileId: string, opts?: Record<string, unknown>): string;
79
+ $download(fileId: string): string;
80
+ $openUrl(fileId: string): void;
81
+ $openPreview(fileId: string): void;
82
+ $openDownload(fileId: string): void;
83
+ $upload(file: File | Blob, opts?: Record<string, unknown>): Promise<{ $id: string }>;
84
+ $remove(fileId: string): Promise<void>;
85
+ $filesFor(parentId: string, fieldName?: string): unknown[];
86
+ $unlinkFrom(parentId: string, fileId: string): Promise<void>;
87
+ $removeFrom(parentId: string, fileId: string): Promise<void>;
88
+ }
89
+
90
+ /**
91
+ * The shape returned by `$x.<source>` for an array-of-rows source.
92
+ * Behaves as a regular `T[]` (supports `map`, `filter`, `find`, etc.) plus
93
+ * Manifest operators and state flags.
94
+ */
95
+ export type ManifestArraySource<T> =
96
+ & ReadonlyArray<T>
97
+ & ManifestSourceState
98
+ & ManifestArrayOps<T>
99
+ & Partial<ManifestAppwriteTableOps<T>>;
100
+
101
+ /** The shape returned by `$x.<source>` for an object-shaped source (CSV key-value, JSON object, YAML map). */
102
+ export type ManifestObjectSource<T> = T & ManifestSourceState;
103
+
104
+ /** The shape returned by `$x.<source>` for an Appwrite storage bucket. */
105
+ export type ManifestBucketSource = ManifestSourceState & ManifestAppwriteBucketOps;
106
+
107
+ // ---------------------------------------------------------------------------
108
+ // Magic globals registered by Manifest plugins
109
+ // ---------------------------------------------------------------------------
110
+
111
+ /**
112
+ * Project-specific data sources, keyed by the names declared in `manifest.json`'s
113
+ * `data` property. Augmented by `npx mnfst-types` from manifest.json + sample
114
+ * data (declarations appended below the AUGMENTATION marker).
115
+ */
116
+ export interface ManifestSources {
117
+ [sourceName: string]: ManifestArraySource<any> | ManifestObjectSource<any> | ManifestBucketSource;
118
+ }
119
+
120
+ /** `$auth` from the Appwrite auth plugin. Loose by design — auth API is broad. */
121
+ export interface ManifestAuth {
122
+ readonly current: { $id: string; email?: string; name?: string;[k: string]: unknown } | null;
123
+ readonly isAuthenticated: boolean;
124
+ readonly isLoading: boolean;
125
+ readonly currentTeam: { $id: string; name: string;[k: string]: unknown } | null;
126
+ readonly teams: Array<{ $id: string; name: string;[k: string]: unknown }>;
127
+ login(email: string, password?: string): Promise<unknown>;
128
+ loginWithMagic(email: string): Promise<unknown>;
129
+ loginWithOAuth(provider: string, opts?: Record<string, unknown>): Promise<unknown>;
130
+ loginAsGuest(): Promise<unknown>;
131
+ logout(): Promise<unknown>;
132
+ [extra: string]: unknown;
133
+ }
134
+
135
+ /** `$locale` from the localization plugin. */
136
+ export interface ManifestLocale {
137
+ readonly current: string;
138
+ readonly available: string[];
139
+ set(locale: string): void;
140
+ }
141
+
142
+ /** `$toast` from the toasts plugin. */
143
+ export interface ManifestToast {
144
+ (message: string, opts?: { type?: 'info' | 'success' | 'warning' | 'error'; duration?: number }): void;
145
+ info(message: string, opts?: Record<string, unknown>): void;
146
+ success(message: string, opts?: Record<string, unknown>): void;
147
+ warning(message: string, opts?: Record<string, unknown>): void;
148
+ error(message: string, opts?: Record<string, unknown>): void;
149
+ dismiss(id?: string): void;
150
+ }
151
+
152
+ /** `$colors` from the themes plugin. */
153
+ export interface ManifestTheme {
154
+ readonly current: 'light' | 'dark' | 'system';
155
+ set(theme: 'light' | 'dark' | 'system'): void;
156
+ toggle(): void;
157
+ }
158
+
159
+ /** `$colors` from the colors plugin. */
160
+ export interface ManifestColors {
161
+ [name: string]: string | ManifestColors;
162
+ }
163
+
164
+ /** `$colorpicker` from the colorpicker plugin. */
165
+ export interface ManifestColorpicker {
166
+ open(opts?: Record<string, unknown>): void;
167
+ close(): void;
168
+ [extra: string]: unknown;
169
+ }
170
+
171
+ /** `$url` from the url-parameters plugin: read/write URL query params reactively. */
172
+ export interface ManifestUrl {
173
+ get(name: string): string | null;
174
+ set(name: string, value: string | null): void;
175
+ has(name: string): boolean;
176
+ [name: string]: unknown;
177
+ }
178
+
179
+ /** `$route` magic — true if the current route matches the given pattern. */
180
+ export type ManifestRoute = (pattern: string) => boolean;
181
+
182
+ /**
183
+ * `$modify('attr')` — exposed in component HTML. Returns the value of an
184
+ * attribute set on the parent component instance (Manifest's prop mechanism).
185
+ */
186
+ export type ManifestModify = (attr: string) => string | undefined;
187
+
188
+ /** `$try(fn)` — run a callback and swallow any thrown error, returning undefined on failure. */
189
+ export type ManifestTry = <T>(fn: () => T) => T | undefined;
190
+
191
+ // ---------------------------------------------------------------------------
192
+ // Global declarations (what Alpine exposes inside `x-data`, `x-show`, etc.)
193
+ // ---------------------------------------------------------------------------
194
+
195
+ declare global {
196
+ /** Project data sources registered in manifest.json. */
197
+ const $x: ManifestSources;
198
+ /** Match the current route against a pattern (e.g. `$route('/about')`). */
199
+ const $route: ManifestRoute;
200
+ /** Read a parent component attribute (Manifest's prop mechanism). */
201
+ const $modify: ManifestModify;
202
+ /** Run a callback safely, returning undefined on error. */
203
+ const $try: ManifestTry;
204
+ /** Appwrite auth plugin (only present when the plugin is loaded). */
205
+ const $auth: ManifestAuth;
206
+ /** Localization plugin. */
207
+ const $locale: ManifestLocale;
208
+ /** Toasts plugin. */
209
+ const $toast: ManifestToast;
210
+ /** Themes plugin. */
211
+ const $colors: ManifestTheme;
212
+ /** Colors plugin. */
213
+ const $colors: ManifestColors;
214
+ /** Colorpicker plugin. */
215
+ const $colorpicker: ManifestColorpicker;
216
+ /** URL parameters plugin. */
217
+ const $url: ManifestUrl;
218
+
219
+ /** Window-level Manifest namespace exposed by the loader. */
220
+ interface Window {
221
+ Manifest?: {
222
+ loadPlugin(name: string, version?: string): Promise<unknown>;
223
+ loadTailwind(version?: string): Promise<unknown>;
224
+ getPluginUrl(name: string, version?: string): string;
225
+ };
226
+ Alpine?: unknown;
227
+ __manifestLoaded?: unknown;
228
+ }
229
+ }
230
+
231
+ // ---------------------------------------------------------------------------
232
+ // AUGMENTATION:start
233
+ // Project-specific declarations are appended below by `npx mnfst-types`.
234
+ // Do not hand-edit between the start/end markers — re-running the CLI
235
+ // regenerates this section from manifest.json + sample data.
236
+ // ---------------------------------------------------------------------------
237
+
238
+ // (No project augmentations yet — run `npx mnfst-types` to generate.)
239
+
240
+ // ---------------------------------------------------------------------------
241
+ // AUGMENTATION:end
242
+ // ---------------------------------------------------------------------------
243
+
244
+ export { };
@@ -164,6 +164,32 @@ function initializeDropdownPlugin() {
164
164
  el.style.setProperty('anchor-name', anchorName);
165
165
  menu.style.setProperty('position-anchor', anchorName);
166
166
 
167
+ // ----- A11y wiring (WAI-ARIA Menu Button pattern) -----
168
+ // The trigger needs `aria-haspopup="menu"`, `aria-controls`, and a
169
+ // dynamic `aria-expanded` that follows the popover's open state.
170
+ // The menu element gets `role="menu"` and each list item gets
171
+ // `role="menuitem"` so screen readers announce the relationship.
172
+ //
173
+ // We don't apply these for `.context` dropdowns invoked by right-
174
+ // click — they're not button-triggered popups in the APG sense.
175
+ if (!modifiers.includes('context')) {
176
+ if (!menu.id) menu.id = 'mnfst-dropdown-' + Math.random().toString(36).slice(2, 9);
177
+ el.setAttribute('aria-haspopup', 'menu');
178
+ el.setAttribute('aria-controls', menu.id);
179
+ el.setAttribute('aria-expanded', menu.matches(':popover-open') ? 'true' : 'false');
180
+ if (!menu.hasAttribute('role')) menu.setAttribute('role', 'menu');
181
+ menu.querySelectorAll('li').forEach((li) => {
182
+ if (!li.hasAttribute('role')) li.setAttribute('role', 'menuitem');
183
+ });
184
+ // Keep aria-expanded in sync with the popover's state.
185
+ if (!menu.__mnfstAriaToggleBound) {
186
+ menu.__mnfstAriaToggleBound = true;
187
+ menu.addEventListener('toggle', (e) => {
188
+ el.setAttribute('aria-expanded', e.newState === 'open' ? 'true' : 'false');
189
+ });
190
+ }
191
+ }
192
+
167
193
  // Set up hover functionality after menu is ready
168
194
  if (modifiers.includes('hover')) {
169
195
  const handleShowPopover = () => {
package/lib/manifest.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /* Manifest JS
2
2
  /* By Andrew Matlock under MIT license
3
- /* https://manifestjs.org
3
+ /* https://manifestx.dev
4
4
  /*
5
5
  /* Lightweight loader that dynamically loads Alpine.js and Manifest plugins
6
6
  /* from jsDelivr CDN. Loads all plugins by default, or a subset if specified.
@@ -20,7 +20,7 @@
20
20
  * innerHTML) of every element that needs runtime hydration. This
21
21
  * function runs once on page load BEFORE any plugin or Alpine starts —
22
22
  * it walks the contract, restores source state, and removes its own
23
- * markers. Every downstream plugin (themes, router, data, markdown,
23
+ * markers. Every downstream plugin (colors, router, data, markdown,
24
24
  * icons, …) then sees exactly the DOM the user authored, exactly as it
25
25
  * would in a live SPA. No plugin needs a "prerender mode" branch.
26
26
  *
@@ -100,7 +100,7 @@
100
100
  tmp.innerHTML = newHTML;
101
101
  const parsed = tmp.firstElementChild;
102
102
  if (parsed) {
103
- try { el.parentNode.replaceChild(parsed, el); } catch (_) {}
103
+ try { el.parentNode.replaceChild(parsed, el); } catch (_) { }
104
104
  }
105
105
  continue;
106
106
  }
@@ -132,7 +132,7 @@
132
132
  tmp.innerHTML = newHTML;
133
133
  const parsed = tmp.firstElementChild;
134
134
  if (parsed) {
135
- try { el.parentNode.replaceChild(parsed, el); } catch (_) {}
135
+ try { el.parentNode.replaceChild(parsed, el); } catch (_) { }
136
136
  }
137
137
  }
138
138