@octane-xplat/macos-renderer 0.12.0 → 0.13.0

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
@@ -9,12 +9,13 @@ Your application owns startup, windows, menus, host services, and custom font
9
9
  assets. The renderer owns views, layout, events, accessibility, and its hosted
10
10
  popups and sheets. It does not load web stylesheets or implement every
11
11
  NativeScript widget. See the [macOS harness](../../apps/macos/README.md) for
12
- the current component and service limits. The image-crop integration test compiles and mounts the public UI barrel.
13
- The full application harness has not been reverified by that test. Registered
14
- action selectors match the assigned target/action strings, and the maintained
15
- consumer checks direct handler dispatch — but OS-level input delivery (a live
12
+ the current component and service limits.
13
+
14
+ Verification status: the image-crop integration test compiles and mounts the
15
+ public UI barrel, and registered action selectors match their target/action
16
+ strings through direct handler dispatch. OS-level input delivery (a live
16
17
  AppKit `performClick`, control edits, gestures) has not been verified end to
17
- end.
18
+ end, and the full application harness has not been reverified by that test.
18
19
 
19
20
  ## Configure an app
20
21
 
@@ -373,5 +374,4 @@ The packed check uses the renderer and CLI tarballs in a temporary app outside
373
374
  the checkout. It checks declarations and production compilation on every
374
375
  host; on Apple Silicon macOS it also packages and launches the app and verifies
375
376
  retained-root HMR. Programmatic action dispatch establishes handler behavior,
376
- not OS input or hit-testing. Publication requires the repository's normal
377
- [npm bootstrap and trusted-publisher setup](../../.agents/docs/releases.md).
377
+ not OS input or hit-testing.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octane-xplat/macos-renderer",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Experimental AppKit renderer for Octane on macOS",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/index.ts CHANGED
@@ -1484,6 +1484,7 @@ function pinLayoutChild(
1484
1484
  const mark = () => {
1485
1485
  parentView.needsLayout = true
1486
1486
  }
1487
+
1487
1488
  if (typeof queueMicrotask === 'function') {
1488
1489
  queueMicrotask(mark)
1489
1490
  } else {
@@ -2497,10 +2498,47 @@ function applyStyle(node: ElementNode, style: PropBag) {
2497
2498
  syncStackLayout(node)
2498
2499
  }
2499
2500
 
2501
+ // `className` composes clsx-style on the DOM renderer and the NativeScript
2502
+ // driver; this mirrors octane's `normalizeClass` (native dist must not import
2503
+ // bare `octane`, and peers older than 0.11 predate the export) so a
2504
+ // declarative array or object reaches the tokenizer instead of String(value)'s
2505
+ // comma-join.
2506
+ function normalizeClass(value: any): string {
2507
+ if (typeof value === 'string') {
2508
+ return value
2509
+ }
2510
+
2511
+ if (typeof value !== 'object') {
2512
+ return typeof value === 'number' && value ? '' + value : ''
2513
+ }
2514
+
2515
+ if (value === null) {
2516
+ return ''
2517
+ }
2518
+
2519
+ let str = ''
2520
+ if (Array.isArray(value)) {
2521
+ for (const item of value) {
2522
+ if (item) {
2523
+ const inner = normalizeClass(item)
2524
+ if (inner) {
2525
+ str = str ? str + ' ' + inner : inner
2526
+ }
2527
+ }
2528
+ }
2529
+ } else {
2530
+ for (const key in value) {
2531
+ if (value[key]) {
2532
+ str = str ? str + ' ' + key : key
2533
+ }
2534
+ }
2535
+ }
2536
+
2537
+ return str
2538
+ }
2539
+
2500
2540
  function applyClassName(node: ElementNode, value: any) {
2501
- const classes = String(value ?? '')
2502
- .split(/\s+/)
2503
- .filter(Boolean)
2541
+ const classes = normalizeClass(value).split(/\s+/).filter(Boolean)
2504
2542
 
2505
2543
  // Class effects re-derive from scratch on every apply: the class-owned
2506
2544
  // fields reset here and re-populate below, so removing a class drops the
@@ -3802,9 +3840,7 @@ const macOSDriver: UniversalHostDriver<RootContainer, any> = {
3802
3840
  const round = (value: number) => Math.round(value * 100) / 100
3803
3841
 
3804
3842
  function nodeClasses(node: ElementNode) {
3805
- return String(node.props?.className ?? '')
3806
- .split(/\s+/)
3807
- .filter(Boolean)
3843
+ return normalizeClass(node.props?.className).split(/\s+/).filter(Boolean)
3808
3844
  }
3809
3845
 
3810
3846
  function descendants(node: ElementNode, out: ElementNode[] = []) {