@symbo.ls/mcp 1.0.19 → 1.0.21
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/package.json +1 -1
- package/symbols_mcp/skills/RULES.md +69 -9
package/package.json
CHANGED
|
@@ -375,22 +375,39 @@ export const switchView = function switchView(view) {
|
|
|
375
375
|
|
|
376
376
|
---
|
|
377
377
|
|
|
378
|
-
## Rule 19 — Conditional props: use `isX` + `'.isX'`
|
|
378
|
+
## Rule 19 — Conditional props: use `isX` + `'.isX'` — STRICTLY enforce when multiple properties share the same condition
|
|
379
|
+
|
|
380
|
+
**IMPORTANT:** When two or more properties depend on the same condition, you MUST use the `isX` / `'.isX'` pattern. NEVER repeat the same condition across multiple property functions — this is redundant, harder to read, and violates DOMQL v3 conventions.
|
|
379
381
|
|
|
380
382
|
```js
|
|
381
|
-
// ✅ —
|
|
382
|
-
export const
|
|
383
|
+
// ✅ CORRECT — conditional props with isX pattern
|
|
384
|
+
export const MapPanel = {
|
|
385
|
+
width: '0',
|
|
386
|
+
height: '0',
|
|
383
387
|
opacity: '0',
|
|
384
|
-
|
|
388
|
+
'@tabletS': { width: '0' },
|
|
389
|
+
'@mobileL': { width: '0' },
|
|
385
390
|
|
|
386
|
-
|
|
387
|
-
'.
|
|
391
|
+
isMapView: (el, s) => s.root.showMapView,
|
|
392
|
+
'.isMapView': {
|
|
393
|
+
width: '50%',
|
|
394
|
+
height: 'calc(100vh - 130px)',
|
|
388
395
|
opacity: '1',
|
|
389
|
-
|
|
396
|
+
'@tabletS': { width: '55%' },
|
|
397
|
+
'@mobileL': { width: '100%' },
|
|
390
398
|
},
|
|
391
399
|
}
|
|
392
400
|
|
|
393
|
-
// ❌ —
|
|
401
|
+
// ❌ WRONG — same condition repeated across multiple properties
|
|
402
|
+
export const MapPanel = {
|
|
403
|
+
width: (el, s) => s.root.showMapView ? '50%' : '0',
|
|
404
|
+
height: (el, s) => s.root.showMapView ? 'calc(100vh - 130px)' : '0',
|
|
405
|
+
opacity: (el, s) => s.root.showMapView ? '1' : '0',
|
|
406
|
+
'@tabletS': { width: (el, s) => s.root.showMapView ? '55%' : '0' },
|
|
407
|
+
'@mobileL': { width: (el, s) => s.root.showMapView ? '100%' : '0' },
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// ❌ WRONG — deprecated props function with conditional spread
|
|
394
411
|
export const ModalCard = {
|
|
395
412
|
props: (el, s) => ({
|
|
396
413
|
...(s.root.activeModal ? { opacity: '1' } : { opacity: '0' })
|
|
@@ -1105,6 +1122,48 @@ if (cell) cell.node.focus()
|
|
|
1105
1122
|
|
|
1106
1123
|
---
|
|
1107
1124
|
|
|
1125
|
+
## Rule 41 — STRICTLY use `Link` component with `href` as a direct property — NEVER use `<a>` tags or put `href` in `attrs`
|
|
1126
|
+
|
|
1127
|
+
**IMPORTANT:** All links MUST use the `Link` component with `extends: 'Link'`. The `href` property MUST be placed at the root level of the component, NOT inside `attrs: {}`. This is critical for proper routing and navigation.
|
|
1128
|
+
|
|
1129
|
+
```js
|
|
1130
|
+
// ✅ CORRECT — Link component with href at root
|
|
1131
|
+
Nav: {
|
|
1132
|
+
extends: 'Link',
|
|
1133
|
+
href: '/about',
|
|
1134
|
+
text: 'About'
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
// ✅ CORRECT — dynamic href at root
|
|
1138
|
+
ProfileLink: {
|
|
1139
|
+
extends: 'Link',
|
|
1140
|
+
href: (el, s) => `/user/${s.userId}`,
|
|
1141
|
+
text: 'View Profile'
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
// ❌ WRONG — href inside attrs
|
|
1145
|
+
Nav: {
|
|
1146
|
+
extends: 'Link',
|
|
1147
|
+
attrs: { href: '/about' }, // NEVER put href in attrs
|
|
1148
|
+
text: 'About'
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
// ❌ WRONG — using tag 'a' instead of Link component
|
|
1152
|
+
Nav: {
|
|
1153
|
+
tag: 'a',
|
|
1154
|
+
href: '/about',
|
|
1155
|
+
text: 'About'
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// ❌ WRONG — no extends: 'Link' for navigation
|
|
1159
|
+
Nav: {
|
|
1160
|
+
href: '/about', // href without Link component won't route properly
|
|
1161
|
+
text: 'About'
|
|
1162
|
+
}
|
|
1163
|
+
```
|
|
1164
|
+
|
|
1165
|
+
---
|
|
1166
|
+
|
|
1108
1167
|
## Project Structure Quick Reference
|
|
1109
1168
|
|
|
1110
1169
|
```
|
|
@@ -1143,7 +1202,7 @@ Before finalizing generated code, verify ALL of the following:
|
|
|
1143
1202
|
- [ ] Color uses dot-notation: `'white.7'` not `'white .7'` (Rule 11)
|
|
1144
1203
|
- [ ] Standard HTML attributes at root; only `data-*`/`aria-*`/custom in `attr: {}` (Rule 14)
|
|
1145
1204
|
- [ ] `onRender` guards against double-init (Rule 15)
|
|
1146
|
-
- [ ] Conditional props use `isX` / `'.isX'` pattern (Rule 19)
|
|
1205
|
+
- [ ] Conditional props use `isX` / `'.isX'` pattern — never repeat the same condition across multiple property functions (Rule 19)
|
|
1147
1206
|
- [ ] One H1 per page; logical heading hierarchy H1 > H2 > H3
|
|
1148
1207
|
- [ ] Buttons for actions, Links for navigation (Rule 21)
|
|
1149
1208
|
- [ ] Forms have labeled inputs with `name` and `type` attributes
|
|
@@ -1167,6 +1226,7 @@ Before finalizing generated code, verify ALL of the following:
|
|
|
1167
1226
|
- [ ] No `el.context` reads in props — use token strings directly (Rule 38)
|
|
1168
1227
|
- [ ] `el.node` reads are fine, `el.node.x = ...` writes are forbidden (Rule 39)
|
|
1169
1228
|
- [ ] No `document.getElementById`/`querySelector` — use `el.lookdown()`, `el.lookup()`, etc. (Rule 40)
|
|
1229
|
+
- [ ] All links use `extends: 'Link'` with `href` at root — never in `attrs`, never `tag: 'a'` (Rule 41)
|
|
1170
1230
|
- [ ] Translations (`lang.js`) at root level, NOT inside `designSystem/`
|
|
1171
1231
|
- [ ] `designSystem/` contains only visual tokens — no translations, no logic
|
|
1172
1232
|
- [ ] `symbols/functions/` contains only frontend functions (called via `el.call()`)
|