@unofficialbox/box-open-elements-solid 0.0.0-stage → 0.42.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kyle @ Unofficial Box
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,61 @@
1
- # Temporary Holding Version
1
+ # SolidJS adapter
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `@unofficialbox/box-open-elements-solid` is implemented, awaiting independent review,
4
+ and **not published**. Use the workspace or a locally packed tarball for now.
5
+ The package version follows core lockstep; it does not indicate npm availability.
6
+
7
+ Exports: `Button`, `TextField`, `Select`, `Dialog`, `Combobox`, `Drawer`, `createWebComponent`,
8
+ `ExplorerSelectionController`, and `useExplorerSelectionController`, with public
9
+ prop/event/ref declarations and per-component subpath exports.
10
+
11
+ Peers: core `^0.42.2` and solid-js `^1.9.17`.
12
+
13
+ ```tsx
14
+ import { TextField, Select, Dialog } from "@unofficialbox/box-open-elements-solid";
15
+
16
+ // Render inside your framework component. Pass normal JSX props, including
17
+ // reactive signal reads in Solid. Structured values go through BOE setters.
18
+ <TextField name="title" label="Title" value="Example"
19
+ ref={element => element?.focus()}
20
+ onValueChanged={event => console.log(event.detail.value)} />;
21
+ <Select options={[{ label: "One", value: "1" }]} value="1" />;
22
+ <Dialog open={false} heading="Details"><span slot="footer">Footer</span></Dialog>;
23
+ ```
24
+
25
+ Solid props remain getter-backed through `splitProps`; the host does not remount
26
+ when signals update. Call `useExplorerSelectionController` within a Solid owner;
27
+ it returns an accessor and owner disposal releases the subscription. Refs follow
28
+ Solid's element callback/JSX assignment contract; callbacks are not called with
29
+ null at disposal. Use `onCleanup` for external ref-owned resources.
30
+
31
+ Mapped BOE event callbacks receive the actual DOM event; `preventDefault` and
32
+ `stopPropagation` act on it. Cancellation works when the underlying event is
33
+ cancelable; BOE Dialog's `cancel` notification itself is not cancelable. Factory
34
+ `events` maps preserve exact spelling/case, and listeners are removed when the
35
+ framework owner unmounts. Temporary DOM disconnect/reconnect retains the owner.
36
+ The wrappers retain BOE's optional-property semantics: omitted scalar props leave
37
+ the element value alone; disabled/invalid default to false. Use explicit false,
38
+ empty string, or empty array to clear controlled values. BOE Select intentionally
39
+ reflects its assigned options array as JSON. Host attributes, children, and slots
40
+ remain framework-native; use Solid's `attr:*`/`bool:*` for explicit attribute mode.
41
+
42
+ SSR imports require no DOM globals. Server rendering emits inert custom-element
43
+ hosts and light-DOM children; controlled properties and arrays are assigned on
44
+ client hydration, so do not expect populated shadow DOM before JavaScript runs.
45
+ Mapped listeners attach before initial property sync, including synchronous
46
+ `open-changed` notifications from initially-open Dialog and Drawer. Browser
47
+ fixtures cover closed-first and initially-open client/hydrated rendering.
48
+ Include `generateHydrationScript()` in the server HTML and compile both halves
49
+ with Solid's hydratable JSX compiler. SolidStart is not verified.
50
+
51
+ Validation: `bun run frameworks:solid`, `bun run frameworks:solid:ssr`,
52
+ `bun run test -- packages/solid`, `bun run frameworks:jsx:browser`, and
53
+ `bun run adapters:pack-check`. See [support status](../../docs/integration/framework-adapters.md)
54
+ and [release requirements](../../RELEASING.md).
55
+
56
+ Design references: [Solid dynamic hosts](https://docs.solidjs.com/reference/components/dynamic),
57
+ [exact native events](https://docs.solidjs.com/reference/jsx-attributes/on), and
58
+ [owner cleanup](https://docs.solidjs.com/reference/lifecycle/on-cleanup).
59
+ The installed 1.9.17 `solid-js/web` source confirms dynamic host hydration-key
60
+ reuse and separate server rendering. The factory uses those runtime APIs so the
61
+ published adapter itself needs no JSX compiler transform.
@@ -0,0 +1,21 @@
1
+ import { Button as ButtonElement } from "@unofficialbox/box-open-elements/button";
2
+ import { type WebComponentProps } from "./create-web-component.js";
3
+ import type { NativeEventHandler } from "./events.js";
4
+ export type ButtonProps = Omit<WebComponentProps, "onClick"> & {
5
+ label?: string;
6
+ accessibleLabel?: string;
7
+ tone?: string;
8
+ size?: string;
9
+ disabled?: boolean;
10
+ onClick?: NativeEventHandler<ButtonElement, MouseEvent>;
11
+ };
12
+ export declare const Button: import("solid-js").Component<Omit<WebComponentProps, "onClick"> & {
13
+ label?: string;
14
+ accessibleLabel?: string;
15
+ tone?: string;
16
+ size?: string;
17
+ disabled?: boolean;
18
+ onClick?: NativeEventHandler<ButtonElement, MouseEvent>;
19
+ } & {
20
+ ref?: ButtonElement | ((element: ButtonElement) => void) | undefined;
21
+ }>;
package/dist/button.js ADDED
@@ -0,0 +1,22 @@
1
+ import { Button as ButtonElement } from "@unofficialbox/box-open-elements/button";
2
+ import { createWebComponent } from "./create-web-component.js";
3
+ ButtonElement.register();
4
+ export const Button = createWebComponent({
5
+ tagName: "box-button",
6
+ propertyNames: ["label", "accessibleLabel", "tone", "size", "disabled"],
7
+ events: [{ propName: "onClick", eventName: "click" }],
8
+ sync: (element, props) => {
9
+ if (props.label !== undefined) {
10
+ element.label = props.label;
11
+ }
12
+ if (props.accessibleLabel !== undefined)
13
+ element.accessibleLabel = props.accessibleLabel;
14
+ if (props.tone !== undefined) {
15
+ element.tone = props.tone;
16
+ }
17
+ if (props.size !== undefined) {
18
+ element.size = props.size;
19
+ }
20
+ element.disabled = Boolean(props.disabled);
21
+ },
22
+ });
@@ -0,0 +1,42 @@
1
+ import { Combobox as ComboboxElement } from "@unofficialbox/box-open-elements/combobox";
2
+ import { type WebComponentProps } from "./create-web-component.js";
3
+ import type { CustomEventHandler, ValueChangedDetail } from "./events.js";
4
+ export type ComboboxOption = {
5
+ label: string;
6
+ value: string;
7
+ description?: string;
8
+ group?: string;
9
+ disabled?: boolean;
10
+ };
11
+ export type ComboboxProps = WebComponentProps & {
12
+ label?: string;
13
+ value?: string;
14
+ options?: ComboboxOption[];
15
+ placeholder?: string;
16
+ placement?: string;
17
+ disabled?: boolean;
18
+ name?: string;
19
+ invalid?: boolean;
20
+ errorMessage?: string;
21
+ description?: string;
22
+ required?: boolean;
23
+ hideLabel?: boolean;
24
+ onValueChanged?: CustomEventHandler<ComboboxElement, ValueChangedDetail>;
25
+ };
26
+ export declare const Combobox: import("solid-js").Component<WebComponentProps & {
27
+ label?: string;
28
+ value?: string;
29
+ options?: ComboboxOption[];
30
+ placeholder?: string;
31
+ placement?: string;
32
+ disabled?: boolean;
33
+ name?: string;
34
+ invalid?: boolean;
35
+ errorMessage?: string;
36
+ description?: string;
37
+ required?: boolean;
38
+ hideLabel?: boolean;
39
+ onValueChanged?: CustomEventHandler<ComboboxElement, ValueChangedDetail>;
40
+ } & {
41
+ ref?: ComboboxElement | ((element: ComboboxElement) => void) | undefined;
42
+ }>;
@@ -0,0 +1,35 @@
1
+ import { Combobox as ComboboxElement } from "@unofficialbox/box-open-elements/combobox";
2
+ import { createWebComponent } from "./create-web-component.js";
3
+ ComboboxElement.register();
4
+ export const Combobox = createWebComponent({
5
+ tagName: "box-combobox",
6
+ propertyNames: [
7
+ "label", "value", "options", "placeholder", "placement", "disabled",
8
+ "name", "invalid", "errorMessage", "description", "required", "hideLabel",
9
+ ],
10
+ events: [{ propName: "onValueChanged", eventName: "value-changed" }],
11
+ sync: (element, props) => {
12
+ if (props.label !== undefined)
13
+ element.label = props.label;
14
+ if (props.value !== undefined)
15
+ element.value = props.value;
16
+ if (props.options !== undefined)
17
+ element.options = props.options;
18
+ if (props.placeholder !== undefined)
19
+ element.placeholder = props.placeholder;
20
+ if (props.placement !== undefined)
21
+ element.placement = props.placement;
22
+ if (props.name !== undefined)
23
+ element.name = props.name;
24
+ if (props.errorMessage !== undefined)
25
+ element.errorMessage = props.errorMessage;
26
+ if (props.description !== undefined)
27
+ element.description = props.description;
28
+ if (props.required !== undefined)
29
+ element.required = props.required;
30
+ if (props.hideLabel !== undefined)
31
+ element.hideLabel = props.hideLabel;
32
+ element.disabled = Boolean(props.disabled);
33
+ element.invalid = Boolean(props.invalid);
34
+ },
35
+ });
@@ -0,0 +1,15 @@
1
+ import { type Component, type JSX } from "solid-js";
2
+ export type WebComponentProps = Omit<JSX.HTMLAttributes<HTMLElement>, "ref" | "onCancel">;
3
+ export type CreateWebComponentOptions<E extends HTMLElement, P> = {
4
+ tagName: string;
5
+ sync: (element: E, props: P) => void;
6
+ propertyNames?: ReadonlyArray<keyof P & string>;
7
+ events?: ReadonlyArray<{
8
+ propName: keyof P & string;
9
+ eventName: string;
10
+ }>;
11
+ };
12
+ /** A stable host with reactive property synchronization and owner-scoped listeners. */
13
+ export declare function createWebComponent<E extends HTMLElement, P extends object>(options: CreateWebComponentOptions<E, P>): Component<P & {
14
+ ref?: E | ((element: E) => void);
15
+ }>;
@@ -0,0 +1,35 @@
1
+ import { createRenderEffect, mergeProps, onCleanup, splitProps, untrack } from "solid-js";
2
+ import { createDynamic } from "solid-js/web";
3
+ /** A stable host with reactive property synchronization and owner-scoped listeners. */
4
+ export function createWebComponent(options) {
5
+ return props => {
6
+ // splitProps preserves Solid's getter-backed props; spreading here would
7
+ // freeze signal values at component creation.
8
+ const [, host] = splitProps(props, [
9
+ ...(options.propertyNames ?? []),
10
+ ...(options.events ?? []).map(binding => binding.propName),
11
+ "ref",
12
+ ]);
13
+ return createDynamic(() => options.tagName, mergeProps(host, {
14
+ ref(element) {
15
+ const subscriptions = (options.events ?? []).map(binding => {
16
+ const listener = (event) => {
17
+ const handler = props[binding.propName];
18
+ if (typeof handler === "function")
19
+ untrack(() => handler(event));
20
+ };
21
+ element.addEventListener(binding.eventName, listener);
22
+ return { ...binding, listener };
23
+ });
24
+ onCleanup(() => {
25
+ for (const binding of subscriptions)
26
+ element.removeEventListener(binding.eventName, binding.listener);
27
+ });
28
+ createRenderEffect(() => options.sync(element, props));
29
+ const ref = props.ref;
30
+ if (typeof ref === "function")
31
+ ref(element);
32
+ },
33
+ }));
34
+ };
35
+ }
@@ -0,0 +1,42 @@
1
+ import type { JSX } from "solid-js";
2
+ import { Dialog as DialogElement } from "@unofficialbox/box-open-elements/dialog";
3
+ import { type WebComponentProps } from "./create-web-component.js";
4
+ import type { CustomEventHandler } from "./events.js";
5
+ export type DialogConfirmTone = "primary" | "danger";
6
+ export type DialogSize = "small" | "medium" | "large" | "fullscreen";
7
+ export type DialogProps = WebComponentProps & {
8
+ children?: JSX.Element;
9
+ open?: boolean;
10
+ heading?: string;
11
+ description?: string;
12
+ confirmLabel?: string;
13
+ confirmTone?: DialogConfirmTone;
14
+ confirmDisabled?: boolean;
15
+ confirmBusy?: boolean;
16
+ confirmBusyLabel?: string;
17
+ size?: DialogSize;
18
+ onOpenChanged?: CustomEventHandler<DialogElement, {
19
+ open: boolean;
20
+ }>;
21
+ onConfirm?: CustomEventHandler<DialogElement, null>;
22
+ onCancel?: CustomEventHandler<DialogElement, null>;
23
+ };
24
+ export declare const Dialog: import("solid-js").Component<WebComponentProps & {
25
+ children?: JSX.Element;
26
+ open?: boolean;
27
+ heading?: string;
28
+ description?: string;
29
+ confirmLabel?: string;
30
+ confirmTone?: DialogConfirmTone;
31
+ confirmDisabled?: boolean;
32
+ confirmBusy?: boolean;
33
+ confirmBusyLabel?: string;
34
+ size?: DialogSize;
35
+ onOpenChanged?: CustomEventHandler<DialogElement, {
36
+ open: boolean;
37
+ }>;
38
+ onConfirm?: CustomEventHandler<DialogElement, null>;
39
+ onCancel?: CustomEventHandler<DialogElement, null>;
40
+ } & {
41
+ ref?: DialogElement | ((element: DialogElement) => void) | undefined;
42
+ }>;
package/dist/dialog.js ADDED
@@ -0,0 +1,37 @@
1
+ import { Dialog as DialogElement } from "@unofficialbox/box-open-elements/dialog";
2
+ import { createWebComponent } from "./create-web-component.js";
3
+ DialogElement.register();
4
+ export const Dialog = createWebComponent({
5
+ tagName: "box-dialog",
6
+ propertyNames: ["open", "heading", "description", "confirmLabel", "confirmTone", "confirmDisabled", "confirmBusy", "confirmBusyLabel", "size"],
7
+ events: [
8
+ { propName: "onOpenChanged", eventName: "open-changed" },
9
+ { propName: "onConfirm", eventName: "confirm" },
10
+ { propName: "onCancel", eventName: "cancel" },
11
+ ],
12
+ sync: (element, props) => {
13
+ if (props.heading !== undefined) {
14
+ element.heading = props.heading;
15
+ }
16
+ if (props.description !== undefined) {
17
+ element.description = props.description;
18
+ }
19
+ if (props.confirmLabel !== undefined) {
20
+ element.confirmLabel = props.confirmLabel;
21
+ }
22
+ if (props.confirmTone !== undefined)
23
+ element.confirmTone = props.confirmTone;
24
+ if (props.confirmDisabled !== undefined)
25
+ element.confirmDisabled = props.confirmDisabled;
26
+ if (props.confirmBusy !== undefined)
27
+ element.confirmBusy = props.confirmBusy;
28
+ if (props.confirmBusyLabel !== undefined)
29
+ element.confirmBusyLabel = props.confirmBusyLabel;
30
+ if (props.size !== undefined) {
31
+ element.size = props.size;
32
+ }
33
+ if (props.open !== undefined) {
34
+ element.open = props.open;
35
+ }
36
+ },
37
+ });
@@ -0,0 +1,39 @@
1
+ import type { JSX } from "solid-js";
2
+ import { Drawer as DrawerRef } from "@unofficialbox/box-open-elements/drawer";
3
+ import { type WebComponentProps } from "./create-web-component.js";
4
+ import type { CustomEventHandler } from "./events.js";
5
+ export type { DrawerRef };
6
+ export type DrawerProps = WebComponentProps & {
7
+ children?: JSX.Element;
8
+ heading?: string;
9
+ description?: string;
10
+ open?: boolean;
11
+ position?: string;
12
+ size?: string;
13
+ busy?: boolean;
14
+ hideCloseButton?: boolean;
15
+ onOpenChanged?: CustomEventHandler<DrawerRef, {
16
+ open: boolean;
17
+ }>;
18
+ onDismiss?: CustomEventHandler<DrawerRef, {
19
+ source: "close-button" | "backdrop" | "escape";
20
+ }>;
21
+ };
22
+ export declare const Drawer: import("solid-js").Component<WebComponentProps & {
23
+ children?: JSX.Element;
24
+ heading?: string;
25
+ description?: string;
26
+ open?: boolean;
27
+ position?: string;
28
+ size?: string;
29
+ busy?: boolean;
30
+ hideCloseButton?: boolean;
31
+ onOpenChanged?: CustomEventHandler<DrawerRef, {
32
+ open: boolean;
33
+ }>;
34
+ onDismiss?: CustomEventHandler<DrawerRef, {
35
+ source: "close-button" | "backdrop" | "escape";
36
+ }>;
37
+ } & {
38
+ ref?: DrawerRef | ((element: DrawerRef) => void) | undefined;
39
+ }>;
package/dist/drawer.js ADDED
@@ -0,0 +1,23 @@
1
+ import { Drawer as DrawerRef } from "@unofficialbox/box-open-elements/drawer";
2
+ import { createWebComponent } from "./create-web-component.js";
3
+ export const Drawer = createWebComponent({
4
+ tagName: DrawerRef.tagName,
5
+ propertyNames: ["heading", "description", "open", "position", "size", "busy", "hideCloseButton"],
6
+ events: [{ propName: "onOpenChanged", eventName: "open-changed" }, { propName: "onDismiss", eventName: "dismiss" }],
7
+ sync: (element, props) => {
8
+ if (props.heading !== undefined)
9
+ element.heading = props.heading;
10
+ if (props.description !== undefined)
11
+ element.description = props.description;
12
+ if (props.open !== undefined)
13
+ element.open = props.open;
14
+ if (props.position !== undefined)
15
+ element.position = props.position;
16
+ if (props.size !== undefined)
17
+ element.size = props.size;
18
+ if (props.busy !== undefined)
19
+ element.busy = props.busy;
20
+ if (props.hideCloseButton !== undefined)
21
+ element.hideCloseButton = props.hideCloseButton;
22
+ },
23
+ });
@@ -0,0 +1,9 @@
1
+ export type CustomEventHandler<E extends HTMLElement, Detail> = (event: CustomEvent<Detail> & {
2
+ currentTarget: E;
3
+ }) => void;
4
+ export type NativeEventHandler<E extends HTMLElement, Ev extends Event = Event> = (event: Ev & {
5
+ currentTarget: E;
6
+ }) => void;
7
+ export type ValueChangedDetail = {
8
+ value: string;
9
+ };
package/dist/events.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import { type Accessor } from "solid-js";
2
+ import { ExplorerSelectionController, type ExplorerSelectionState } from "@unofficialbox/box-open-elements/patterns/content-explorer/selection";
3
+ export { ExplorerSelectionController };
4
+ export type { ExplorerSelectionState };
5
+ /** Call inside a Solid owner; disposal releases the controller subscription. */
6
+ export declare function useExplorerSelectionController(controller: ExplorerSelectionController): Accessor<Readonly<ExplorerSelectionState>>;
@@ -0,0 +1,12 @@
1
+ import { createSignal, getOwner, onCleanup } from "solid-js";
2
+ import { ExplorerSelectionController } from "@unofficialbox/box-open-elements/patterns/content-explorer/selection";
3
+ export { ExplorerSelectionController };
4
+ /** Call inside a Solid owner; disposal releases the controller subscription. */
5
+ export function useExplorerSelectionController(controller) {
6
+ if (!getOwner())
7
+ throw new Error("useExplorerSelectionController requires a Solid reactive owner.");
8
+ const [state, setState] = createSignal(controller.getState());
9
+ const unsubscribe = controller.subscribe("selectionChanged", () => setState(controller.getState()));
10
+ onCleanup(unsubscribe);
11
+ return state;
12
+ }
@@ -0,0 +1,9 @@
1
+ export { createWebComponent, type WebComponentProps, type CreateWebComponentOptions } from "./create-web-component.js";
2
+ export type { CustomEventHandler, NativeEventHandler, ValueChangedDetail } from "./events.js";
3
+ export { Button, type ButtonProps } from "./button.js";
4
+ export { TextField, type TextFieldProps } from "./text-field.js";
5
+ export { Select, type SelectProps, type SelectOption } from "./select.js";
6
+ export { Dialog, type DialogProps, type DialogConfirmTone, type DialogSize } from "./dialog.js";
7
+ export { ExplorerSelectionController, useExplorerSelectionController, type ExplorerSelectionState } from "./explorer-selection.js";
8
+ export { Combobox, type ComboboxProps, type ComboboxOption } from "./combobox.js";
9
+ export { Drawer, type DrawerProps, type DrawerRef } from "./drawer.js";
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ export { createWebComponent } from "./create-web-component.js";
2
+ export { Button } from "./button.js";
3
+ export { TextField } from "./text-field.js";
4
+ export { Select } from "./select.js";
5
+ export { Dialog } from "./dialog.js";
6
+ export { ExplorerSelectionController, useExplorerSelectionController } from "./explorer-selection.js";
7
+ export { Combobox } from "./combobox.js";
8
+ export { Drawer } from "./drawer.js";
@@ -0,0 +1,35 @@
1
+ import { Select as SelectElement } from "@unofficialbox/box-open-elements/select";
2
+ import { type WebComponentProps } from "./create-web-component.js";
3
+ import type { CustomEventHandler, ValueChangedDetail } from "./events.js";
4
+ export type SelectOption = {
5
+ label: string;
6
+ value: string;
7
+ };
8
+ export type SelectProps = WebComponentProps & {
9
+ label?: string;
10
+ value?: string;
11
+ options?: SelectOption[];
12
+ disabled?: boolean;
13
+ name?: string;
14
+ invalid?: boolean;
15
+ errorMessage?: string;
16
+ description?: string;
17
+ required?: boolean;
18
+ hideLabel?: boolean;
19
+ onValueChanged?: CustomEventHandler<SelectElement, ValueChangedDetail>;
20
+ };
21
+ export declare const Select: import("solid-js").Component<WebComponentProps & {
22
+ label?: string;
23
+ value?: string;
24
+ options?: SelectOption[];
25
+ disabled?: boolean;
26
+ name?: string;
27
+ invalid?: boolean;
28
+ errorMessage?: string;
29
+ description?: string;
30
+ required?: boolean;
31
+ hideLabel?: boolean;
32
+ onValueChanged?: CustomEventHandler<SelectElement, ValueChangedDetail>;
33
+ } & {
34
+ ref?: SelectElement | ((element: SelectElement) => void) | undefined;
35
+ }>;
package/dist/select.js ADDED
@@ -0,0 +1,42 @@
1
+ import { Select as SelectElement } from "@unofficialbox/box-open-elements/select";
2
+ import { createWebComponent } from "./create-web-component.js";
3
+ SelectElement.register();
4
+ export const Select = createWebComponent({
5
+ tagName: "box-select",
6
+ propertyNames: [
7
+ "label",
8
+ "value",
9
+ "options",
10
+ "disabled",
11
+ "name",
12
+ "invalid",
13
+ "errorMessage",
14
+ "description", "required", "hideLabel",
15
+ ],
16
+ events: [{ propName: "onValueChanged", eventName: "value-changed" }],
17
+ sync: (element, props) => {
18
+ if (props.description !== undefined)
19
+ element.description = props.description;
20
+ if (props.required !== undefined)
21
+ element.required = props.required;
22
+ if (props.hideLabel !== undefined)
23
+ element.hideLabel = props.hideLabel;
24
+ if (props.label !== undefined) {
25
+ element.label = props.label;
26
+ }
27
+ if (props.value !== undefined) {
28
+ element.value = props.value;
29
+ }
30
+ if (props.options !== undefined) {
31
+ element.options = props.options;
32
+ }
33
+ if (props.name !== undefined) {
34
+ element.name = props.name;
35
+ }
36
+ if (props.errorMessage !== undefined) {
37
+ element.errorMessage = props.errorMessage;
38
+ }
39
+ element.disabled = Boolean(props.disabled);
40
+ element.invalid = Boolean(props.invalid);
41
+ },
42
+ });
@@ -0,0 +1,41 @@
1
+ import { TextField as TextFieldElement } from "@unofficialbox/box-open-elements/text-field";
2
+ import { type WebComponentProps } from "./create-web-component.js";
3
+ import type { CustomEventHandler, ValueChangedDetail } from "./events.js";
4
+ export type TextFieldProps = WebComponentProps & {
5
+ label?: string;
6
+ value?: string;
7
+ placeholder?: string;
8
+ type?: "text" | "password" | "email" | "tel" | "url" | "search" | "number";
9
+ reveal?: boolean;
10
+ revealLabel?: string;
11
+ autocomplete?: string;
12
+ disabled?: boolean;
13
+ readonly?: boolean;
14
+ name?: string;
15
+ invalid?: boolean;
16
+ errorMessage?: string;
17
+ description?: string;
18
+ required?: boolean;
19
+ hideLabel?: boolean;
20
+ onValueChanged?: CustomEventHandler<TextFieldElement, ValueChangedDetail>;
21
+ };
22
+ export declare const TextField: import("solid-js").Component<WebComponentProps & {
23
+ label?: string;
24
+ value?: string;
25
+ placeholder?: string;
26
+ type?: "text" | "password" | "email" | "tel" | "url" | "search" | "number";
27
+ reveal?: boolean;
28
+ revealLabel?: string;
29
+ autocomplete?: string;
30
+ disabled?: boolean;
31
+ readonly?: boolean;
32
+ name?: string;
33
+ invalid?: boolean;
34
+ errorMessage?: string;
35
+ description?: string;
36
+ required?: boolean;
37
+ hideLabel?: boolean;
38
+ onValueChanged?: CustomEventHandler<TextFieldElement, ValueChangedDetail>;
39
+ } & {
40
+ ref?: TextFieldElement | ((element: TextFieldElement) => void) | undefined;
41
+ }>;
@@ -0,0 +1,54 @@
1
+ import { TextField as TextFieldElement } from "@unofficialbox/box-open-elements/text-field";
2
+ import { createWebComponent } from "./create-web-component.js";
3
+ TextFieldElement.register();
4
+ export const TextField = createWebComponent({
5
+ tagName: "box-text-field",
6
+ propertyNames: [
7
+ "label",
8
+ "value",
9
+ "placeholder",
10
+ "type", "reveal", "revealLabel", "autocomplete",
11
+ "disabled",
12
+ "readonly",
13
+ "name",
14
+ "invalid",
15
+ "errorMessage",
16
+ "description", "required", "hideLabel",
17
+ ],
18
+ events: [{ propName: "onValueChanged", eventName: "value-changed" }],
19
+ sync: (element, props) => {
20
+ if (props.readonly !== undefined)
21
+ element.readonly = props.readonly;
22
+ if (props.description !== undefined)
23
+ element.description = props.description;
24
+ if (props.required !== undefined)
25
+ element.required = props.required;
26
+ if (props.hideLabel !== undefined)
27
+ element.hideLabel = props.hideLabel;
28
+ if (props.label !== undefined) {
29
+ element.label = props.label;
30
+ }
31
+ if (props.value !== undefined) {
32
+ element.value = props.value;
33
+ }
34
+ if (props.placeholder !== undefined) {
35
+ element.placeholder = props.placeholder;
36
+ }
37
+ if (props.type !== undefined)
38
+ element.type = props.type;
39
+ if (props.reveal !== undefined)
40
+ element.reveal = props.reveal;
41
+ if (props.revealLabel !== undefined)
42
+ element.revealLabel = props.revealLabel;
43
+ if (props.autocomplete !== undefined)
44
+ element.autocomplete = props.autocomplete;
45
+ if (props.name !== undefined) {
46
+ element.name = props.name;
47
+ }
48
+ if (props.errorMessage !== undefined) {
49
+ element.errorMessage = props.errorMessage;
50
+ }
51
+ element.disabled = Boolean(props.disabled);
52
+ element.invalid = Boolean(props.invalid);
53
+ },
54
+ });
package/package.json CHANGED
@@ -1,6 +1,53 @@
1
1
  {
2
2
  "name": "@unofficialbox/box-open-elements-solid",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.42.2",
4
+ "description": "Optional native solid adapters for box-open-elements Web Components.",
5
+ "license": "MIT",
6
+ "homepage": "https://unofficialbox.github.io/box-open-elements",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/unofficialbox/box-open-elements.git",
10
+ "directory": "packages/solid"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/unofficialbox/box-open-elements/issues"
14
+ },
15
+ "keywords": [
16
+ "solid",
17
+ "web-components",
18
+ "design-system",
19
+ "box"
20
+ ],
21
+ "type": "module",
22
+ "sideEffects": false,
23
+ "main": "dist/index.js",
24
+ "types": "dist/index.d.ts",
25
+ "exports": {
26
+ "./*": {
27
+ "types": "./dist/*.d.ts",
28
+ "import": "./dist/*.js"
29
+ },
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js"
33
+ }
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "engines": {
42
+ "node": ">=20.9.0"
43
+ },
44
+ "peerDependencies": {
45
+ "@unofficialbox/box-open-elements": "^0.42.2",
46
+ "solid-js": "^1.9.17"
47
+ },
48
+ "scripts": {
49
+ "build": "tsc -p tsconfig.build.json",
50
+ "prepublishOnly": "bun run build",
51
+ "typecheck": "tsc -p tsconfig.json --noEmit"
52
+ }
53
+ }