@myop/cli 0.1.47 → 0.1.48

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.
@@ -52,25 +52,17 @@ The deployed artifact is a **single entry point** — currently an HTML file (`i
52
52
  <head>
53
53
  <meta charset="UTF-8">
54
54
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
55
- <meta name="myop:size" content='{"width":"100%","height":"100%"}'>
55
+ <meta name="myop:size" content='{"width":"100%","height":300}'>
56
56
  <title>My Component</title>
57
57
  <script type="myop/types">
58
+ // Only dynamic data goes here — static labels stay hardcoded in the component
58
59
  interface MyopInitData {
59
- title: string;
60
- items: Array<{ id: string; label: string }>;
60
+ items: Array<{ id: string; label: string; status?: 'active' | 'done' }>;
61
+ selectedId?: string;
61
62
  }
62
63
 
63
64
  interface MyopCtaPayloads {
64
65
  'item-selected': { itemId: string };
65
- 'size-requested': {
66
- width?: number | null;
67
- height?: number | null;
68
- minWidth?: number | null;
69
- maxWidth?: number | null;
70
- minHeight?: number | null;
71
- maxHeight?: number | null;
72
- required?: boolean;
73
- };
74
66
  }
75
67
 
76
68
  declare function myop_init_interface(): MyopInitData;
@@ -81,10 +73,10 @@ The deployed artifact is a **single entry point** — currently an HTML file (`i
81
73
  </script>
82
74
  <style>
83
75
  * { box-sizing: border-box; margin: 0; padding: 0; }
84
- html, body { width: 100%; height: 100%; overflow: hidden;
76
+ html, body { width: 100%; margin: 0; padding: 0;
85
77
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
86
78
  }
87
- #app-root { width: 100%; height: 100%; padding: 16px; }
79
+ #app-root { width: 100%; padding: 16px; }
88
80
  </style>
89
81
  </head>
90
82
  <body>
@@ -97,8 +89,9 @@ The deployed artifact is a **single entry point** — currently an HTML file (`i
97
89
  function render(data) {
98
90
  state = data;
99
91
  var root = document.getElementById('app-root');
92
+ // "My Tasks" heading is hardcoded — it's part of the component, not dynamic data
100
93
  root.innerHTML =
101
- '<h2>' + (data.title || '') + '</h2>' +
94
+ '<h2>My Tasks</h2>' +
102
95
  '<ul>' + (data.items || []).map(function(item) {
103
96
  return '<li data-id="' + item.id + '">' + item.label + '</li>';
104
97
  }).join('') + '</ul>';
@@ -123,12 +116,12 @@ The deployed artifact is a **single entry point** — currently an HTML file (`i
123
116
  })();
124
117
  </script>
125
118
 
119
+ <!-- Preview: only dynamic data, not UI labels -->
126
120
  <script id="myop_preview">
127
121
  window.myop_init_interface({
128
- title: 'My Component',
129
122
  items: [
130
- { id: '1', label: 'First item' },
131
- { id: '2', label: 'Second item' }
123
+ { id: '1', label: 'Review PR #42' },
124
+ { id: '2', label: 'Update dependencies', status: 'done' }
132
125
  ]
133
126
  });
134
127
  </script>
@@ -136,6 +129,42 @@ The deployed artifact is a **single entry point** — currently an HTML file (`i
136
129
  </html>
137
130
  ```
138
131
 
132
+ ## What Goes in myop_init_interface vs Component Code
133
+
134
+ Think of `myop_init_interface(data)` exactly like **React component props**. The component is a reusable UI module — its structure, labels, buttons, and layout are built-in. The host only passes dynamic data.
135
+
136
+ ### Component code (hardcoded — like JSX):
137
+ - Button labels ("Submit", "Cancel", "Sign Up")
138
+ - Headings and static copy ("Welcome", "Sign up to continue")
139
+ - Icons, decorative elements, illustrations
140
+ - Form labels ("Email", "Password")
141
+ - Placeholder text
142
+ - Navigation items, tabs, section titles
143
+ - Any text that is part of the component's identity
144
+
145
+ ### myop_init_interface data (dynamic — like React props):
146
+ - Lists of items (users, products, tasks, notifications)
147
+ - User-specific data (name, email, avatar, role)
148
+ - Configuration flags (theme, locale, permissions, feature flags)
149
+ - Counts and metrics (unread: 5, total: 42)
150
+ - State (selectedId, isExpanded, activeTab)
151
+ - URLs and dynamic assets (profile image URL, API endpoints)
152
+
153
+ ### Example — Login Component:
154
+
155
+ | WRONG (everything as data) | CORRECT (only dynamic data as props) |
156
+ |---|---|
157
+ | `heading: "Welcome back"` | `user: { email: "prefilled@example.com" }` |
158
+ | `emailLabel: "Email"` | `error: null` |
159
+ | `passwordLabel: "Password"` | `redirectUrl: "/dashboard"` |
160
+ | `submitText: "Sign In"` | |
161
+ | `forgotText: "Forgot password?"` | |
162
+
163
+ The labels "Welcome back", "Email", "Password", "Sign In" are part of the component — hardcoded in the HTML/JS, just like you'd write them in React JSX.
164
+
165
+ ### Rule of thumb:
166
+ If the host app would NOT need to change this value across different instances, it belongs in the component code, not in myop_init_interface.
167
+
139
168
  ## Component File Structure
140
169
 
141
170
  ### Single-file mode (simplest — good for small components)
@@ -122,25 +122,6 @@ window.myop_cta_handler(action_id, payload);
122
122
  })();
