@octane-xplat/date-picker 0.14.0 → 0.16.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octane-xplat/date-picker",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "description": "Platform-specific date and time selection controls for Octane xplat",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,26 +8,27 @@
8
8
  "directory": "packages/date-picker"
9
9
  },
10
10
  "files": [
11
- "dist",
12
11
  "types",
13
12
  "src",
14
- "platforms"
13
+ "platforms",
14
+ "!src/**/*.test.*",
15
+ "!src/**/*.spec.*"
15
16
  ],
16
17
  "type": "module",
17
18
  "exports": {
18
19
  ".": {
19
20
  "types": "./types/index.d.ts",
20
- "web": "./dist/native/index.js",
21
- "native": "./dist/native/index.js",
22
- "default": "./dist/native/index.js"
21
+ "web": "./src/index.ts",
22
+ "native": "./src/index.ts",
23
+ "default": "./src/index.ts"
23
24
  },
24
25
  "./ios": {
25
26
  "types": "./types/ios/index.d.ts",
26
- "native": "./dist/native/ios/index.js"
27
+ "native": "./src/ios/index.ts"
27
28
  },
28
29
  "./android": {
29
30
  "types": "./types/android/index.d.ts",
30
- "native": "./dist/native/android/index.js"
31
+ "native": "./src/android/index.ts"
31
32
  },
32
33
  "./macos": {
33
34
  "types": "./types/macos/index.d.ts",
@@ -42,11 +43,12 @@
42
43
  "@nativescript/swift-ui": "4.0.2"
43
44
  },
44
45
  "devDependencies": {
45
- "@nativescript-community/octane": "0.2.4",
46
+ "@nativescript-community/octane": "0.2.5",
46
47
  "@nativescript/core": "9.1.3",
47
- "@octanejs/vite-plugin": "0.1.60",
48
- "octane": "0.5.0",
49
- "tsrx-typegen": "0.2.2",
48
+ "@octane-xplat/macos-renderer": "0.16.0",
49
+ "@octanejs/vite-plugin": "0.1.61",
50
+ "octane": "0.11.0",
51
+ "tsrx-typegen": "0.3.1",
50
52
  "typescript": "5.9.3",
51
53
  "vite": "8.3.0"
52
54
  },
@@ -73,8 +75,8 @@
73
75
  }
74
76
  },
75
77
  "scripts": {
76
- "build": "vite build --mode native && tsc -p tsconfig.types.json",
77
78
  "test:packed": "node tests/packed-consumer.mjs",
78
- "pack:check": "tsrx-typegen --pack-check"
79
+ "pack:check": "tsrx-typegen --pack-check",
80
+ "typegen": "tsc -p tsconfig.types.json"
79
81
  }
80
82
  }
@@ -21,6 +21,8 @@ import androidx.compose.material3.TimePicker
21
21
  import androidx.compose.material3.TimePickerDefaults
22
22
  import androidx.compose.material3.TimePickerLayoutType
23
23
  import androidx.compose.material3.TimePickerState
24
+ import androidx.compose.material3.darkColorScheme
25
+ import androidx.compose.material3.lightColorScheme
24
26
  import androidx.compose.runtime.Composable
25
27
  import androidx.compose.runtime.CompositionLocalProvider
26
28
  import androidx.compose.runtime.LaunchedEffect
@@ -32,6 +34,7 @@ import androidx.compose.ui.Modifier
32
34
  import androidx.compose.ui.graphics.Color
33
35
  import androidx.compose.ui.platform.ComposeView
34
36
  import androidx.compose.ui.platform.LocalConfiguration
37
+ import androidx.compose.foundation.isSystemInDarkTheme
35
38
  import org.json.JSONObject
36
39
  import java.util.Calendar
37
40
  import java.util.Date
@@ -47,8 +50,18 @@ private fun Any?.asLong(): Long? = when (this) {
47
50
  else -> null
48
51
  }
49
52
 
53
+ // android.graphics.Color.parseColor only accepts #RRGGBB/#AARRGGBB (and
54
+ // named colors); the elementColors doc also advertises the CSS-style #rgb
55
+ // shorthand — expand it so a documented value doesn't silently fall back.
56
+ private fun expandShortHex(value: String): String =
57
+ if (value.length == 4 && value.startsWith('#')) {
58
+ "#" + value.substring(1).map { "$it$it" }.joinToString("")
59
+ } else {
60
+ value
61
+ }
62
+
50
63
  private fun Any?.asColor(): Color? = when (this) {
51
- is String -> runCatching { Color(android.graphics.Color.parseColor(this)) }.getOrNull()
64
+ is String -> runCatching { Color(android.graphics.Color.parseColor(expandShortHex(this))) }.getOrNull()
52
65
  else -> null
53
66
  }
