@mintjamsinc/ichigojs 0.1.76 → 0.1.77

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
@@ -959,18 +959,143 @@ defineComponent('my-list', {
959
959
 
960
960
  **Props:**
961
961
 
962
- - Declared via the `props` array. Each declared prop becomes a property on the
963
- custom element, so the parent can bind to it with `v-bind` / `:`
964
- (e.g. `:items="searchResults"`).
962
+ - Declared via the `props` array, or as a record with per-prop options:
963
+
964
+ ```javascript
965
+ defineComponent('my-badge', {
966
+ template: '#my-badge',
967
+ props: {
968
+ label: { type: String, default: 'none' },
969
+ count: { type: Number, default: 0, validator: v => v >= 0 },
970
+ items: { type: Array, default: () => [] }, // Object/Array: use a factory
971
+ target: { required: true }, // any type, but must be provided
972
+ },
973
+ });
974
+ ```
975
+
976
+ - Each declared prop becomes a property on the custom element, so the parent
977
+ can bind to it with `v-bind` / `:` (e.g. `:items="searchResults"`).
978
+ - `type`, `required` and `validator` are development aids: violations log a
979
+ console warning, but the value is always delivered as-is (same philosophy as
980
+ `emits`).
981
+ - `default` is applied when the prop is `undefined` at mount time, or when the
982
+ parent later assigns `undefined`. `null` passes through as an explicit
983
+ "no value". A function default is called as a factory unless `type` includes
984
+ `Function`.
985
+ - A component with declared props always mounts: values bound by the parent are
986
+ delivered first, and a component used without any binding mounts with its
987
+ declared defaults.
988
+ - Plain HTML attributes work as a fallback for props that receive no property
989
+ value (e.g. `<my-badge label="hi" count="3">`; kebab-case matches camelCase
990
+ prop names). Attribute values are strings, except that a declared `Boolean`
991
+ type turns attribute presence into `true` and a declared `Number` type parses
992
+ numeric strings.
965
993
  - Props are reactive from the start and are included in the component's data
966
994
  automatically. Values returned from `data()` take precedence, allowing you to
967
995
  default or transform a prop (e.g. `this.items ?? []`).
968
996
 
997
+ > ⚠️ **Object props are shared references** (same as Vue): when the parent
998
+ > passes an object or array, the component receives the parent's reactive proxy
999
+ > itself. Mutating a nested property from inside the component
1000
+ > (e.g. `this.user.name = '...'`) also updates the parent's state. Reassigning
1001
+ > the prop itself (`this.user = {...}`) stays local to the component and does
1002
+ > not affect the parent. Treat props as read-only and notify the parent with
1003
+ > `$emit` when a change is intended.
1004
+
969
1005
  **Slots:**
970
1006
 
971
1007
  Use the native `<slot>` element in the component template to project content
972
1008
  from the parent. ichigo.js components use Light DOM.
973
1009
 
1010
+ ### Scoped slots
1011
+
1012
+ A scoped slot lets the parent supply a template for content that the component
1013
+ renders with its own data — e.g. the rows of a list or tree. The component
1014
+ passes slot props by binding values on the `<slot>` outlet; the parent declares
1015
+ a `<template v-slot:name="scopeVar">` and receives those values under the
1016
+ scope variable:
1017
+
1018
+ ```html
1019
+ <!-- Component template: bind slot props on the outlet -->
1020
+ <template id="my-tree">
1021
+ <ul>
1022
+ <li v-for="(node, i) of items">
1023
+ <slot name="item" :node="node" :index="i">
1024
+ <span>{{ node.label }}</span> <!-- fallback content -->
1025
+ </slot>
1026
+ </li>
1027
+ </ul>
1028
+ </template>
1029
+
1030
+ <!-- Usage: slot content sees the PARENT scope plus the scope variable -->
1031
+ <my-tree :items="nodes">
1032
+ <template v-slot:item="row">
1033
+ <b>{{ row.node.label }}</b> <i>#{{ row.index }}</i>
1034
+ <my-badge v-if="row.node.count > 0" :value="row.node.count" @picked="onPicked"></my-badge>
1035
+ </template>
1036
+ </my-tree>
1037
+ ```
1038
+
1039
+ - Slot content is compiled in the **parent scope** (where it was authored),
1040
+ extended with the slot props under the scope variable — Vue semantics. A
1041
+ scope variable shadows a parent binding of the same name.
1042
+ - `#item="row"` is a shorthand for `v-slot:item="row"`. `v-slot="row"`
1043
+ (no name) targets the default `<slot>`.
1044
+ - The scope variable must be a **single identifier** — destructuring
1045
+ (`v-slot:item="{ node }"`) is not supported.
1046
+ - The scoped template replaces the outlet's fallback content; without a
1047
+ matching `v-slot` template, the fallback renders in the component scope as
1048
+ before. Static slot content (`slot="name"` attribute) coexists with scoped
1049
+ templates.
1050
+ - Slot content may freely use directives and other components. Parent-side
1051
+ data changes and component-side slot-prop changes both propagate.
1052
+
1053
+ ### v-model on components
1054
+
1055
+ A component can support `v-model` by accepting a `modelValue` prop and
1056
+ emitting an `update:modelValue` event with the new value as the payload
1057
+ (Vue 3 convention):
1058
+
1059
+ ```html
1060
+ <template id="my-input">
1061
+ <label>
1062
+ {{ label }}
1063
+ <input :value="modelValue"
1064
+ @input="$emit('update:modelValue', $event.target.value)">
1065
+ </label>
1066
+ </template>
1067
+ ```
1068
+
1069
+ ```javascript
1070
+ defineComponent('my-input', {
1071
+ template: '#my-input',
1072
+ props: {
1073
+ modelValue: { default: '' },
1074
+ label: { default: '' },
1075
+ },
1076
+ });
1077
+ ```
1078
+
1079
+ ```html
1080
+ <my-input v-model="name" :label="'Name'"></my-input>
1081
+ ```
1082
+
1083
+ - `v-model:arg` targets a different prop/event pair — `v-model:size="w"` binds
1084
+ prop `size` and listens for `update:size`. Multiple `v-model:arg` bindings on
1085
+ one component are allowed. HTML attribute names are lowercased by the
1086
+ browser, so address a camelCase prop with kebab-case
1087
+ (`v-model:user-name` → prop `userName`, event `update:userName`).
1088
+ - The `.trim` and `.number` modifiers apply to the emitted payload. `.lazy` has
1089
+ no effect on components (the component decides when to emit) and logs a
1090
+ development warning.
1091
+ - `update:*` events are always allowed regardless of the `emits` declaration.
1092
+ - Emit `update:*` events with the default `$emit` target (the component's root
1093
+ element). The listener attached by `v-model` only accepts events emitted by
1094
+ the component itself, so an `update:modelValue` from a nested component
1095
+ bubbling through does not corrupt the outer binding.
1096
+ - The convention works for any custom element that follows it, not only
1097
+ ichigo.js components.
1098
+
974
1099
  ### Events (`$emit`)
975
1100
 
976
1101
  Components (and applications) can dispatch custom events with `$emit`, which is
@@ -1086,7 +1211,10 @@ Creates a new application instance.
1086
1211
  - `emits`: Optional array of event names the app/component is expected to emit via `$emit`. Emitting an undeclared event logs a development warning (validation only).
1087
1212
  - `logLevel`: Logging level (`'debug'` | `'info'` | `'warn'` | `'error'`)
1088
1213
 
1089
- **Returns:** Application instance with `mount(selector)` method
1214
+ **Returns:** Application instance with `mount(selector)` method.
1215
+ `mount()` returns the application instance itself, so
1216
+ `const app = VDOM.createApp({...}).mount('#app')` keeps a handle for later use
1217
+ (e.g. `app.unmount()`).
1090
1218
 
1091
1219
  **Instance helpers** (available in `data()`, methods, expressions, and lifecycle hooks as appropriate):
1092
1220
 
@@ -1103,7 +1231,9 @@ Defines and registers a custom element backed by ichigo.js reactivity. See [Comp
1103
1231
  **Options** (extends the `createApp` options above):
1104
1232
 
1105
1233
  - `template`: CSS selector for the `<template>` element that defines the component's markup (required)
1106
- - `props`: Array of property names received from the parent via attribute/property binding
1234
+ - `props`: Props received from the parent — either an array of names, or a record
1235
+ of per-prop options (`type` / `default` / `required` / `validator`).
1236
+ See [Components — Props](#components).
1107
1237
 
1108
1238
  **Returns:** `void` (the custom element is registered via `customElements.define`)
1109
1239