fluid-primitives 0.16.0 → 0.17.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/README.md CHANGED
@@ -2,12 +2,54 @@
2
2
 
3
3
  # Fluid Primitives
4
4
 
5
- The headless component library for TYPO3 Fluid
5
+ Unstyled, flexible and accessible UI Primitives that provide a foundation for building your own component library in Fluid.
6
+
7
+ Fluid Primitives brings modern component patterns to TYPO3. Build accessible, composable UI components with the same developer experience you'd expect from React libraries like Radix or Base UI - but for Fluid templates.
8
+
9
+ Full documentation can be found at [fluid-primitives.com](https://fluid-primitives.com).
10
+
11
+ ## What You Get
12
+
13
+ **Accessible by default.** Every interactive component handles keyboard navigation, focus management, and ARIA attributes automatically via [Zag.js](https://zagjs.com/) state machines.
14
+
15
+ **Composable API.** No more prop drilling. Build complex UIs by composing small, focused parts that work together.
16
+
17
+ **Unstyled.** Zero design opinions. Use Tailwind, vanilla CSS, or any styling approach. You control every pixel.
18
+
19
+ **Server-rendered.** Components render on the server with PHP/Fluid, then hydrate on the client. No layout shift, great for SEO.
20
+
21
+ ## Quick Example
22
+
23
+ A tooltip with full accessibility support in just a few lines:
24
+
25
+ ```html
26
+ <ui:tooltip.root>
27
+ <ui:tooltip.trigger>Hover me</ui:tooltip.trigger>
28
+ <ui:tooltip.content>Tooltip content here</ui:tooltip.content>
29
+ </ui:tooltip.root>
30
+ ```
31
+
32
+ That's it. Keyboard support, focus handling, proper ARIA attributes - all handled.
33
+
34
+ ## Why This Exists
35
+
36
+ TYPO3 Fluid lacked an elegant solution for building robust, interactive components. The typical approach leads to bloated templates with complex conditional logic, poor accessibility, and custom JavaScript that's hard to maintain.
37
+
38
+ Fluid Primitives solves this by bringing proven patterns from the modern frontend ecosystem to TYPO3, while respecting its server-first architecture.
39
+
40
+ ## Acknowledgments
41
+
42
+ Built on the shoulders of giants:
43
+
44
+ - [Zag.js](https://zagjs.com/) - The state machine foundation
45
+ - [Radix UI](https://www.radix-ui.com/primitives) - API design inspiration
46
+ - [Base UI](https://base-ui.com/) - Component behavior patterns
47
+ - [Ark UI](https://ark-ui.com/) - Zag.js integration patterns
6
48
 
7
49
  ## Documentation
8
50
 
9
- The documentation can be found at [fluid-primitives.com](https://fluid-primitives.com).
51
+ The full documentation can be found at [fluid-primitives.com](https://fluid-primitives.com).
10
52
 
11
53
  ## Development
12
54
 
13
- See [github.com/jramke/fluid-primitives.com](https://github.com/jramke/fluid-primitives.com) for the development setup.
55
+ See [github.com/jramke/fluid-primitives.com](https://github.com/jramke/fluid-primitives.com) monorepo for the development setup.
@@ -1,12 +1,12 @@
1
1
  import { Component$1 as Component, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as accordion from "@zag-js/accordion";
3
- import * as _zag_js_types3 from "@zag-js/types";
3
+ import * as _zag_js_types2 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/Accordion/Accordion.d.ts
6
6
  declare class Accordion extends Component<accordion.Props, accordion.Api> {
7
7
  static name: string;
8
8
  initMachine(props: accordion.Props): Machine<any>;
9
- initApi(): accordion.Api<_zag_js_types3.PropTypes<{
9
+ initApi(): accordion.Api<_zag_js_types2.PropTypes<{
10
10
  [x: string]: any;
11
11
  }>>;
12
12
  render(): void;
@@ -1,13 +1,13 @@
1
1
  import { FieldAwareComponent$1 as FieldAwareComponent, FieldMachine, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as checkbox from "@zag-js/checkbox";
3
- import * as _zag_js_types7 from "@zag-js/types";
3
+ import * as _zag_js_types0 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/Checkbox/Checkbox.d.ts
6
6
  declare class Checkbox extends FieldAwareComponent<checkbox.Props, checkbox.Api> {
7
7
  static name: string;
8
8
  propsWithField(props: checkbox.Props, fieldMachine: FieldMachine): checkbox.Props;
9
9
  initMachine(props: checkbox.Props): Machine<any>;
10
- initApi(): checkbox.Api<_zag_js_types7.PropTypes<{
10
+ initApi(): checkbox.Api<_zag_js_types0.PropTypes<{
11
11
  [x: string]: any;
12
12
  }>>;
13
13
  render(): void;
@@ -1,12 +1,12 @@
1
1
  import { Component$1 as Component, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as clipboard from "@zag-js/clipboard";
3
- import * as _zag_js_types4 from "@zag-js/types";
3
+ import * as _zag_js_types7 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/Clipboard/Clipboard.d.ts
6
6
  declare class Clipboard extends Component<clipboard.Props, clipboard.Api> {
7
7
  static name: string;
8
8
  initMachine(props: clipboard.Props): Machine<any>;
9
- initApi(): clipboard.Api<_zag_js_types4.PropTypes<{
9
+ initApi(): clipboard.Api<_zag_js_types7.PropTypes<{
10
10
  [x: string]: any;
11
11
  }>>;
12
12
  render(): void;
package/dist/dialog.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Component$1 as Component, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as dialog from "@zag-js/dialog";
3
- import * as _zag_js_types2 from "@zag-js/types";
3
+ import * as _zag_js_types1 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/Dialog/Dialog.d.ts
6
6
  declare class Dialog extends Component<dialog.Props, dialog.Api> {
7
7
  static name: string;
8
8
  initMachine(props: dialog.Props): Machine<any>;
9
- initApi(): dialog.Api<_zag_js_types2.PropTypes<{
9
+ initApi(): dialog.Api<_zag_js_types1.PropTypes<{
10
10
  [x: string]: any;
11
11
  }>>;
12
12
  render(): void;
package/dist/form.js CHANGED
@@ -1 +1 @@
1
- import{Component as e,Machine as t,normalizeProps as n}from"./Client-CygooKu8.js";import{getFieldMachinesFor as r,registerFormMachine as i}from"./form.registry-Bv4jZGjo.js";import{debounce as a}from"@zag-js/utils";import{createAnatomy as o}from"@zag-js/anatomy";import{createMachine as s}from"@zag-js/core";const c=o(`form`).parts(`form`),l=c.build(),u=e=>e.ids?.form??`form:${e.id}:form`,d=e=>e.getById(u(e));function f(e,t){let{context:n,state:i,send:o,scope:s,prop:c}=e;function f(){return n.get(`values`)}function p(){return n.get(`errors`)}function m(){return n.get(`dirty`)}function h(){return n.get(`touched`)}function g(){return d(s)}let _=i.matches(`submitting`),v=Object.values(m()).length>0,y=Object.keys(p()).length>0,b=i.matches(`success`),x=i.matches(`error`),S=Object.values(h()).length>0,C=i.get(),w=c(`inputDebounceMs`)??100,T=w>0?a(e=>{o({type:`INPUT`,detail:{target:e}})},w):e=>{o({type:`INPUT`,detail:{target:e}})};return{isSubmitting:_,isDirty:v,isInvalid:y,isSuccessful:b,isError:x,getValues:f,getErrors:p,getDirty:m,getTouched:h,_userRenderFn:c(`render`),getFormEl:g,getAllFields(){return r(d(s))},getField(e){return this.getAllFields().get(e)},getAction(){let e=g();return e?.getAttribute(`action`)||``},reset(){o({type:`RESET`})},getFormProps(){return t.element({...l.form.attrs,noValidate:!0,id:u(s),"data-state":C,"data-submitting":_?``:void 0,"data-invalid":y?``:void 0,"data-dirty":v?``:void 0,"data-touched":S?``:void 0,onSubmit:async e=>{e.preventDefault();let t=e.currentTarget;n.set(`values`,new FormData(t)),o({type:`SUBMIT`,detail:{event:e,api:this}})},onReset:()=>{o({type:`RESET`,detail:{omitManualReset:!0}})},onInput:e=>{T(e.target)},onBlur:e=>{let t=e.target;!(t instanceof HTMLInputElement)&&!(t instanceof HTMLTextAreaElement)&&!(t instanceof HTMLSelectElement)&&!(t instanceof HTMLButtonElement&&t.getAttribute(`data-scope`)===`select`)||o({type:`BLUR`,detail:{target:t}})}})}}}const p=Object.freeze({status:`aborted`});function m(e,t,n){function r(n,r){if(n._zod||Object.defineProperty(n,`_zod`,{value:{def:r,constr:o,traits:new Set},enumerable:!1}),n._zod.traits.has(e))return;n._zod.traits.add(e),t(n,r);let i=o.prototype,a=Object.keys(i);for(let e=0;e<a.length;e++){let t=a[e];t in n||(n[t]=i[t].bind(n))}}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,`name`,{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,`init`,{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,`name`,{value:e}),o}const h=Symbol(`zod_brand`);function g(e,t){return typeof t==`bigint`?t.toString():t}function _(e){let t=!1;return{get value(){if(!t){let t=e();return Object.defineProperty(this,`value`,{value:t}),t}throw Error(`cached value already set`)}}}const v=Symbol(`evaluating`),y=`captureStackTrace`in Error?Error.captureStackTrace:(...e)=>{},b=_(()=>{if(typeof navigator<`u`&&navigator?.userAgent?.includes(`Cloudflare`))return!1;try{let e=Function;return new e(``),!0}catch{return!1}}),x={safeint:[-(2**53-1),2**53-1],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]},S=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,`_zod`,{value:e._zod,enumerable:!1}),Object.defineProperty(e,`issues`,{value:t,enumerable:!1}),e.message=JSON.stringify(t,g,2),Object.defineProperty(e,`toString`,{value:()=>e.message,enumerable:!1})},C=m(`$ZodError`,S),w=m(`$ZodError`,S,{Parent:Error});function T(e,t=e=>e.message){let n={},r=[];for(let i of e.issues)i.path.length>0?(n[i.path[0]]=n[i.path[0]]||[],n[i.path[0]].push(t(i))):r.push(t(i));return{formErrors:r,fieldErrors:n}}var E=class extends Error{constructor(e){super(`Server validation failed`),this.errors=e,this.name=`ValidationError`}};function D(e,t){if(!e)return{};let n=Object.fromEntries(t.entries()),r=e.safeParse(n);if(r.success)return{};let i=T(r.error).fieldErrors,a={};for(let e in i){if(!i[e])continue;a[e]={messages:i[e],value:A(t,e)}}return a}function O(e,t,n){let r={};for(let i in e){let a=i;t&&(a=a.replace(t+`.`,``)),r[a]={messages:e[i],value:A(n,a)}}return r}function k(e){let t=e;if(!(!t||!(`type`in t))){if(t.type===`checkbox`){let e=t;if(e.name){let t=e.form;if(t){let n=Array.from(t.querySelectorAll(`input[type="checkbox"][name="${CSS.escape(e.name)}"]`)),r=n.filter(e=>e.checked).map(e=>e.value||`on`);return n.length===1&&!n[0].value?n[0].checked:r}}return e.checked}if(t.type===`radio`){let e=t;if(e.form&&e.name){let t=e.form.querySelector(`input[type="radio"][name="${CSS.escape(e.name)}"]:checked`);return t?t.value:``}return e.checked?e.value:``}return t instanceof HTMLSelectElement&&t.multiple?Array.from(t.selectedOptions).map(e=>e.value):t.value}}function A(e,t){return e.getAll(t).length>1?e.getAll(t):e.get(t)}function j(e,t,n){if(e===``)return``;let r=e.endsWith(`[]`);r&&(e=e.slice(0,-2)),n&&(e=`${n}[${e}]`);let i=e.split(`[`,2),a=`${t}[${i[0]}]`;return i.length>1&&(a+=`[${i[1]}`),r&&(a+=`[]`),a}const M=s({initialState(){return`ready`},context({bindable:e}){return{values:e(()=>({defaultValue:new FormData})),initialValues:e(()=>({defaultValue:new FormData})),errors:e(()=>({defaultValue:{}})),dirty:e(()=>({defaultValue:{}})),touched:e(()=>({defaultValue:{}}))}},states:{ready:{},invalid:{},submitting:{},success:{},error:{}},on:{SUBMIT:{target:`submitting`,actions:[`validateAll`]},VALIDATE:{actions:[`validateAll`]},VALIDATE_FIELD:{actions:[`validateField`]},INVALID:{target:`invalid`},INPUT:{actions:[`handleInput`]},BLUR:{actions:[`handleBlur`]},RESET:{target:`ready`,actions:[`resetForm`]},ERROR:{target:`error`},SUCCESS:{target:`success`}},entry:[`setupFormListeners`],implementations:{actions:{validateAll({context:e,send:t,prop:n,state:r,action:i,event:a,scope:o}){let s=r.matches(`submitting`),c=n(`schema`);if(c){let n=e.get(`values`),r=D(c,n);if(e.set(`errors`,r),Object.keys(r).length>0){t({type:`INVALID`}),s&&i([`focusFirstInvalid`]);return}}if(!s){r.set(`ready`);return}let l=n(`onSubmit`);if(!l){t({type:`SUCCESS`});return}(async()=>{try{let r=await l({formData:e.get(`values`),api:a.detail.api,event:a.detail.event,post:async(e,t)=>{let r=new FormData,i=n(`objectName`),a=d(o),s=a?.getAttribute(`data-field-name-prefix`)||``;for(let[e,n]of t.entries()){if(e.includes(s)){r.append(e,n);continue}r.append(j(e,s,i),n)}let c=await fetch(e,{method:`POST`,body:r});if(c.status===422){let e=await c.json(),n=O(e,i,t);throw new E(n)}return c}});t(r?{type:`SUCCESS`}:{type:`ERROR`})}catch(n){if(n instanceof E){e.set(`errors`,n.errors),t({type:`INVALID`}),i([`focusFirstInvalid`]);return}t({type:`ERROR`})}})()},validateField({context:e,prop:t,event:n}){let r=t(`schema`);if(!r)return;let i=n.detail?.fieldName;if(!i)return;let a=e.get(`values`),o=e.get(`errors`),s=o[i],c=A(a,i);if(s){let e=s.value;if(JSON.stringify(c)===JSON.stringify(e))return}let l=D(r,a),u={...o};l[i]?u[i]=l[i]:delete u[i],e.set(`errors`,u)},handleInput({context:e,event:t,send:n}){let r=t,i=r?.detail?.target??r?.target??r?.currentTarget,a=i?.name;if(!a)return;let o=r?.detail?.value??k(i),s=e.get(`values`);s.set(a,o),e.set(`values`,s);let c=e.get(`initialValues`).get(a),l={...e.get(`dirty`)};l[a]=JSON.stringify(s.get(a))!==JSON.stringify(c),e.set(`dirty`,l);let u=e.get(`errors`),d=e.get(`touched`),f=!!u[a],p=!!d[a];(f||p)&&n({type:`VALIDATE_FIELD`,detail:{fieldName:a}})},handleBlur({context:e,send:t,prop:n,event:r}){let i=r,a=i?.detail?.target,o=a?.name;if(o||=a?.closest(`[data-scope="field"]`)?.getAttribute(`name`)||void 0,!o)return;let s={...e.get(`touched`)};s[o]=!0,e.set(`touched`,s);let c=a.form;if(c){let t=new FormData(c);e.set(`values`,t)}let l=n(`schema`);l&&t({type:`VALIDATE_FIELD`,detail:{fieldName:o}})},resetForm({context:e,scope:t,event:n}){let r=d(t);r&&!n?.detail?.omitManualReset&&r.reset();let i=r?new FormData(r):e.get(`initialValues`);e.set(`values`,i),e.set(`initialValues`,i),e.set(`errors`,{}),e.set(`touched`,{}),e.set(`dirty`,{})},focusFirstInvalid({context:e,scope:t}){let n=e.get(`errors`),r=Object.keys(n)[0];if(!r)return;let i=d(t);if(!i)return;let a=i.querySelector(`[name="${CSS.escape(r)}"]`);a?.focus(),(a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement)&&a.select()},setupFormListeners({scope:e,send:t}){let n=d(e);n&&n.addEventListener(`change`,e=>{t({type:`INPUT`,detail:{target:e.target}})},!0)}}}});var N=class extends e{static name=`form`;initMachine(e){let n=new t(M,e);return i(this.getElement(`form`),n),n}initApi(){return f(this.machine.service,n)}render(){let e=this.getElement(`form`);e&&(this.spreadProps(e,this.api.getFormProps()),this.api._userRenderFn?.(this))}};export{N as Form,E as ValidationError};
1
+ import{Component as e,Machine as t,normalizeProps as n}from"./Client-CygooKu8.js";import{getFieldMachinesFor as r,registerFormMachine as i}from"./form.registry-Bv4jZGjo.js";import{debounce as a}from"@zag-js/utils";import{createAnatomy as o}from"@zag-js/anatomy";import{createMachine as s}from"@zag-js/core";const c=o(`form`).parts(`form`),l=c.build(),u=e=>e.ids?.form??`form:${e.id}:form`,d=e=>e.getById(u(e));function f(e,t){let{context:n,state:i,send:o,scope:s,prop:c}=e;function f(){return n.get(`values`)}function p(){return n.get(`errors`)}function m(){return n.get(`dirty`)}function h(){return n.get(`touched`)}function g(){return d(s)}let _=i.matches(`submitting`),v=Object.values(m()).length>0,y=Object.keys(p()).length>0,b=i.matches(`success`),x=i.matches(`error`),S=Object.values(h()).length>0,C=i.get(),w=c(`inputDebounceMs`)??100,T=w>0?a(e=>{o({type:`INPUT`,detail:{target:e}})},w):e=>{o({type:`INPUT`,detail:{target:e}})};return{isSubmitting:_,isDirty:v,isInvalid:y,isSuccessful:b,isError:x,getValues:f,getErrors:p,getDirty:m,getTouched:h,_userRenderFn:c(`render`),getFormEl:g,getAllFields(){return r(d(s))},getField(e){return this.getAllFields().get(e)},getAction(){let e=g();return e?.getAttribute(`action`)||``},reset(){o({type:`RESET`})},getFormProps(){return t.element({...l.form.attrs,noValidate:!0,id:u(s),"data-state":C,"data-submitting":_?``:void 0,"data-invalid":y?``:void 0,"data-dirty":v?``:void 0,"data-touched":S?``:void 0,onSubmit:async e=>{e.preventDefault();let t=e.currentTarget;n.set(`values`,new FormData(t)),o({type:`SUBMIT`,detail:{event:e,api:this}})},onReset:()=>{o({type:`RESET`,detail:{omitManualReset:!0}})},onInput:e=>{T(e.target)},onBlur:e=>{let t=e.target;!(t instanceof HTMLInputElement)&&!(t instanceof HTMLTextAreaElement)&&!(t instanceof HTMLSelectElement)&&!(t instanceof HTMLButtonElement&&t.getAttribute(`data-scope`)===`select`)||o({type:`BLUR`,detail:{target:t}})}})}}}const p=Object.freeze({status:`aborted`});function m(e,t,n){function r(n,r){if(n._zod||Object.defineProperty(n,`_zod`,{value:{def:r,constr:o,traits:new Set},enumerable:!1}),n._zod.traits.has(e))return;n._zod.traits.add(e),t(n,r);let i=o.prototype,a=Object.keys(i);for(let e=0;e<a.length;e++){let t=a[e];t in n||(n[t]=i[t].bind(n))}}let i=n?.Parent??Object;class a extends i{}Object.defineProperty(a,`name`,{value:e});function o(e){var t;let i=n?.Parent?new a:this;r(i,e),(t=i._zod).deferred??(t.deferred=[]);for(let e of i._zod.deferred)e();return i}return Object.defineProperty(o,`init`,{value:r}),Object.defineProperty(o,Symbol.hasInstance,{value:t=>n?.Parent&&t instanceof n.Parent?!0:t?._zod?.traits?.has(e)}),Object.defineProperty(o,`name`,{value:e}),o}const h=Symbol(`zod_brand`);function g(e,t){return typeof t==`bigint`?t.toString():t}function _(e){let t=!1;return{get value(){if(!t){let t=e();return Object.defineProperty(this,`value`,{value:t}),t}throw Error(`cached value already set`)}}}const v=Symbol(`evaluating`),y=`captureStackTrace`in Error?Error.captureStackTrace:(...e)=>{},b=_(()=>{if(typeof navigator<`u`&&navigator?.userAgent?.includes(`Cloudflare`))return!1;try{let e=Function;return new e(``),!0}catch{return!1}}),x={safeint:[-(2**53-1),2**53-1],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]},S=(e,t)=>{e.name=`$ZodError`,Object.defineProperty(e,`_zod`,{value:e._zod,enumerable:!1}),Object.defineProperty(e,`issues`,{value:t,enumerable:!1}),e.message=JSON.stringify(t,g,2),Object.defineProperty(e,`toString`,{value:()=>e.message,enumerable:!1})},C=m(`$ZodError`,S),w=m(`$ZodError`,S,{Parent:Error});function T(e,t=e=>e.message){let n={},r=[];for(let i of e.issues)i.path.length>0?(n[i.path[0]]=n[i.path[0]]||[],n[i.path[0]].push(t(i))):r.push(t(i));return{formErrors:r,fieldErrors:n}}var E=class extends Error{constructor(e){super(`Server validation failed`),this.errors=e,this.name=`ValidationError`}};function D(e,t){if(!e)return{};let n=Object.fromEntries(t.entries()),r=e.safeParse(n);if(r.success)return{};let i=T(r.error).fieldErrors,a={};for(let e in i){if(!i[e])continue;a[e]={messages:i[e],value:A(t,e)}}return a}function O(e,t,n){let r={};for(let i in e){let a=i;t&&(a=a.replace(t+`.`,``)),r[a]={messages:e[i],value:A(n,a)}}return r}function k(e){let t=e;if(!(!t||!(`type`in t))){if(t.type===`checkbox`){let e=t;if(e.name){let t=e.form;if(t){let n=Array.from(t.querySelectorAll(`input[type="checkbox"][name="${CSS.escape(e.name)}"]`)),r=n.filter(e=>e.checked).map(e=>e.value||`on`);return n.length===1&&!n[0].value?n[0].checked:r}}return e.checked}if(t.type===`radio`){let e=t;if(e.form&&e.name){let t=e.form.querySelector(`input[type="radio"][name="${CSS.escape(e.name)}"]:checked`);return t?t.value:``}return e.checked?e.value:``}return t instanceof HTMLSelectElement&&t.multiple?Array.from(t.selectedOptions).map(e=>e.value):t.value}}function A(e,t){return e.getAll(t).length>1?e.getAll(t):e.get(t)}function j(e,t,n){if(e===``)return``;let r=e.endsWith(`[]`);r&&(e=e.slice(0,-2)),n&&(e=`${n}[${e}]`);let i=e.split(`[`,2),a=`${t}[${i[0]}]`;return i.length>1&&(a+=`[${i[1]}`),r&&(a+=`[]`),a}const M=s({initialState(){return`ready`},context({bindable:e}){return{values:e(()=>({defaultValue:new FormData})),initialValues:e(()=>({defaultValue:new FormData})),errors:e(()=>({defaultValue:{}})),dirty:e(()=>({defaultValue:{}})),touched:e(()=>({defaultValue:{}}))}},states:{ready:{},invalid:{},submitting:{},success:{},error:{}},on:{SUBMIT:{target:`submitting`,actions:[`validateAll`]},VALIDATE:{actions:[`validateAll`]},VALIDATE_FIELD:{actions:[`validateField`]},INVALID:{target:`invalid`},INPUT:{actions:[`handleInput`]},BLUR:{actions:[`handleBlur`]},RESET:{target:`ready`,actions:[`resetForm`]},ERROR:{target:`error`},SUCCESS:{target:`success`,actions:[`clearErrors`]}},entry:[`setupFormListeners`],implementations:{actions:{validateAll({context:e,send:t,prop:n,state:r,action:i,event:a,scope:o}){let s=r.matches(`submitting`),c=n(`schema`);if(c){let n=e.get(`values`),r=D(c,n);if(e.set(`errors`,r),Object.keys(r).length>0){t({type:`INVALID`}),s&&i([`focusFirstInvalid`]);return}}if(!s){r.set(`ready`);return}let l=n(`onSubmit`);if(!l){t({type:`SUCCESS`});return}(async()=>{try{let r=await l({formData:e.get(`values`),api:a.detail.api,event:a.detail.event,post:async(e,t)=>{let r=new FormData,i=n(`objectName`),a=d(o),s=a?.getAttribute(`data-field-name-prefix`)||``;for(let[e,n]of t.entries()){if(e.includes(s)){r.append(e,n);continue}r.append(j(e,s,i),n)}let c=await fetch(e,{method:`POST`,body:r});if(c.status===422){let e=await c.json(),n=O(e,i,t);throw new E(n)}return c}});t(r?{type:`SUCCESS`}:{type:`ERROR`})}catch(n){if(n instanceof E){e.set(`errors`,n.errors),t({type:`INVALID`}),i([`focusFirstInvalid`]);return}t({type:`ERROR`})}})()},validateField({context:e,prop:t,event:n}){let r=t(`schema`);if(!r)return;let i=n.detail?.fieldName;if(!i)return;let a=e.get(`values`),o=e.get(`errors`),s=o[i],c=A(a,i);if(s){let e=s.value;if(JSON.stringify(c)===JSON.stringify(e))return}let l=D(r,a),u={...o};l[i]?u[i]=l[i]:delete u[i],e.set(`errors`,u)},handleInput({context:e,event:t,send:n}){let r=t,i=r?.detail?.target??r?.target??r?.currentTarget,a=i?.name;if(!a)return;let o=r?.detail?.value??k(i),s=e.get(`values`);s.set(a,o),e.set(`values`,s);let c=e.get(`initialValues`).get(a),l={...e.get(`dirty`)};l[a]=JSON.stringify(s.get(a))!==JSON.stringify(c),e.set(`dirty`,l);let u=e.get(`errors`),d=e.get(`touched`),f=!!u[a],p=!!d[a];(f||p)&&n({type:`VALIDATE_FIELD`,detail:{fieldName:a}})},handleBlur({context:e,send:t,prop:n,event:r}){let i=r,a=i?.detail?.target,o=a?.name;if(o||=a?.closest(`[data-scope="field"]`)?.getAttribute(`name`)||void 0,!o)return;let s={...e.get(`touched`)};s[o]=!0,e.set(`touched`,s);let c=a.form;if(c){let t=new FormData(c);e.set(`values`,t)}let l=n(`schema`);l&&t({type:`VALIDATE_FIELD`,detail:{fieldName:o}})},resetForm({context:e,scope:t,event:n}){let r=d(t);r&&!n?.detail?.omitManualReset&&r.reset();let i=r?new FormData(r):e.get(`initialValues`);e.set(`values`,i),e.set(`initialValues`,i),e.set(`errors`,{}),e.set(`touched`,{}),e.set(`dirty`,{})},focusFirstInvalid({context:e,scope:t}){let n=e.get(`errors`),r=Object.keys(n)[0];if(!r)return;let i=d(t);if(!i)return;let a=i.querySelector(`[name="${CSS.escape(r)}"]`);a?.focus(),(a instanceof HTMLInputElement||a instanceof HTMLTextAreaElement)&&a.select()},setupFormListeners({scope:e,send:t}){let n=d(e);n&&n.addEventListener(`change`,e=>{t({type:`INPUT`,detail:{target:e.target}})},!0)},clearErrors({context:e}){e.set(`errors`,{}),e.set(`touched`,{})}}}});var N=class extends e{static name=`form`;initMachine(e){let n=new t(M,e);return i(this.getElement(`form`),n),n}initApi(){return f(this.machine.service,n)}render(){let e=this.getElement(`form`);e&&(this.spreadProps(e,this.api.getFormProps()),this.api._userRenderFn?.(this))}};export{N as Form,E as ValidationError};
@@ -1,13 +1,13 @@
1
1
  import { FieldAwareComponent$1 as FieldAwareComponent, FieldMachine, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as numberInput from "@zag-js/number-input";
3
- import * as _zag_js_types9 from "@zag-js/types";
3
+ import * as _zag_js_types4 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/NumberInput/NumberInput.d.ts
6
6
  declare class NumberInput extends FieldAwareComponent<numberInput.Props, numberInput.Api> {
7
7
  static name: string;
8
8
  propsWithField(props: numberInput.Props, fieldMachine: FieldMachine): numberInput.Props;
9
9
  initMachine(props: numberInput.Props): Machine<any>;
10
- initApi(): numberInput.Api<_zag_js_types9.PropTypes<{
10
+ initApi(): numberInput.Api<_zag_js_types4.PropTypes<{
11
11
  [x: string]: any;
12
12
  }>>;
13
13
  render(): void;
package/dist/popover.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Component$1 as Component, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as popover from "@zag-js/popover";
3
- import * as _zag_js_types1 from "@zag-js/types";
3
+ import * as _zag_js_types3 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/Popover/Popover.d.ts
6
6
  declare class Popover extends Component<popover.Props, popover.Api> {
7
7
  static name: string;
8
8
  initMachine(props: popover.Props): Machine<any>;
9
- initApi(): popover.Api<_zag_js_types1.PropTypes<{
9
+ initApi(): popover.Api<_zag_js_types3.PropTypes<{
10
10
  [x: string]: any;
11
11
  }>>;
12
12
  render(): void;
@@ -1,13 +1,13 @@
1
1
  import { FieldAwareComponent$1 as FieldAwareComponent, FieldMachine, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as radioGroup from "@zag-js/radio-group";
3
- import * as _zag_js_types8 from "@zag-js/types";
3
+ import * as _zag_js_types6 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/RadioGroup/RadioGroup.d.ts
6
6
  declare class RadioGroup extends FieldAwareComponent<radioGroup.Props, radioGroup.Api> {
7
7
  static name: string;
8
8
  propsWithField(props: radioGroup.Props, fieldMachine: FieldMachine): radioGroup.Props;
9
9
  initMachine(props: radioGroup.Props): Machine<any>;
10
- initApi(): radioGroup.Api<_zag_js_types8.PropTypes<{
10
+ initApi(): radioGroup.Api<_zag_js_types6.PropTypes<{
11
11
  [x: string]: any;
12
12
  }>>;
13
13
  render(): void;
package/dist/select.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { FieldAwareComponent$1 as FieldAwareComponent, FieldMachine, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as _zag_js_collection0 from "@zag-js/collection";
3
3
  import * as select from "@zag-js/select";
4
- import * as _zag_js_types6 from "@zag-js/types";
4
+ import * as _zag_js_types8 from "@zag-js/types";
5
5
 
6
6
  //#region Resources/Private/Primitives/Select/Select.d.ts
7
7
  declare class Select extends FieldAwareComponent<select.Props, select.Api> {
@@ -9,6 +9,7 @@ declare class Select extends FieldAwareComponent<select.Props, select.Api> {
9
9
  propsWithField(props: select.Props, fieldMachine: FieldMachine): select.Props;
10
10
  transformProps(props: select.Props): {
11
11
  collection: _zag_js_collection0.ListCollection<any>;
12
+ translations?: select.IntlTranslations | undefined;
12
13
  ids?: Partial<{
13
14
  root: string;
14
15
  content: string;
@@ -54,7 +55,7 @@ declare class Select extends FieldAwareComponent<select.Props, select.Api> {
54
55
  onInteractOutside?: ((event: select.InteractOutsideEvent) => void) | undefined;
55
56
  };
56
57
  initMachine(props: select.Props): Machine<any>;
57
- initApi(): select.Api<_zag_js_types6.PropTypes<{
58
+ initApi(): select.Api<_zag_js_types8.PropTypes<{
58
59
  [x: string]: any;
59
60
  }>, any>;
60
61
  render: () => void;
package/dist/tabs.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { Component$1 as Component, Machine$1 as Machine } from "./index-BpcuNDMI.js";
2
2
  import * as tabs from "@zag-js/tabs";
3
- import * as _zag_js_types0 from "@zag-js/types";
3
+ import * as _zag_js_types9 from "@zag-js/types";
4
4
 
5
5
  //#region Resources/Private/Primitives/Tabs/Tabs.d.ts
6
6
  declare class Tabs extends Component<tabs.Props, tabs.Api> {
7
7
  static name: string;
8
8
  initMachine(props: tabs.Props): Machine<any>;
9
- initApi(): tabs.Api<_zag_js_types0.PropTypes<{
9
+ initApi(): tabs.Api<_zag_js_types9.PropTypes<{
10
10
  [x: string]: any;
11
11
  }>>;
12
12
  render: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluid-primitives",
3
- "version": "0.16.0",
3
+ "version": "0.17.2",
4
4
  "description": "Client-side library for Fluid Primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -90,25 +90,25 @@
90
90
  "zod": "^4.3.6"
91
91
  },
92
92
  "dependencies": {
93
- "@zag-js/accordion": "^1.35.2",
94
- "@zag-js/anatomy": "^1.35.2",
95
- "@zag-js/checkbox": "^1.35.2",
96
- "@zag-js/clipboard": "^1.35.2",
97
- "@zag-js/collapsible": "^1.35.2",
98
- "@zag-js/collection": "^1.35.2",
99
- "@zag-js/core": "^1.35.2",
100
- "@zag-js/dialog": "^1.35.2",
101
- "@zag-js/dom-query": "^1.35.2",
102
- "@zag-js/number-input": "^1.35.2",
103
- "@zag-js/popover": "^1.35.2",
104
- "@zag-js/radio-group": "^1.35.2",
105
- "@zag-js/scroll-area": "^1.35.2",
106
- "@zag-js/select": "^1.35.2",
107
- "@zag-js/store": "^1.35.2",
108
- "@zag-js/tabs": "^1.35.2",
109
- "@zag-js/tooltip": "^1.35.2",
110
- "@zag-js/types": "^1.35.2",
111
- "@zag-js/utils": "^1.35.2",
112
- "@zag-js/vanilla": "^1.35.2"
93
+ "@zag-js/accordion": "^1.37.0",
94
+ "@zag-js/anatomy": "^1.37.0",
95
+ "@zag-js/checkbox": "^1.37.0",
96
+ "@zag-js/clipboard": "^1.37.0",
97
+ "@zag-js/collapsible": "^1.37.0",
98
+ "@zag-js/collection": "^1.37.0",
99
+ "@zag-js/core": "^1.37.0",
100
+ "@zag-js/dialog": "^1.37.0",
101
+ "@zag-js/dom-query": "^1.37.0",
102
+ "@zag-js/number-input": "^1.37.0",
103
+ "@zag-js/popover": "^1.37.0",
104
+ "@zag-js/radio-group": "^1.37.0",
105
+ "@zag-js/scroll-area": "^1.37.0",
106
+ "@zag-js/select": "^1.37.0",
107
+ "@zag-js/store": "^1.37.0",
108
+ "@zag-js/tabs": "^1.37.0",
109
+ "@zag-js/tooltip": "^1.37.0",
110
+ "@zag-js/types": "^1.37.0",
111
+ "@zag-js/utils": "^1.37.0",
112
+ "@zag-js/vanilla": "^1.37.0"
113
113
  }
114
114
  }