123
123
  ```
124
124
 
125
- ### Standard Actions
126
-
127
- These action IDs have special meaning and are handled by the Myop SDK:
128
-
129
- | Action ID | Payload | Purpose |
130
- |-----------|---------|---------|
131
- | `'size-requested'` | `{ width?, height?, minWidth?, maxWidth?, minHeight?, maxHeight?, required? }` | Request the host to resize the component container |
132
-
133
- ```javascript
134
- // Request more width
135
- window.myop_cta_handler('size-requested', {
136
- width: 400,
137
- minWidth: 300,
138
- maxWidth: 600,
139
- required: true // true = content is clipped without this size
140
- // false = preference only, host may ignore
141
- });
142
- ```
143
-
144
125
  ### Custom Actions
145
126
 
146
127
  Define any custom actions your component needs. Use kebab-case for action IDs:
@@ -226,15 +207,6 @@ The `<script id="myop_preview">` block provides mock data for development. In pr
226
207
  interface MyopCtaPayloads {
227
208
  'task-toggled': { taskId: string; completed: boolean };
228
209
  'task-deleted': { taskId: string };
229
- 'size-requested': {
230
- width?: number | null;
231
- height?: number | null;
232
- minWidth?: number | null;
233
- maxWidth?: number | null;
234
- minHeight?: number | null;
235
- maxHeight?: number | null;
236
- required?: boolean;
237
- };
238
210
  }
239
211
 
240
212
  declare function myop_init_interface(): MyopInitData;
@@ -6,7 +6,6 @@ Myop components run inside a container managed by the host application. Proper s
6
6
  - [Size Meta Tag](#size-meta-tag)
7
7
  - [Required Base CSS](#required-base-css)
8
8
  - [Layout Patterns](#layout-patterns)
9
- - [Dynamic Size Requests](#dynamic-size-requests)
10
9
  - [Common Mistakes](#common-mistakes)
11
10
 
12
11
  ## Size Meta Tag
@@ -14,10 +13,13 @@ Myop components run inside a container managed by the host application. Proper s
14
13
  Every component should declare its preferred dimensions in a `<meta>` tag inside `<head>`:
15
14
 
16
15
  ```html
17
- <meta name="myop:size" content='{"width":"100%","height":"100%"}'>
16
+ <meta name="myop:size" content='{"width":"100%","height":300}'>
18
17
  ```
19
18
 
20
- The host reads this BEFORE rendering the component, so the container can be sized correctly from the start (no layout shift).
19
+ The host reads this BEFORE rendering the component, so the container can be sized correctly from the start (no layout shift). The `height` value also determines the sizing mode:
20
+
21
+ - **Number (or absent)** → **Content mode** (default): component auto-sizes to its content, like a `<div>`
22
+ - **`"100%"`** → **Fill mode**: component fills its parent container
21
23
 
22
24
  ### Properties
23
25
 
@@ -26,7 +28,7 @@ All values are either a number (pixels) or the string `"100%"`:
26
28
  | Property | Type | Description |
27
29
  |----------|------|-------------|
28
30
  | `width` | `number \| "100%"` | Preferred width in px, or `"100%"` to fill container |
29
- | `height` | `number \| "100%"` | Preferred height in px, or `"100%"` to fill container |
31
+ | `height` | `number \| "100%"` | Preferred height in px (content mode), or `"100%"` to fill container (fill mode) |
30
32
  | `minWidth` | `number` | Minimum acceptable width in px |
31
33
  | `maxWidth` | `number` | Maximum useful width in px |
32
34
  | `minHeight` | `number` | Minimum acceptable height in px |
@@ -35,13 +37,16 @@ All values are either a number (pixels) or the string `"100%"`:
35
37
  ### Examples
36
38
 
37
39
  ```html
