@solidrt/components 0.0.3 → 0.0.5

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
@@ -8,6 +8,10 @@ A collection of components for [SolidRT](https://github.com/wellawaretech/solidr
8
8
  bun add @solidrt/components
9
9
  ```
10
10
 
11
+ ## Theming
12
+
13
+ Appearance (colors, spacing, border, font size) is controlled via the shared theme. Call `setTheme` from `@solidrt/components` to override defaults.
14
+
11
15
  ## Components
12
16
 
13
17
  ### SafeArea
@@ -19,8 +23,8 @@ import { SafeArea } from "@solidrt/components"
19
23
 
20
24
  function App() {
21
25
  return (
22
- <window flexDirection="column">
23
- <SafeArea>
26
+ <window>
27
+ <SafeArea top bottom>
24
28
  <text>Content clear of system UI</text>
25
29
  </SafeArea>
26
30
  </window>
@@ -28,17 +32,32 @@ function App() {
28
32
  }
29
33
  ```
30
34
 
35
+ Top and bottom insets are applied by default. Pass `false` to opt out of an edge, or a number to apply the inset with a minimum padding.
36
+
37
+ ```jsx
38
+ // top only
39
+ <SafeArea bottom={false}>
40
+
41
+ // apply top and bottom insets, with a minimum of 16px each
42
+ <SafeArea top={16} bottom={16}>
43
+
44
+ // all four edges
45
+ <SafeArea top bottom left right>
46
+ ```
47
+
31
48
  **Props**
32
49
 
33
- | Prop | Type | Default | Description |
34
- | ---------- | -------------------------------------------- | ------------------- | -------------------------------------------------------------- |
35
- | `edges` | `("top" \| "bottom" \| "left" \| "right")[]` | `["top", "bottom"]` | Which edges to apply safe area insets on |
36
- | `minimum` | `number` | `0` | Minimum padding applied even if the safe area inset is smaller |
37
- | `children` | `any` | - | Content to render inside the safe area |
50
+ | Prop | Type | Default | Description |
51
+ | ---------- | ------------------- | ------- | --------------------------------------------------- |
52
+ | `top` | `boolean \| number` | `true` | Apply top inset. A number sets the minimum padding. |
53
+ | `bottom` | `boolean \| number` | `true` | Apply bottom inset. A number sets the minimum padding. |
54
+ | `left` | `boolean \| number` | `false` | Apply left inset. A number sets the minimum padding. |
55
+ | `right` | `boolean \| number` | `false` | Apply right inset. A number sets the minimum padding. |
56
+ | `children` | `any` | - | Content to render inside the safe area. |
38
57
 
39
58
  ### TextInput
40
59
 
41
- Single-line text input. Tapping/clicking the field focuses it; the OS-level text input (and on-screen keyboard, where applicable) is activated automatically while focused. Printable text arrives via the platform `textInput` event (post-IME commit). V1 supports caret-at-end editing only: no selection, no mid-string cursor movement.
60
+ Single-line text input.
42
61
 
43
62
  ```jsx
44
63
  import { TextInput } from "@solidrt/components"
@@ -60,29 +79,39 @@ function NameField() {
60
79
 
61
80
  **Props**
62
81
 
63
- | Prop | Type | Default | Description |
64
- | ------------------ | -------------------------- | ------------------ | ------------------------------------------------------------ |
65
- | `value` | `string` | - | Controlled value. If omitted, the component is uncontrolled. |
66
- | `defaultValue` | `string` | `""` | Initial value for uncontrolled use |
67
- | `onInput` | `(value: string) => void` | - | Fires on every change |
68
- | `onSubmit` | `(value: string) => void` | - | Fires on Enter |
69
- | `onFocus` | `() => void` | - | Fires when the field gains focus |
70
- | `onBlur` | `() => void` | - | Fires when the field loses focus |
71
- | `placeholder` | `string` | - | Shown when value is empty and the field is not focused |
72
- | `maxLength` | `number` | - | Truncates input to this length |
73
- | `disabled` | `boolean` | `false` | Ignores pointer and key events when true |
74
- | `autoFocus` | `boolean` | `false` | Focuses on mount |
75
- | `fontSize` | `number` | `14` | Text size |
76
- | `color` | `string` | `"black"` | Text color |
77
- | `placeholderColor` | `string` | `"rgba(0,0,0,.4)"` | Placeholder color |
78
- | `background` | `string` | `"white"` | Background fill color |
79
- | `borderColor` | `string` | `"rgba(0,0,0,.2)"` | Border stroke color |
80
- | `borderWidth` | `number` | `1` | Border stroke width |
81
- | `borderRadius` | `number` | `4` | Corner radius |
82
- | `caretColor` | `string` | same as `color` | Caret color |
83
- | `padding` | `number` | `8` | Horizontal padding |
84
- | `width` | `number \| "auto" \| "N%"` | - | Field width |
85
- | `height` | `number` | `32` | Field height |
82
+ | Prop | Type | Default | Description |
83
+ | -------------- | -------------------------- | ------- | ------------------------------------------------------------ |
84
+ | `value` | `string` | - | Controlled value. If omitted, the component is uncontrolled. |
85
+ | `defaultValue` | `string` | `""` | Initial value for uncontrolled use |
86
+ | `onInput` | `(value: string) => void` | - | Fires on every change |
87
+ | `onSubmit` | `(value: string) => void` | - | Fires on Enter |
88
+ | `onFocus` | `() => void` | - | Fires when the field gains focus |
89
+ | `onBlur` | `() => void` | - | Fires when the field loses focus |
90
+ | `placeholder` | `string` | - | Shown when value is empty and the field is not focused |
91
+ | `maxLength` | `number` | - | Truncates input to this length |
92
+ | `disabled` | `boolean` | `false` | Ignores pointer and key events when true |
93
+ | `autoFocus` | `boolean` | `false` | Focuses on mount |
94
+ | `width` | `number \| "auto" \| "N%"` | - | Field width |
95
+
96
+ ### Image
97
+
98
+ Loads and displays an image from a URL or raw bytes.
99
+
100
+ ```jsx
101
+ import { Image } from "@solidrt/components"
102
+
103
+ function Avatar() {
104
+ return <Image src="https://example.com/avatar.png" width={64} height={64} />
105
+ }
106
+ ```
107
+
108
+ **Props**
109
+
110
+ Accepts all layout, transform, and pointer event props, plus:
111
+
112
+ | Prop | Type | Description |
113
+ | ----- | ---------------------- | -------------------------------------------- |
114
+ | `src` | `string \| Uint8Array` | URL to fetch, or raw image bytes to decode |
86
115
 
87
116
  ## License
88
117
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidrt/components",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "license": "MIT",
5
5
  "author": "Antoine van Wel",
6
6
  "type": "module",
@@ -15,6 +15,6 @@
15
15
  ],
16
16
  "peerDependencies": {
17
17
  "@solidjs/signals": "2.0.0-beta.13",
18
- "@solidrt/core": "0.0.3"
18
+ "@solidrt/core": "0.0.5"
19
19
  }
20
20
  }
package/src/image.tsx ADDED
@@ -0,0 +1,66 @@
1
+ import { createSignal, onCleanup } from "@solidjs/signals"
2
+ import { decodeImage, createTexture } from "@solidrt/core/gpu"
3
+ import type { LayoutProps, TransformProps, PointerProps } from "@solidrt/core"
4
+
5
+ export interface ImageProps extends LayoutProps, TransformProps, PointerProps {
6
+ src: string | Uint8Array
7
+ }
8
+
9
+ //TODO onLoad, onError
10
+ //TODO release texture in onCleanup
11
+ //TODO forward all LayoutProps (currently only the common subset)
12
+ export function Image(props: ImageProps) {
13
+ let [res] = createSignal(async () => {
14
+ let bytes: Uint8Array
15
+ if (typeof props.src === "string") {
16
+ let response = await fetch(props.src)
17
+ bytes = await response.bytes()
18
+ } else {
19
+ bytes = props.src
20
+ }
21
+ let { data, width, height } = decodeImage(bytes)
22
+ let id = createTexture(data, width, height)
23
+ return { id, width, height }
24
+ })
25
+
26
+ let src = () => res()?.id
27
+
28
+ onCleanup(() => {
29
+ //TODO release texture
30
+ })
31
+
32
+ return (
33
+ <view
34
+ width={props.width}
35
+ height={props.height}
36
+ flex={props.flex}
37
+ flexGrow={props.flexGrow}
38
+ flexShrink={props.flexShrink}
39
+ alignSelf={props.alignSelf}
40
+ margin={props.margin}
41
+ marginTop={props.marginTop}
42
+ marginBottom={props.marginBottom}
43
+ marginLeft={props.marginLeft}
44
+ marginRight={props.marginRight}
45
+ padding={props.padding}
46
+ position={props.position}
47
+ top={props.top}
48
+ right={props.right}
49
+ bottom={props.bottom}
50
+ left={props.left}
51
+ x={props.x}
52
+ y={props.y}
53
+ scale={props.scale}
54
+ rotate={props.rotate}
55
+ onPointerEnter={props.onPointerEnter}
56
+ onPointerLeave={props.onPointerLeave}
57
+ onPointerDown={props.onPointerDown}
58
+ onPointerUp={props.onPointerUp}
59
+ onPointerMove={props.onPointerMove}
60
+ onWheel={props.onWheel}
61
+ pointerEvents={props.pointerEvents}
62
+ >
63
+ <texture src={src()} />
64
+ </view>
65
+ )
66
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { Image, type ImageProps } from "./image"
1
2
  export { SafeArea } from "./safe-area"
2
3
  export { TextInput, type TextInputProps } from "./text-input"
3
4
  export { theme, setTheme, type Theme } from "./theme"
package/src/safe-area.tsx CHANGED
@@ -2,8 +2,10 @@ import { createSignal } from "@solidjs/signals"
2
2
  import { onResize } from "@solidrt/core"
3
3
 
4
4
  export function SafeArea(props: {
5
- edges?: ("top" | "bottom" | "left" | "right")[]
6
- minimum?: number
5
+ top?: boolean | number
6
+ bottom?: boolean | number
7
+ left?: boolean | number
8
+ right?: boolean | number
7
9
  children?: any
8
10
  }) {
9
11
  let [insets, setInsets] = createSignal({ top: 0, bottom: 0, left: 0, right: 0 })
@@ -15,9 +17,13 @@ export function SafeArea(props: {
15
17
  right: width - safeArea.right,
16
18
  })
17
19
  })
18
- let has = (e: string) => (props.edges ?? ["top", "bottom"]).includes(e as any)
19
- let pad = (edge: "top" | "bottom" | "left" | "right") =>
20
- has(edge) ? Math.max(insets()[edge], props.minimum ?? 0) : 0
20
+ let pad = (edge: "top" | "bottom" | "left" | "right") => {
21
+ let defaultOn = edge === "top" || edge === "bottom"
22
+ let p = props[edge] ?? defaultOn
23
+ if (p === false) return 0
24
+ if (p === true) return insets()[edge]
25
+ return Math.max(insets()[edge], p as number)
26
+ }
21
27
  return (
22
28
  <view
23
29
  flex={1}