@pebble-software/bonsai 0.0.7 → 0.1.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.
Files changed (90) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +367 -88
  3. package/dist/chunks/button-CSLrIvsS.js +166 -0
  4. package/dist/chunks/button-CSLrIvsS.js.map +1 -0
  5. package/dist/chunks/create-renderer-1cky1uN9.js +280 -0
  6. package/dist/chunks/create-renderer-1cky1uN9.js.map +1 -0
  7. package/dist/chunks/render-shared-CIUUkLDn.js +2319 -0
  8. package/dist/chunks/render-shared-CIUUkLDn.js.map +1 -0
  9. package/dist/components/core/bonsai.d.ts +5 -0
  10. package/dist/components/core/render-shared.d.ts +123 -0
  11. package/dist/components/core/render-tree-client.d.ts +4 -0
  12. package/dist/components/core/render-tree-server.d.ts +2 -0
  13. package/dist/components/ui/a.d.ts +3 -0
  14. package/dist/components/ui/accordion.d.ts +17 -0
  15. package/dist/components/ui/alert-dialog.d.ts +23 -0
  16. package/dist/components/ui/alert.d.ts +12 -0
  17. package/dist/components/ui/avatar.d.ts +21 -0
  18. package/dist/components/ui/badge.d.ts +10 -0
  19. package/dist/components/ui/breadcrumb.d.ts +10 -0
  20. package/dist/components/ui/button.d.ts +14 -0
  21. package/dist/components/ui/calendar.d.ts +9 -0
  22. package/dist/components/ui/card.d.ts +15 -0
  23. package/dist/components/ui/checkbox.d.ts +7 -0
  24. package/dist/components/ui/collapsible.d.ts +5 -0
  25. package/dist/components/ui/combobox.d.ts +31 -0
  26. package/dist/components/ui/command.d.ts +23 -0
  27. package/dist/components/ui/dialog.d.ts +23 -0
  28. package/dist/components/ui/drawer.d.ts +22 -0
  29. package/dist/components/ui/dropdown-menu.d.ts +29 -0
  30. package/dist/components/ui/form.d.ts +24 -0
  31. package/dist/components/ui/h.d.ts +10 -0
  32. package/dist/components/ui/input-group.d.ts +18 -0
  33. package/dist/components/ui/input-otp.d.ts +11 -0
  34. package/dist/components/ui/input.d.ts +3 -0
  35. package/dist/components/ui/label.d.ts +10 -0
  36. package/dist/components/ui/loader.d.ts +14 -0
  37. package/dist/components/ui/p.d.ts +11 -0
  38. package/dist/components/ui/popover.d.ts +9 -0
  39. package/dist/components/ui/progress.d.ts +31 -0
  40. package/dist/components/ui/scroll-area.d.ts +13 -0
  41. package/dist/components/ui/select.d.ts +17 -0
  42. package/dist/components/ui/separator.d.ts +8 -0
  43. package/dist/components/ui/sidebar.d.ts +70 -0
  44. package/dist/components/ui/signature-pad.d.ts +7 -0
  45. package/dist/components/ui/skeleton.d.ts +7 -0
  46. package/dist/components/ui/switch.d.ts +8 -0
  47. package/dist/components/ui/table.d.ts +14 -0
  48. package/dist/components/ui/tabs.d.ts +15 -0
  49. package/dist/components/ui/textarea.d.ts +5 -0
  50. package/dist/components/ui/toast.d.ts +46 -0
  51. package/dist/components/ui/tooltip.d.ts +15 -0
  52. package/dist/core.d.ts +12 -0
  53. package/dist/core.js +17 -0
  54. package/dist/core.js.map +1 -0
  55. package/dist/hooks/haptics.d.ts +8 -0
  56. package/dist/hooks/use-mobile.d.ts +1 -0
  57. package/dist/index.css +7 -0
  58. package/dist/index.d.ts +27 -338
  59. package/dist/index.js +1157 -4760
  60. package/dist/index.js.map +1 -0
  61. package/dist/lib/ast/cache.d.ts +8 -0
  62. package/dist/lib/ast/evaluator.d.ts +2 -0
  63. package/dist/lib/ast/helpers.d.ts +2 -0
  64. package/dist/lib/ast/index.d.ts +29 -0
  65. package/dist/lib/ast/setup.d.ts +2 -0
  66. package/dist/lib/ast/types.d.ts +1 -0
  67. package/dist/lib/ast/utils.d.ts +4 -0
  68. package/dist/lib/haptics.d.ts +8 -0
  69. package/dist/lib/registry/drift.d.ts +17 -0
  70. package/dist/lib/registry/identity.d.ts +24 -0
  71. package/dist/lib/registry/json-schema-to-zod.d.ts +32 -0
  72. package/dist/lib/registry/manifest-schema.d.ts +62 -0
  73. package/dist/lib/registry/manifest.d.ts +26 -0
  74. package/dist/lib/registry/merge-generated.d.ts +7 -0
  75. package/dist/lib/registry/pebble-registry.d.ts +1 -0
  76. package/dist/lib/registry/types.d.ts +29 -0
  77. package/dist/lib/registry/validate.d.ts +18 -0
  78. package/dist/lib/renderer/compile-template.d.ts +70 -0
  79. package/dist/lib/ui/registry.d.ts +19 -0
  80. package/dist/lib/utils.d.ts +3 -0
  81. package/dist/presets/calendar.js +373 -0
  82. package/dist/presets/calendar.js.map +1 -0
  83. package/dist/presets/signature.js +404 -0
  84. package/dist/presets/signature.js.map +1 -0
  85. package/dist/renderer/core-registry.d.ts +52 -0
  86. package/dist/renderer/create-renderer.d.ts +38 -0
  87. package/dist/renderer/presets/calendar.d.ts +5 -0
  88. package/dist/renderer/presets/signature.d.ts +6 -0
  89. package/dist/types.d.ts +1 -0
  90. package/package.json +47 -21
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Compiles the JSON Schema subset a manifest's `propsSchema` is allowed to use into a
4
+ * Zod validator (REGISTRY_SPIKE.md, "Registry manifests": "JSON Schema on the wire;
5
+ * compiled to a Zod validator at load"). Deliberately a subset, not a general JSON
6
+ * Schema implementation — enough to express prop narrowing (type, enum, required,
7
+ * string/number bounds), which is the only thing a Case A manifest is allowed to do
8
+ * to a prop schema in the first place.
9
+ */
10
+ export type JsonSchema = Record<string, unknown>;
11
+ export interface JsonSchemaToZodOptions {
12
+ /**
13
+ * Accept a `"{{expression}}"` binding anywhere a typed value is declared.
14
+ *
15
+ * A template author writes `checked: "{{form.agree}}"` and the binding is resolved at
16
+ * render time, long after validation runs — so a schema saying `{"type":"boolean"}`
17
+ * rejects a template that would render perfectly. The hand-rolled registry has always
18
+ * worked around this by declaring `z.union([z.string(), z.boolean()])` by hand on every
19
+ * affected prop. This is that convention made available to manifests whose schemas were
20
+ * machine-derived from component sources and so cannot hand-write it.
21
+ *
22
+ * Opt-in rather than automatic: `bonsai.generated.json` doubles as an LLM tool
23
+ * definition, and a prop that reads "boolean" there is worth keeping precise.
24
+ *
25
+ * Narrower than the hand-rolled convention on purpose — only binding-*shaped* strings
26
+ * are admitted, not every string. `{"type":"string","minLength":1}` therefore still
27
+ * rejects `""`, and an `enum` still rejects a value outside it, both of which a blanket
28
+ * `z.string()` union would silently discard.
29
+ */
30
+ allowBindings?: boolean;
31
+ }
32
+ export declare function jsonSchemaToZod(schema: JsonSchema, options?: JsonSchemaToZodOptions): z.ZodType<unknown>;
@@ -0,0 +1,62 @@
1
+ import { z } from 'zod';
2
+ export declare const ManifestControlledSchema: z.ZodObject<{
3
+ valueProp: z.ZodString;
4
+ changeProp: z.ZodString;
5
+ extract: z.ZodString;
6
+ }, z.core.$strict>;
7
+ export declare const ManifestComponentSchema: z.ZodObject<{
8
+ name: z.ZodString;
9
+ canonicalName: z.ZodOptional<z.ZodString>;
10
+ entry: z.ZodString;
11
+ propsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
12
+ capabilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
13
+ children: "children";
14
+ bindings: "bindings";
15
+ events: "events";
16
+ formField: "formField";
17
+ ssr: "ssr";
18
+ pdf: "pdf";
19
+ }>>>;
20
+ controlled: z.ZodOptional<z.ZodObject<{
21
+ valueProp: z.ZodString;
22
+ changeProp: z.ZodString;
23
+ extract: z.ZodString;
24
+ }, z.core.$strict>>;
25
+ css: z.ZodOptional<z.ZodArray<z.ZodString>>;
26
+ }, z.core.$strict>;
27
+ export declare const RegistryManifestSchema: z.ZodObject<{
28
+ $schema: z.ZodOptional<z.ZodString>;
29
+ id: z.ZodString;
30
+ namespace: z.ZodOptional<z.ZodString>;
31
+ version: z.ZodString;
32
+ engine: z.ZodObject<{
33
+ name: z.ZodLiteral<"bonsai">;
34
+ api: z.ZodString;
35
+ }, z.core.$strict>;
36
+ components: z.ZodArray<z.ZodObject<{
37
+ name: z.ZodString;
38
+ canonicalName: z.ZodOptional<z.ZodString>;
39
+ entry: z.ZodString;
40
+ propsSchema: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
+ capabilities: z.ZodOptional<z.ZodArray<z.ZodEnum<{
42
+ children: "children";
43
+ bindings: "bindings";
44
+ events: "events";
45
+ formField: "formField";
46
+ ssr: "ssr";
47
+ pdf: "pdf";
48
+ }>>>;
49
+ controlled: z.ZodOptional<z.ZodObject<{
50
+ valueProp: z.ZodString;
51
+ changeProp: z.ZodString;
52
+ extract: z.ZodString;
53
+ }, z.core.$strict>>;
54
+ css: z.ZodOptional<z.ZodArray<z.ZodString>>;
55
+ }, z.core.$strict>>;
56
+ integrity: z.ZodOptional<z.ZodObject<{
57
+ algorithm: z.ZodLiteral<"sha256">;
58
+ manifestHash: z.ZodString;
59
+ }, z.core.$strict>>;
60
+ }, z.core.$strict>;
61
+ export type RegistryManifest = z.infer<typeof RegistryManifestSchema>;
62
+ export type ManifestComponent = z.infer<typeof ManifestComponentSchema>;
@@ -0,0 +1,26 @@
1
+ import { z } from 'zod';
2
+ import { RegistryManifest } from './manifest-schema.js';
3
+ import { BonsaiRegistry } from './types.js';
4
+ export type { RegistryManifest, ManifestComponent } from './manifest-schema.js';
5
+ export { RegistryManifestSchema } from './manifest-schema.js';
6
+ export declare const EXTRACTOR_ALLOWLIST: Record<string, (eventOrValue: unknown) => unknown>;
7
+ export declare class ManifestLoadError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ export declare function composePropsSchema(baseSchema: z.ZodType<unknown> | undefined, tenantSchema: z.ZodType<unknown> | undefined): z.ZodType<unknown> | undefined;
11
+ export declare function computeManifestHash(raw: string): Promise<string>;
12
+ export interface ResolveManifestOptions {
13
+ base: BonsaiRegistry;
14
+ engineApi?: string;
15
+ maxComponents?: number;
16
+ maxManifestBytes?: number;
17
+ rawManifestSize?: number;
18
+ manifestHash?: string;
19
+ }
20
+ export declare function resolveManifest(manifest: RegistryManifest, options: ResolveManifestOptions): BonsaiRegistry;
21
+ export interface LoadManifestOptions extends ResolveManifestOptions {
22
+ allowedOrigins?: string[];
23
+ fetchImpl?: typeof fetch;
24
+ }
25
+ export declare function clearManifestCache(): void;
26
+ export declare function loadRegistryManifest(source: RegistryManifest | string, options: LoadManifestOptions): Promise<BonsaiRegistry>;
@@ -0,0 +1,7 @@
1
+ import { JsonSchema } from './json-schema-to-zod.js';
2
+ export type ObjectPropsSchema = {
3
+ type?: "object";
4
+ properties: Record<string, JsonSchema>;
5
+ required?: string[];
6
+ };
7
+ export declare function mergeGeneratedWithOverrides(generated: ObjectPropsSchema | undefined, overrides: Partial<ObjectPropsSchema> | undefined): ObjectPropsSchema;
@@ -0,0 +1 @@
1
+ export declare const pebbleRegistry: import('./types.js').BonsaiRegistry;
@@ -0,0 +1,29 @@
1
+ import { ComponentType } from 'react';
2
+ import { ZodType } from 'zod';
3
+ export type ComponentCapability = "children" | "bindings" | "events" | "formField" | "ssr" | "pdf";
4
+ export interface ControlledFieldSpec {
5
+ valueProp: string;
6
+ changeProp: string;
7
+ extract: (eventOrValue: unknown) => unknown;
8
+ }
9
+ export interface ComponentDefinition {
10
+ component: ComponentType<any> | string;
11
+ propsSchema?: ZodType<any>;
12
+ capabilities?: ComponentCapability[];
13
+ controlled?: ControlledFieldSpec | Record<string, ControlledFieldSpec>;
14
+ assets?: {
15
+ css?: string[];
16
+ fonts?: string[];
17
+ };
18
+ }
19
+ export type RegistryFallback = "error" | "div" | ComponentType<any>;
20
+ export interface BonsaiRegistry {
21
+ id: string;
22
+ version: string;
23
+ namespace?: string;
24
+ manifestHash?: string;
25
+ components: Record<string, ComponentDefinition>;
26
+ fallback?: RegistryFallback;
27
+ }
28
+ export declare function defineComponent(def: ComponentDefinition): ComponentDefinition;
29
+ export declare function defineBonsaiRegistry(registry: BonsaiRegistry): BonsaiRegistry;
@@ -0,0 +1,18 @@
1
+ import { Config } from '../../types.js';
2
+ import { RegistryIdentity } from './identity.js';
3
+ import { BonsaiRegistry } from './types.js';
4
+ export interface RegistryValidationError {
5
+ path: string;
6
+ message: string;
7
+ componentType?: string;
8
+ }
9
+ export interface RegistryValidationResult {
10
+ valid: boolean;
11
+ errors: RegistryValidationError[];
12
+ warnings: string[];
13
+ }
14
+ export interface ValidateTemplateOptions {
15
+ mode?: "web" | "pdf";
16
+ pin?: RegistryIdentity;
17
+ }
18
+ export declare function validateTemplate(template: Config, registry: BonsaiRegistry, options?: ValidateTemplateOptions): RegistryValidationResult;
@@ -0,0 +1,70 @@
1
+ import { Config } from '../../types.js';
2
+ import { CompiledExpression } from '../ast/index.js';
3
+ /**
4
+ * Ahead-of-render metadata for one template node.
5
+ *
6
+ * Everything here is *scope-independent*: it is a pure function of the template
7
+ * node itself, so it survives being reused by every `each` row, every renderer
8
+ * instance and both render paths. Anything that depends on a row's `scope` /
9
+ * `indexScope`, on the live store, or on the `BonsaiRegistry` read from React
10
+ * context deliberately stays in the render path.
11
+ */
12
+ export interface CompiledNode {
13
+ /** The raw template node this was compiled from. */
14
+ source: Config;
15
+ /** True when the node is a bare string leaf. */
16
+ isText: boolean;
17
+ /** Element type *string* only — the registry lookup stays at render time. */
18
+ type: string;
19
+ isEach: boolean;
20
+ isIf: boolean;
21
+ isImage: boolean;
22
+ /** Variables the node's own bindings read, pre-split into path segments. */
23
+ dynamicKeys: CompiledKey[];
24
+ /** Arg names whose value is a `{{...}}` expression, so static props skip evaluation. */
25
+ dynamicArgs: Set<string>;
26
+ /**
27
+ * Arg name -> unresolved store path, only for args whose expression is a plain
28
+ * path (`{{user.name}}`, `{{rows[0].x}}`). Formulas (`{{a + b}}`, `{{xs.filter(...)}}`)
29
+ * have no path to write back to, so they're left out.
30
+ */
31
+ argPaths: Record<string, string>;
32
+ /** Parsed expressions keyed by arg name; `text` for a string leaf. */
33
+ expressions: Record<string, CompiledExpression>;
34
+ text: CompiledExpression | null;
35
+ /** True when the node has no bindings and is not a control node, so it can render as a memoised static subtree. */
36
+ isStatic: boolean;
37
+ each: CompiledEach | null;
38
+ children: CompiledNode[];
39
+ }
40
+ /** A dynamic key with the path-splitting work already done. */
41
+ export interface CompiledKey {
42
+ /** The key exactly as `extractVariables` produced it, e.g. `applicant.name`. */
43
+ key: string;
44
+ /** `key` split and unwrapped, e.g. `["rows", "0", "label"]`. */
45
+ segments: string[];
46
+ /** `numericNext[i]` is true when `segments[i + 1]` is an array index. */
47
+ numericNext: boolean[];
48
+ }
49
+ export interface CompiledEach {
50
+ as: string;
51
+ indexAlias: string | undefined;
52
+ keyExpr: any;
53
+ /**
54
+ * The unresolved store path the array lives at (`""` for a computed items
55
+ * expression). Resolving it against a row's `scope` stays at render time.
56
+ */
57
+ rawItemsPath: string;
58
+ }
59
+ export interface CompiledTemplate {
60
+ root: CompiledNode;
61
+ source: Config;
62
+ }
63
+ export declare function splitPathSegments(path: string): string[];
64
+ export declare function unwrapSegment(seg: string): string;
65
+ /**
66
+ * Compiles a template once and caches it by object identity, so mounting the
67
+ * same template in N renderer instances does the work once. Both `RenderTree`
68
+ * (SSR) and `RenderTreeClient` (client) consume the result.
69
+ */
70
+ export declare function compileTemplate(template: Config): CompiledTemplate;
@@ -0,0 +1,19 @@
1
+ import { ComponentRegistry, ControlledInput, ControlledInputEntry, ControlledInputRegistry } from '../../renderer/core-registry.js';
2
+ /**
3
+ * The full, batteries-included registry: every core component plus the heavy
4
+ * opt-in presets (calendar, signature). Importing this module transitively
5
+ * pulls in react-day-picker and react-signature-canvas — use
6
+ * `renderer/core-registry` if you want to stay lightweight.
7
+ *
8
+ * Typed with `ComponentRegistry`/`ControlledInputRegistry` (both
9
+ * `Record<string, ...>`) rather than `Record<COMPONENT[number], ...>` from
10
+ * `@bonsai/constants` — that package is workspace-only and unpublished, and
11
+ * referencing its types here would bake an escaping import path into this
12
+ * file's emitted declaration, the same class of bug fixed for `Config` in
13
+ * `src/types.ts`. (`COMPONENT[number]`, a numeric index into a union of
14
+ * string-literal enum members, was already widening to plain `string` here —
15
+ * so `ComponentRegistry`/`ControlledInputRegistry` lose nothing.)
16
+ */
17
+ export declare const componentMap: ComponentRegistry;
18
+ export declare const controlledInputMap: ControlledInputRegistry;
19
+ export type { ControlledInput, ControlledInputEntry };
@@ -0,0 +1,3 @@
1
+ import { ClassValue } from 'clsx';
2
+ export declare function cn(...inputs: ClassValue[]): string;
3
+ export declare function colorHash(text: string): string;
@@ -0,0 +1,373 @@
1
+ import { c as a, b, B as _, C as h } from "../chunks/button-CSLrIvsS.js";
2
+ import { jsxs as p, jsx as t } from "react/jsx-runtime";
3
+ import * as x from "react";
4
+ import { getDefaultClassNames as S, DayPicker as z } from "react-day-picker";
5
+ import { IconSelector as C, IconCheck as k, IconChevronUp as D, IconChevronDown as v, IconChevronLeft as I, IconChevronRight as j } from "@tabler/icons-react";
6
+ import { Select as s } from "@base-ui/react/select";
7
+ const y = s.Root;
8
+ y.displayName = "Select";
9
+ function P({ className: n, ...e }) {
10
+ return /* @__PURE__ */ t(
11
+ s.Value,
12
+ {
13
+ "data-slot": "select-value",
14
+ className: a(
15
+ "flex flex-1 text-left",
16
+ "group/select-trigger:line-clamp-1 group/select-trigger:items-center data-placeholder:text-subtle font-base",
17
+ n
18
+ ),
19
+ ...e
20
+ }
21
+ );
22
+ }
23
+ function L({
24
+ className: n,
25
+ size: e = "lg",
26
+ variant: i = "outline",
27
+ raised: c,
28
+ extrude: m,
29
+ children: f,
30
+ ...r
31
+ }) {
32
+ return /* @__PURE__ */ p(
33
+ s.Trigger,
34
+ {
35
+ "data-slot": "select-trigger",
36
+ "data-size": e,
37
+ "aria-label": r["aria-label"] ?? "select-trigger",
38
+ className: a(
39
+ b({ size: e, variant: i, raised: c, extrude: m }),
40
+ "group/select-trigger neo-base neo-input-focus disabled:opacity-50 [&_svg]:shrink-0 w-full",
41
+ n
42
+ ),
43
+ ...r,
44
+ children: [
45
+ f,
46
+ /* @__PURE__ */ t(
47
+ s.Icon,
48
+ {
49
+ className: "flex items-center justify-center",
50
+ render: /* @__PURE__ */ t(
51
+ C,
52
+ {
53
+ "data-slot": "select-selector",
54
+ className: "text-muted size-4 pointer-events-none"
55
+ }
56
+ )
57
+ }
58
+ )
59
+ ]
60
+ }
61
+ );
62
+ }
63
+ function R({
64
+ className: n,
65
+ children: e,
66
+ side: i = "bottom",
67
+ sideOffset: c = 4,
68
+ align: m = "center",
69
+ alignOffset: f = 0,
70
+ alignItemWithTrigger: r = !0,
71
+ ...g
72
+ }) {
73
+ return /* @__PURE__ */ t(s.Portal, { children: /* @__PURE__ */ t(
74
+ s.Positioner,
75
+ {
76
+ side: i,
77
+ sideOffset: c,
78
+ align: m,
79
+ alignOffset: f,
80
+ alignItemWithTrigger: r,
81
+ className: "isolate z-50",
82
+ children: /* @__PURE__ */ p(
83
+ s.Popup,
84
+ {
85
+ "data-slot": "select-content",
86
+ className: a(
87
+ "neo-base neo-focus relative isolate bg-surface text-foreground rounded-base shadow-md border-2 z-50 duration-100",
88
+ "max-h-(--available-height) w-(--anchor-width) min-w-36",
89
+ "origin-(--transform-origin) overflow-x-hidden overflow-y-auto",
90
+ "data-open:animate-in data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95",
91
+ "data-closed:animate-out data-closed:fade-out-0",
92
+ "data-[side=top]:slide-in-from-bottom-2",
93
+ "data-[side=bottom]:slide-in-from-top-2",
94
+ "data-[side=left]:slide-in-from-right-2",
95
+ "data-[side=right]:slide-in-from-left-2",
96
+ n
97
+ ),
98
+ ...g,
99
+ children: [
100
+ /* @__PURE__ */ t(B, {}),
101
+ /* @__PURE__ */ t(s.List, { className: "flex flex-col gap-0.5 p-0.5", children: e }),
102
+ /* @__PURE__ */ t(E, {})
103
+ ]
104
+ }
105
+ )
106
+ }
107
+ ) });
108
+ }
109
+ function A({
110
+ className: n,
111
+ children: e,
112
+ ...i
113
+ }) {
114
+ return /* @__PURE__ */ p(
115
+ s.Item,
116
+ {
117
+ "data-slot": "select-item",
118
+ className: a(
119
+ "neo-base flex items-center gap-2 py-1.5 pr-8 pl-2 relative w-full cursor-pointer select-none",
120
+ "border-2 border-transparent hover:border-border focus-visible:border-border outline-hidden rounded-base text-sm",
121
+ "*:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
122
+ "data-disabled:pointer-events-none data-disabled:opacity-50",
123
+ "[&_svg]:pointer-events-none [&_svg]:shrink-0",
124
+ n
125
+ ),
126
+ ...i,
127
+ children: [
128
+ /* @__PURE__ */ t(s.ItemText, { className: "flex flex-1 gap-2 shrink-0 whitespace-nowrap", children: e }),
129
+ /* @__PURE__ */ t(
130
+ s.ItemIndicator,
131
+ {
132
+ render: /* @__PURE__ */ t("span", { className: "pointer-events-none absolute right-2 flex size-4 items-center justify-center" }),
133
+ children: /* @__PURE__ */ t(k, { className: "pointer-events-none" })
134
+ }
135
+ )
136
+ ]
137
+ }
138
+ );
139
+ }
140
+ function B({
141
+ className: n,
142
+ ...e
143
+ }) {
144
+ return /* @__PURE__ */ t(
145
+ s.ScrollUpArrow,
146
+ {
147
+ "data-slot": "select-scroll-up-button",
148
+ className: a(
149
+ "bg-surface z-10 flex cursor-default items-center justify-center py-1 top-0 w-full",
150
+ n
151
+ ),
152
+ ...e,
153
+ children: /* @__PURE__ */ t(D, {})
154
+ }
155
+ );
156
+ }
157
+ function E({
158
+ className: n,
159
+ ...e
160
+ }) {
161
+ return /* @__PURE__ */ t(
162
+ s.ScrollDownArrow,
163
+ {
164
+ "data-slot": "select-scroll-down-button",
165
+ className: a(
166
+ "bg-surface z-10 flex cursor-default items-center justify-center py-1 bottom-0 w-full",
167
+ n
168
+ ),
169
+ ...e,
170
+ children: /* @__PURE__ */ t(v, {})
171
+ }
172
+ );
173
+ }
174
+ function T({
175
+ className: n,
176
+ classNames: e,
177
+ showOutsideDays: i = !0,
178
+ captionLayout: c = "label",
179
+ hideWeekdays: m = !1,
180
+ buttonVariant: f = "outline",
181
+ hideWeekends: r,
182
+ formatters: g,
183
+ components: w,
184
+ ...N
185
+ }) {
186
+ const o = S();
187
+ return /* @__PURE__ */ t(
188
+ z,
189
+ {
190
+ showOutsideDays: i,
191
+ className: a(
192
+ "p-3 bg-surface group/calendar [--cell-size:--spacing(8)]",
193
+ "in-data-[slot=card-content]:bg-transparent",
194
+ "in-data-[slot=popover-content]:bg-transparent",
195
+ n
196
+ ),
197
+ captionLayout: c,
198
+ formatters: {
199
+ formatCaption: (l) => l.toLocaleString("default", { month: "short", year: "numeric" }),
200
+ formatMonthDropdown: (l) => l.toLocaleString("default", { month: "short" }),
201
+ ...g
202
+ },
203
+ classNames: {
204
+ root: a("w-fit", o.root),
205
+ nav: a(
206
+ "flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
207
+ o.nav
208
+ ),
209
+ button_previous: a(
210
+ b({ variant: f, icon: "sm" }),
211
+ "aria-disabled:opacity-50 aria-disabled:translate-[0px] aria-disabled:shadow-none aria-disabled:pointer-events-none",
212
+ o.button_previous
213
+ ),
214
+ button_next: a(
215
+ b({ variant: f, icon: "sm" }),
216
+ "aria-disabled:opacity-50 aria-disabled:translate-[0px] aria-disabled:shadow-none aria-disabled:pointer-events-none",
217
+ o.button_next
218
+ ),
219
+ caption_label: a("select-none", o.caption_label),
220
+ months: a(
221
+ "flex gap-4 flex-col md:flex-row relative",
222
+ o.months
223
+ ),
224
+ month: a(
225
+ "flex flex-col w-full gap-4 *:first:*:h-(--cell-size) *:first:*:flex *:first:*:items-center *:first:*:justify-center *:first:**:font-medium *:first:**:font-heading *:first:**:text-base",
226
+ o.month
227
+ ),
228
+ table: "w-full border-collapse",
229
+ weekdays: a("flex", o.weekdays),
230
+ weekday: a(
231
+ m ? "hidden" : "text-sm font-normal font-heading text-muted text-center select-none flex-1",
232
+ o.weekday
233
+ ),
234
+ week_number: a(
235
+ "text-sm font-normal font-heading text-muted text-center select-none flex size-(--cell-size) items-center justify-center my-auto",
236
+ o.week_number
237
+ ),
238
+ week_number_header: a(
239
+ "select-none w-(--cell-size)",
240
+ o.week_number_header
241
+ ),
242
+ week: a("flex w-full", o.week),
243
+ day: a(
244
+ "relative text-center group/day select-none transition-[width,padding,margin] duration-200",
245
+ o.day
246
+ ),
247
+ day_button: a("m-1", o.day_button),
248
+ today: a(
249
+ "*:data-[slot=calendar-day-button]:font-semibold *:data-[slot=calendar-day-button]:text-lg",
250
+ o.today
251
+ ),
252
+ outside: a(
253
+ "text-muted aria-selected:text-foreground opacity-50 hover:opacity-100 aria-selected:opacity-100 aria-selected:*:data-[slot=calendar-day-button]:bg-main-secondary hover:*:data-[slot=calendar-day-button]:bg-surface *:data-[slot=calendar-day-button]:bg-foreground/20",
254
+ o.outside
255
+ ),
256
+ ...e
257
+ },
258
+ components: {
259
+ Root: ({ className: l, rootRef: d, ...u }) => /* @__PURE__ */ t(
260
+ "div",
261
+ {
262
+ "data-slot": "calendar",
263
+ ref: d,
264
+ className: a(l),
265
+ ...u
266
+ }
267
+ ),
268
+ Chevron: ({ className: l, orientation: d, ...u }) => d === "left" ? /* @__PURE__ */ t(I, { className: a("size-4", l), ...u }) : d === "right" ? /* @__PURE__ */ t(
269
+ j,
270
+ {
271
+ className: a("size-4", l),
272
+ ...u
273
+ }
274
+ ) : /* @__PURE__ */ t(v, { className: a("size-4", l), ...u }),
275
+ Weekday: ({ children: l, ...d }) => {
276
+ const u = d["aria-label"] === "Saturday" || d["aria-label"] === "Sunday";
277
+ return r && u ? /* @__PURE__ */ t("td", { hidden: !0 }) : /* @__PURE__ */ t("td", { ...d, children: l });
278
+ },
279
+ Day: ({ children: l, ...d }) => {
280
+ const u = new Date(d.day.date).getDay();
281
+ return r && (u === 0 || u === 6) ? /* @__PURE__ */ t("td", { hidden: !0 }) : d.modifiers.hidden ? /* @__PURE__ */ t("td", { className: "all-unset size-(--cell-size) m-1 bg-foreground opacity-20 rounded-base" }) : /* @__PURE__ */ t("td", { ...d, children: l });
282
+ },
283
+ Dropdown: V,
284
+ DayButton: U,
285
+ ...w
286
+ },
287
+ ...N
288
+ }
289
+ );
290
+ }
291
+ function U({
292
+ day: n,
293
+ modifiers: e,
294
+ ...i
295
+ }) {
296
+ const c = x.useRef(null);
297
+ return x.useEffect(() => {
298
+ e.focused && c.current?.focus();
299
+ }, [e.focused]), /* @__PURE__ */ t(
300
+ _,
301
+ {
302
+ "data-slot": "calendar-day-button",
303
+ "data-day": n.date.toLocaleDateString(),
304
+ "data-selected-single": e.selected && !e.range_start && !e.range_end && !e.range_middle,
305
+ "data-range-start": e.range_start,
306
+ "data-range-end": e.range_end,
307
+ "data-range-middle": e.range_middle,
308
+ "aria-label": n.date.toDateString(),
309
+ raised: e.range_start || e.range_end ? "md" : e.range_middle ? "xs" : "sm",
310
+ variant: e.selected ? "default" : "outline",
311
+ extrude: e.selected ? null : "xs",
312
+ disabled: e.disabled,
313
+ icon: "sm",
314
+ ...i
315
+ }
316
+ );
317
+ }
318
+ function V(n) {
319
+ const { options: e, onChange: i, value: c } = n, m = e?.find((r) => r.value === c), f = (r) => {
320
+ i?.({
321
+ target: { value: r }
322
+ });
323
+ };
324
+ return /* @__PURE__ */ p(
325
+ y,
326
+ {
327
+ value: c?.toString(),
328
+ onValueChange: (r) => f(r),
329
+ children: [
330
+ /* @__PURE__ */ t(
331
+ L,
332
+ {
333
+ variant: "ghost",
334
+ raised: null,
335
+ extrude: null,
336
+ className: "w-fit mx-1",
337
+ size: "sm",
338
+ children: /* @__PURE__ */ t(P, { children: m?.label })
339
+ }
340
+ ),
341
+ /* @__PURE__ */ t(R, { className: "bg-transparent border-0 w-30 shadow-none", children: /* @__PURE__ */ t("div", { className: "p-2", children: /* @__PURE__ */ t("div", { className: "flex flex-col items-center bg-foreground shadow-xs rounded-base", children: e?.map((r) => /* @__PURE__ */ t(
342
+ A,
343
+ {
344
+ className: a(
345
+ b({ extrude: "md" }),
346
+ "not-last:rounded-b-none not-first:rounded-t-none border-2 not-last:border-b-0 hover:border-2 hover:z-2 z-1 duration-200"
347
+ ),
348
+ value: r.value.toString(),
349
+ children: r.label
350
+ },
351
+ r.value
352
+ )) }) }) })
353
+ ]
354
+ }
355
+ );
356
+ }
357
+ const G = {
358
+ components: {
359
+ [h.CALENDAR]: T
360
+ },
361
+ controlledInputs: {
362
+ [h.CALENDAR]: {
363
+ valueProp: "selected",
364
+ changeProp: "onSelect",
365
+ extractor: (n) => n
366
+ }
367
+ }
368
+ };
369
+ export {
370
+ T as Calendar,
371
+ G as calendarPreset
372
+ };
373
+ //# sourceMappingURL=calendar.js.map