38
- <!-- Fill all available space (most common) -->
40
+ <!-- Content mode (default): auto-sizes to content -->
41
+ <meta name="myop:size" content='{"width":"100%","height":300}'>
42
+
43
+ <!-- Fill mode: fills all available space -->
39
44
  <meta name="myop:size" content='{"width":"100%","height":"100%"}'>
40
45
 
41
- <!-- Fixed width sidebar component -->
46
+ <!-- Fixed width sidebar, fills height -->
42
47
  <meta name="myop:size" content='{"width":300,"height":"100%","minWidth":200,"maxWidth":400}'>
43
48
 
44
- <!-- Fixed height banner -->
49
+ <!-- Fixed height banner, content mode -->
45
50
  <meta name="myop:size" content='{"width":"100%","height":80}'>
46
51
 
47
52
  <!-- Card with constraints -->
@@ -50,32 +55,31 @@ All values are either a number (pixels) or the string `"100%"`:
50
55
 
51
56
  ## Required Base CSS
52
57
 
53
- Every Myop component MUST include this base CSS to prevent unexpected scrollbars and ensure the component fills its container:
58
+ There are two base CSS patterns depending on the sizing mode:
59
+
60
+ ### Content Mode (default) — component acts like a `<div>`
61
+
62
+ The component auto-sizes to its content. Width fills the parent, height grows with content. Use for cards, forms, lists, banners, modals, and any component where the height depends on the content.
54
63
 
55
64
  ```css
56
- * {
57
- box-sizing: border-box;
58
- margin: 0;
59
- padding: 0;
60
- }
65
+ * { box-sizing: border-box; margin: 0; padding: 0; }
66
+ html, body { width: 100%; margin: 0; padding: 0; }
67
+ #app-root { width: 100%; }
68
+ ```
61
69
 
62
- html, body {
63
- width: 100%;
64
- height: 100%;
65
- overflow: hidden; /* Component handles its own scrolling */
66
- margin: 0;
67
- padding: 0;
68
- }
70
+ ### Fill Mode (opt-in) — component fills its parent container
69
71
 
70
- #app-root {
71
- width: 100%;
72
- height: 100%;
73
- }
72
+ The component fills all available space. Use for sidebars, full-page panels, dashboards, and any component that must stretch to fit the parent.
73
+
74
+ ```css
75
+ * { box-sizing: border-box; margin: 0; padding: 0; }
76
+ html, body { width: 100%; height: 100%; overflow: hidden; margin: 0; padding: 0; }
77
+ #app-root { width: 100%; height: 100%; }
74
78
  ```
75
79
 
76
- ### Why `overflow: hidden` on body?
80
+ ### Why `overflow: hidden` on body in fill mode?
77
81
 
78
- The component is rendered inside an iframe by the host. If the body scrolls, the host has no way to control or sync that scroll. Instead, the component should manage scrolling internally with specific scrollable regions.
82
+ The component is rendered inside an iframe by the host. If the body scrolls, the host has no way to control or sync that scroll. Instead, fill-mode components should manage scrolling internally with specific scrollable regions. In content mode, overflow is omitted so the host can control it.
79
83
 
80
84
  ## Layout Patterns
81
85
 
@@ -147,47 +151,6 @@ For simple display components:
147
151
  }