54
67
 
@@ -116,12 +116,16 @@ public final class XplatDatePickerProvider: UIViewController, SwiftUIProvider {
116
116
  }
117
117
 
118
118
  public func updateData(data: NSDictionary) {
119
- if let title = data["title"] as? String {
120
- model.title = title.isEmpty ? nil : title
121
- }
122
- if let selection = data["selection"] as? NSNumber {
123
- model.selection = Date(timeIntervalSince1970: selection.doubleValue / 1000)
119
+ // dataSerialize drops undefined keys — an absent key is a revert to
120
+ // the unset state, not "leave the previous value".
121
+ if data.object(forKey: "title") == nil {
122
+ model.title = nil
123
+ } else {
124
+ let title = data["title"] as? String
125
+ model.title = title?.isEmpty == false ? title : nil
124
126
  }
127
+ model.selection = Self.millisToDate(data["selection"])
128
+
125
129
  if let range = data["range"] as? [String: Any] {
126
130
  model.rangeStart = Self.millisToDate(range["start"])
127
131
  model.rangeEnd = Self.millisToDate(range["end"])
@@ -15,9 +15,9 @@ export function AppKitDatePicker(props: AppKitDatePickerProps) @{
15
15
  const handle = useRef<any>(null)
16
16
 
17
17
  const options = () => ({
18
- mode: props.components === 'time' ? 'time' : 'date',
18
+ mode: props.components,
19
19
  style: props.pickerStyle,
20
- selectionMillis: (props.selection ?? props.defaultSelection)?.getTime?.(),
20
+ selectionMillis: props.selection?.getTime?.(),
21
21
  minimumMillis: props.minimumDate?.getTime?.(),
22
22
  maximumMillis: props.maximumDate?.getTime?.(),
23
23
  enabled: !props.disabled,
@@ -27,9 +27,15 @@ export function AppKitDatePicker(props: AppKitDatePickerProps) @{
27
27
  const view = anchor.current
28
28
  const attach = host().attachDatePicker
29
29
  if (!view || typeof attach !== 'function') return
30
- handle.current = attach(view, options(), (millis: number) => {
31
- props.onSelectionChange?.(new Date(millis))
32
- })
30
+ // defaultSelection seeds the initial date; after that the user's
31
+ // pick owns the value — only the controlled `selection` is pushed.
32
+ handle.current = attach(
33
+ view,
34
+ { ...options(), selectionMillis: (props.selection ?? props.defaultSelection)?.getTime?.() },
35
+ (millis: number) => {
36
+ props.onSelectionChange?.(new Date(millis))
37
+ },
38
+ )
33
39
 
34
40
  return () => {
35
41
  handle.current?.detach()
@@ -43,14 +49,9 @@ export function AppKitDatePicker(props: AppKitDatePickerProps) @{
43
49
  handle.current?.update(options())
44
50
  })
45
51
 
46
- <flexboxlayout
47
- ref={(v: any) => { anchor.current = v }}
48
- id={props.id}
49
- className={props.className}
50
- style={{
52
+ <masonview ref={(v: any) => { anchor.current = v }} id={props.id} className={props.className} style={{display: "flex", ...({
51
53
  minWidth: 240,
52
54
  minHeight: props.pickerStyle === 'graphical' ? 300 : 26,
53
55
  ...props.style,
54
- }}
55
- />;
56
+ })}}/>;
56
57
  }
@@ -1,46 +0,0 @@
1
- import { defineUniversalComponent, registerElement, universalPlan, universalValue } from "@nativescript-community/octane";
2
- import { ComposeDataDriver, JetpackCompose, registerJetpackCompose } from "@nativescript/jetpack-compose";
3
- //#region src/MaterialDatePicker.android.tsrx
4
- var __octaneUniversalPlan0 = universalPlan("nativescript", {
5
- "kind": "host",
6
- "type": "xplatandroiddatepicker",
7
- "props": { "composeId": "xplat-material-datepicker" },
8
- "bindings": [
9
- ["id", 0],
10
- ["className", 1],
11
- ["style", 2],
12
- ["accessibilityLabel", 3],
13
- ["data", 4],
14
- ["onComposeEvent", 5]
15
- ]
16
- });
17
- registerElement("xplatandroiddatepicker", JetpackCompose);
18
- registerJetpackCompose("xplat-material-datepicker", (owner) => new ComposeDataDriver(new com.octanexplat.datepicker.XplatDatePickerProvider(), owner));
19
- var MaterialDatePicker = defineUniversalComponent("nativescript", function MaterialDatePicker(props) {
20
- const data = {
21
- initialDate: props.initialDate?.getTime() ?? null,
22
- variant: props.variant ?? "picker",
23
- displayedComponents: props.displayedComponents ?? "date",
24
- showVariantToggle: props.showVariantToggle ?? true ? 1 : 0,
25
- is24Hour: props.is24Hour ?? true ? 1 : 0,
26
- color: props.color,
27
- elementColors: props.elementColors,
28
- selectableDates: {
29
- start: props.selectableDates?.start?.getTime() ?? null,
30
- end: props.selectableDates?.end?.getTime() ?? null
31
- }
32
- };
33
- return universalValue(__octaneUniversalPlan0, [
34
- props.id,
35
- props.className,
36
- props.style,
37
- props.accessibilityLabel,
38
- data,
39
- (event) => {
40
- const millis = event.data?.date;
41
- props.onDateSelected?.(typeof millis === "number" ? new Date(millis) : null);
42
- }
43
- ]);
44
- }, { "module": "@nativescript-community/octane" });
45
- //#endregion
46
- export { MaterialDatePicker };
@@ -1,48 +0,0 @@
1
- import { defineUniversalComponent, hookSlots, registerElement, universalPlan, universalValue, useState } from "@nativescript-community/octane";
2
- import { SwiftUI, UIDataDriver, registerSwiftUI } from "@nativescript/swift-ui";
3
- //#region src/SwiftUIDatePicker.ios.tsrx
4
- var _h$0 = /* @__PURE__ */ Symbol(/* @__PURE__ */ hookSlots(1));
5
- var __octaneUniversalPlan0 = universalPlan("nativescript", {
6
- "kind": "host",
7
- "type": "xplatiosdatepicker",
8
- "props": { "swiftId": "xplat-swiftui-datepicker" },
9
- "bindings": [
10
- ["id", 0],
11
- ["className", 1],
12
- ["style", 2],
13
- ["data", 3],
14
- ["onSwiftUIEvent", 4]
15
- ]
16
- });
17
- registerElement("xplatiosdatepicker", SwiftUI);
18
- registerSwiftUI("xplat-swiftui-datepicker", (owner) => new UIDataDriver(new XplatDatePickerProvider(), owner));
19
- var SwiftUIDatePicker = defineUniversalComponent("nativescript", function SwiftUIDatePicker(props) {
20
- const controlled = props.selection !== void 0;
21
- const [internalSelection, setInternalSelection] = useState(props.defaultSelection, _h$0);
22
- const selection = controlled ? props.selection : internalSelection;
23
- return universalValue(__octaneUniversalPlan0, [
24
- props.id,
25
- props.className,
26
- props.style,
27
- {
28
- title: props.title,
29
- selection: selection?.getTime(),
30
- range: {
31
- start: props.minimumDate?.getTime(),
32
- end: props.maximumDate?.getTime()
33
- },
34
- displayedComponents: props.displayedComponents ?? ["date"],
35
- pickerStyle: props.pickerStyle ?? "automatic",
36
- disabled: props.disabled ?? false
37
- },
38
- (event) => {
39
- const millis = event.data?.date;
40
- if (typeof millis !== "number") return;
41
- const next = new Date(millis);
42
- if (!controlled) setInternalSelection(next);
43
- props.onSelectionChange?.(next);
44
- }
45
- ]);
46
- }, { "module": "@nativescript-community/octane" });
47
- //#endregion
48
- export { SwiftUIDatePicker };
@@ -1,2 +0,0 @@
1
- import { MaterialDatePicker } from "../MaterialDatePicker.android.tsrx.js";
2
- export { MaterialDatePicker };
File without changes
@@ -1,2 +0,0 @@
1
- import { SwiftUIDatePicker } from "../SwiftUIDatePicker.ios.tsrx.js";
2
- export { SwiftUIDatePicker };
@@ -1,8 +0,0 @@
1
- {
2
- "version": 1,
3
- "buildId": "8d8fb4a1-69e7-4d76-9401-ad577ac00c0d",
4
- "mode": "production",
5
- "capabilities": {
6
- "independentHydration": false
7
- }
8
- }