smbls 3.7.0 → 3.7.4

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
@@ -2,63 +2,64 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/smbls.svg)](https://www.npmjs.com/package/smbls)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/smbls.svg)](https://www.npmjs.com/package/smbls)
5
- [![bundle size](https://img.shields.io/bundlephobia/minzip/smbls)](https://bundlephobia.com/package/smbls)
6
5
  [![license](https://img.shields.io/npm/l/smbls.svg)](https://github.com/symbo-ls/smbls/blob/main/LICENSE)
7
- [![node](https://img.shields.io/node/v/smbls.svg)](https://nodejs.org)
8
- [![ESM](https://img.shields.io/badge/module-ESM%20%7C%20CJS%20%7C%20IIFE-blue)](https://www.npmjs.com/package/smbls)
9
6
 
10
- > The main Symbols package bundles the entire design system ecosystem into a single import.
7
+ The main Symbols package. Bundles the design system framework, UI components, and rendering engine into a single import.
11
8
 
12
- ## Installation
9
+ ## Install
13
10
 
14
11
  ```bash
15
12
  npm install smbls
16
13
  ```
17
14
 
18
- ## What's Included
15
+ ## Quick start
19
16
 
20
- This package re-exports everything from:
21
-
22
- | Package | Description |
23
- |---------|-------------|
24
- | `@domql/utils` | Utility functions |
25
- | `@symbo.ls/scratch` | CSS framework and methodology |
26
- | `@symbo.ls/emotion` | Emotion CSS-in-JS integration |
27
- | `@symbo.ls/default-config` | Default design system configuration |
28
- | `@symbo.ls/uikit` | Complete UI component library |
29
- | `@symbo.ls/smbls-utils` | Symbols-specific utilities |
30
- | `css-in-props` | CSS properties as props |
31
- | `attrs-in-props` | HTML attributes as props |
32
-
33
- It also includes the `@symbo.ls/cli` binary, `@symbo.ls/fetch`, `@symbo.ls/sync`, `@symbo.ls/helmet`, and `@domql/router`.
34
-
35
- ## Quick Start
36
-
37
- ### Initialize Design System
38
-
39
- ```javascript
40
- import { init } from 'smbls'
17
+ ```js
18
+ import { init, create } from 'smbls'
41
19
 
42
20
  init({
43
21
  color: {
44
22
  primary: '#3B82F6',
45
- gray: ['#1F2937', '#9CA3AF'] // [light, dark]
23
+ gray: ['#1F2937', '#9CA3AF']
46
24
  },
47
25
  theme: {
48
26
  primary: {
49
27
  color: 'white',
50
- background: 'primary',
51
- ':hover': { opacity: '0.85' }
28
+ background: 'primary'
52
29
  }
53
30
  }
54
31
  })
32
+
33
+ create({
34
+ Header: {
35
+ tag: 'header',
36
+ H1: { text: 'Hello Symbols' }
37
+ },
38
+ Main: {
39
+ Button: {
40
+ text: 'Get Started',
41
+ theme: 'primary'
42
+ }
43
+ }
44
+ }, { key: 'my-app' })
55
45
  ```
56
46
 
57
- ### Theme Switching
47
+ ## Create variants
58
48
 
59
- Themes switch automatically via CSS — no JavaScript re-renders needed:
49
+ ```js
50
+ import { create, createAsync, createSync, createSkeleton } from 'smbls'
60
51
 
61
- ```javascript
52
+ create(App, ctx) // render immediately
53
+ createAsync(App, ctx) // render first, fetch remote config after
54
+ await createSync(App, ctx) // fetch remote config first, then render
55
+ createSkeleton(App, ctx) // resolve extends only, no DOM rendering
56
+ ```
57
+
58
+ ## Themes
59
+
60
+ Themes switch via CSS custom properties — no JavaScript re-renders:
61
+
62
+ ```js
62
63
  init({
63
64
  theme: {
64
65
  document: {
@@ -67,99 +68,109 @@ init({
67
68
  }
68
69
  }
69
70
  })
70
-
71
- // Auto: system preference drives switching
72
- // Force: document.documentElement.dataset.theme = 'dark'
73
- // Custom: add @ocean, @sunset, etc. — activate with data-theme="ocean"
74
71
  ```
75
72
 
76
- ### Create an Application
73
+ - **Auto** follows system preference
74
+ - **Force** — `document.documentElement.dataset.theme = 'dark'`
75
+ - **Custom** — add `@ocean`, `@sunset`, activate with `data-theme="ocean"`
77
76
 
78
- ```javascript
79
- import { create } from 'smbls'
77
+ ## Init options
80
78
 
81
- const App = {
82
- extends: 'Flex',
83
- flow: 'column',
79
+ ```js
80
+ init(config, {
81
+ useVariable: true, // CSS custom properties
82
+ useReset: true, // CSS reset
83
+ useFontImport: true, // @font-face declarations
84
+ useIconSprite: true, // SVG icon sprite
85
+ useDocumentTheme: true, // document-level theme
86
+ globalTheme: 'auto', // 'auto', 'dark', 'light', or custom name
87
+ verbose: false
88
+ })
89
+ ```
84
90
 
85
- Header: {
86
- extends: 'Flex',
87
- H1: { text: 'Hello Symbols!' }
88
- },
91
+ ## Plugins
89
92
 
90
- Main: {
91
- extends: 'Flex',
92
- Button: {
93
- text: 'Get Started',
94
- theme: 'primary'
95
- }
96
- }
97
- }
93
+ domql supports a plugin system via `context.plugins`. Plugins hook into the element lifecycle and can extend how event handlers, props, and metadata are processed.
94
+
95
+ ```js
96
+ import { funcqlPlugin } from '@domql/funcql'
97
+ import { create } from 'smbls'
98
98
 
99
99
  create(App, {
100
- key: 'your-project-key'
100
+ plugins: [funcqlPlugin]
101
101
  })
102
102
  ```
103
103
 
104
- ### Create Variants
104
+ ### Plugin interface
105
105
 
106
- ```javascript
107
- import { create, createAsync, createSync, createSkeleton } from 'smbls'
106
+ A plugin is a plain object with optional lifecycle hooks and a handler resolver:
108
107
 
109
- // Standard — renders immediately
110
- create(App, options)
108
+ ```js
109
+ {
110
+ name: 'my-plugin',
111
111
 
112
- // Asyncrenders first, then fetches remote config
113
- createAsync(App, options)
112
+ // Lifecycle hooks called on every element at each stage
113
+ start (element, options) {},
114
+ init (element, options) {},
115
+ render (element, options) {},
116
+ done (element, options) {},
117
+ create (element, options) {},
118
+ update (element, updatedObj, options) {},
114
119
 
115
- // Sync fetches remote config first, then renders
116
- await createSync(App, options)
117
-
118
- // Skeleton — resolves extends only, no full rendering
119
- createSkeleton(App, options)
120
+ // Resolve non-function event handlers into callable functions
121
+ resolveHandler (handler, element) {}
122
+ }
120
123
  ```
121
124
 
122
- ## Init Options
125
+ ### Available plugins
123
126
 
124
- ```javascript
125
- init(config, {
126
- emotion: customEmotion, // custom Emotion instance
127
- useVariable: true, // inject CSS custom properties
128
- useReset: true, // inject CSS reset
129
- useFontImport: true, // inject @font-face declarations
130
- useIconSprite: true, // create SVG icon sprite
131
- useDocumentTheme: true, // apply document-level theme
132
- useSvgSprite: true, // create SVG sprite sheet
133
- useDefaultConfig: false, // use built-in default config
134
- globalTheme: 'auto', // 'auto' (system preference), 'dark', 'light', or custom theme name
135
- useThemeSuffixedVars: false, // also generate --theme-name-dark-prop vars (opt-in)
136
- verbose: false // enable verbose logging
127
+ | Plugin | Package | Purpose |
128
+ |--------|---------|---------|
129
+ | funcql | `@domql/funcql` | Declare event handlers as JSON schemas instead of functions |
130
+ | helmet | `@symbo.ls/helmet` | SEO metadata via lifecycle hooks |
131
+ | shorthand | `@symbo.ls/shorthand` | Expand abbreviated component definitions |
132
+
133
+ ```js
134
+ import { funcqlPlugin } from '@domql/funcql'
135
+
136
+ create(App, {
137
+ plugins: [funcqlPlugin]
137
138
  })
139
+
140
+ // Now event handlers can be JSON schemas
141
+ const Button = {
142
+ text: 'Play',
143
+ on: {
144
+ click: {
145
+ audio: 'scope.audio',
146
+ if: ['audio.paused', 'audio.play()', 'audio.pause()']
147
+ }
148
+ }
149
+ }
138
150
  ```
139
151
 
140
- ## Additional Exports
152
+ ## Included packages
141
153
 
142
- ```javascript
143
- import {
144
- // Re-initialization
145
- reinit, // re-apply config changes
146
- applyCSS, // inject global CSS
147
- updateVars, // update CSS custom properties
154
+ | Package | Description |
155
+ |---------|-------------|
156
+ | `domql` | Reactive DOM element engine |
157
+ | `@domql/utils` | Utility functions |
158
+ | `@symbo.ls/scratch` | CSS framework |
159
+ | `@symbo.ls/emotion` | Emotion CSS-in-JS integration |
160
+ | `@symbo.ls/default-config` | Default design system configuration |
161
+ | `@symbo.ls/uikit` | UI component library |
162
+ | `@domql/router` | Client-side router |
163
+ | `css-in-props` | CSS properties as component props |
164
+ | `attrs-in-props` | HTML attributes as component props |
148
165
 
149
- // Constants
150
- DEFAULT_CONTEXT,
151
- DESIGN_SYSTEM_OPTIONS,
152
- ROUTER_OPTIONS
153
- } from 'smbls'
154
- ```
166
+ Also includes `@symbo.ls/cli`, `@symbo.ls/fetch`, `@symbo.ls/sync`, and `@symbo.ls/helmet`.
155
167
 
156
- ## Page Metadata
168
+ ## SEO metadata
157
169
 
158
- Define SEO metadata on your app or individual pages. Values can be static or functions:
170
+ Define metadata on your app or pages. Values can be static or functions:
159
171
 
160
- ```javascript
161
- // app.js app-level defaults
162
- export default {
172
+ ```js
173
+ const App = {
163
174
  metadata: {
164
175
  title: 'My App',
165
176
  description: 'Built with Symbols',
@@ -167,78 +178,33 @@ export default {
167
178
  }
168
179
  }
169
180
 
170
- // pages/about.js page-level overrides
171
- export const about = {
181
+ const AboutPage = {
172
182
  metadata: {
173
183
  title: 'About Us',
174
- description: (el, s) => s.aboutDescription
175
- },
176
- // ... page content
184
+ description: (el, s) => s.aboutText
185
+ }
177
186
  }
178
187
  ```
179
188
 
180
- Metadata is applied at runtime (updates `<title>` and `<meta>` tags in the DOM) and during SSR (generates `<head>` HTML via brender). See [`@symbo.ls/helmet`](../../plugins/helmet/) for the full API.
189
+ See [`@symbo.ls/helmet`](../../plugins/helmet/) for the full API.
181
190
 
182
191
  ## CLI
183
192
 
184
- This package also provides the `smbls` CLI binary:
185
-
186
193
  ```bash
187
- smbls init # Initialize a project
188
- smbls start # Start dev server
189
- smbls build # Build for production
190
- smbls deploy # Deploy to hosting
191
- smbls fetch # Fetch remote config
192
- smbls push # Push changes to platform
193
- smbls ask # AI assistant
194
+ smbls init # initialize a project
195
+ smbls start # start dev server
196
+ smbls build # build for production
197
+ smbls fetch # fetch remote config
198
+ smbls push # push changes to platform
199
+ smbls ask # AI assistant
194
200
  ```
195
201
 
196
- See the [@symbo.ls/cli](../cli/) package for the full command reference.
202
+ See [`@symbo.ls/cli`](../cli/) for the full command reference.
197
203
 
198
204
  ## Documentation
199
205
 
200
- ## Define System
201
-
202
- The define system (`context.define` and `element.define`) maps special keys to handler functions. When a key with a matching define handler appears on an element, `throughInitialDefine` calls the handler instead of treating the key as a child or prop.
203
-
204
- ### Built-in define handlers (in `defaultDefine`)
205
-
206
- | Key | Purpose |
207
- |-----|---------|
208
- | `routes` | Route definitions — passed through as-is |
209
- | `metadata` | SEO metadata — resolves and applies `<title>` and `<meta>` tags via helmet |
210
- | `$router` | Router content — wraps params in a fragment and calls `el.set()` |
211
-
212
- ### Collection define handlers (deprecated in v3)
213
-
214
- The following collection define handlers existed in v2 but are **deprecated in v3**:
215
-
216
- | Key (deprecated) | Data source | v3 replacement |
217
- |-------------------|-------------|----------------|
218
- | `$collection` | Direct data array/object | Use `children` + `childExtends` |
219
- | `$propsCollection` | `element.props` as data source | Use `children: ({ props }) => props.items` |
220
- | `$stateCollection` | `element.state` as data source | Use `children: ({ state }) => state.items` |
221
- | `$setCollection` | Uses `set()` to update content | Use `content` or `children` |
222
-
223
- Some older projects still use these handlers via project-level `context.define`. The framework's propertization layer (`@domql/utils/props.js`) is define-aware to avoid moving these keys into `props` when define handlers are present.
206
+ [symbols.app/developers](https://symbols.app/developers)
224
207
 
225
- > **Lesson learned:** The `$` prefix overlaps between css-in-props selectors and define handlers. The propertization in `props.js` checks for define handlers before applying `CSS_SELECTOR_PREFIXES` to prevent define keys from being swallowed into props. This matters for backwards compatibility with v2 projects that still use `$propsCollection` etc.
226
-
227
- ## Emotion Integration (`prepare.js`)
228
-
229
- `prepareDesignSystem()` calls `initEmotion()` from `@symbo.ls/emotion/initEmotion.js` to initialize the CSS-in-JS engine. This import must be present for Emotion to work.
230
-
231
- ```javascript
232
- import { initEmotion } from '@symbo.ls/emotion/initEmotion.js'
233
-
234
- export const prepareDesignSystem = (key, context) => {
235
- const [scratchDesignSystem, emotion, registry] = initEmotion(key, context)
236
- return [scratchDesignSystem, emotion, registry]
237
- }
238
- ```
239
-
240
- > **Lesson learned:** If the `initEmotion` import is missing or broken, no CSS classes are generated and components render unstyled (Bazaar rendering issue).
241
-
242
- ## Documentation
208
+ ## License
243
209
 
244
- For full documentation visit [symbols.app/developers](https://symbols.app/developers).
210
+ CC-BY-NC-4.0