148
152
  ```
149
153
 
150
- ## Dynamic Size Requests
151
-
152
- If the component needs to change its size after initialization (e.g., content loaded, accordion expanded), use the `size-requested` CTA:
153
-
154
- ```javascript
155
- // Request specific dimensions
156
- window.myop_cta_handler('size-requested', {
157
- width: 400,
158
- height: 600,
159
- required: true // true = content will be clipped without this size
160
- });
161
-
162
- // Request only width change
163
- window.myop_cta_handler('size-requested', {
164
- width: 500,
165
- minWidth: 350,
166
- maxWidth: 700
167
- });
168
-
169
- // Request based on content height
170
- var contentHeight = document.getElementById('content').scrollHeight;
171
- window.myop_cta_handler('size-requested', {
172
- height: contentHeight + 40, // Add padding
173
- required: false // Preference, not critical
174
- });
175
- ```
176
-
177
- ### Size Request Payload
178
-
179
- | Property | Type | Description |
180
- |----------|------|-------------|
181
- | `width` | `number \| null` | Desired width in px (`null` = no preference) |
182
- | `height` | `number \| null` | Desired height in px (`null` = no preference) |
183
- | `minWidth` | `number \| null` | Minimum acceptable width |
184
- | `maxWidth` | `number \| null` | Maximum acceptable width |
185
- | `minHeight` | `number \| null` | Minimum acceptable height |
186
- | `maxHeight` | `number \| null` | Maximum acceptable height |
187
- | `required` | `boolean` | `true` = content is clipped/broken without this size; `false` = preference only |
188
-
189
- **Important:** The host application may choose to ignore size requests. Always design the component to be functional at any reasonable size, and use `required: true` sparingly.
190
-
191
154
  ## Common Mistakes
192
155
 
193
156
  ### Missing `min-height: 0` on flex children
@@ -207,15 +170,15 @@ window.myop_cta_handler('size-requested', {
207
170
  }
208
171
  ```
209
172
 
210
- ### Body scrolling instead of internal scrolling
173
+ ### Body scrolling instead of internal scrolling (fill mode)
211
174
 
212
175
  ```css
213
- /* WRONG: Body scrolls, host can't control it */
176
+ /* WRONG: Body scrolls in fill mode, host can't control it */
214
177
  html, body {
215
178
  overflow: auto;
216
179
  }
217
180
 
218
- /* CORRECT: Body never scrolls, content region scrolls */
181
+ /* CORRECT (fill mode): Body never scrolls, content region scrolls */
219
182
  html, body {
220
183
  overflow: hidden;
221
184
  }
@@ -224,6 +187,8 @@ html, body {
224
187
  }
225
188
  ```
226
189
 
190
+ Note: In content mode, body overflow is not set — the host controls overflow.
191
+
227
192
  ### Forgetting `box-sizing: border-box`
228
193
 
229
194
  ```css
@@ -252,11 +217,16 @@ html, body {
252
217
  height: 400px;
253
218
  }
254
219
 
255
- /* CORRECT: Fills whatever container the host provides */
220
+ /* CORRECT (fill mode): Fills whatever container the host provides */
256
221
  #app-root {
257
222
  width: 100%;
258
223
  height: 100%;
259
224
  }
225
+
226
+ /* CORRECT (content mode): Width fills, height is content-driven */
227
+ #app-root {
228
+ width: 100%;
229
+ }
260
230
  ```
261
231
 
262
232
  ### Size meta tag with invalid JSON
@@ -135,16 +135,6 @@ interface MyopCtaPayloads {
135
135
  'page-changed': { page: number };
136
136
  'tab-switched': { tabId: string };
137
137
 
138
- // Standard Myop actions (always include if component needs resizing)
139
- 'size-requested': {
140
- width?: number | null;
141
- height?: number | null;
142
- minWidth?: number | null;
143
- maxWidth?: number | null;
144
- minHeight?: number | null;
145
- maxHeight?: number | null;
146
- required?: boolean;
147
- };
148
138
  }
149
139
  ```
150
140
 
@@ -152,9 +142,8 @@ interface MyopCtaPayloads {
152
142
 
153
143
  1. **Use kebab-case** for action names: `'item-selected'` not `'itemSelected'`
154
144
  2. **Use `void`** for actions with no payload (e.g., `'refresh-requested': void`)
155
- 3. **Include `size-requested`** if the component ever needs to request a resize
156
- 4. **Payload must be JSON-serializable** - no functions, DOM elements, or class instances
157
- 5. **Every action called in code must be defined here** - keep types in sync with implementation
145
+ 3. **Payload must be JSON-serializable** - no functions, DOM elements, or class instances
146
+ 4. **Every action called in code must be defined here** - keep types in sync with implementation
158
147
 
159
148
  ## Standard Declarations
160
149
 
@@ -205,12 +194,6 @@ interface MyopInitData {
205
194
 
206
195
  interface MyopCtaPayloads {
207
196
  'point-clicked': { datasetIndex: number; pointIndex: number; value: number };
208
- 'size-requested': {
209
- width?: number | null; height?: number | null;
210
- minWidth?: number | null; maxWidth?: number | null;
211
- minHeight?: number | null; maxHeight?: number | null;
212
- required?: boolean;
213
- };
214
197
  }
215
198
  ```
216
199
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myop/cli",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "description": "Myop cli",
5
5
  "type": "module",
6
6
  "repository": {