### Install and Run UIx Development Server Source: https://github.com/pitch-io/uix/blob/master/README.md Install development dependencies and start the shadow-cljs watch process for UIx development. ```bash npm i -D react@19.2.0 react-dom@19.2.0 react-refresh process clojure -M -m shadow.cljs.devtools.cli watch app ``` -------------------------------- ### UIx Quick Start Example (app.core.cljs) Source: https://github.com/pitch-io/uix/blob/master/README.md Defines a simple UIx application with a counter component using state management and buttons for increment/decrement. ```clojure (ns app.core (:require [uix.core :as uix :refer [defui $]] [uix.dom])) (defui button [{:keys [on-click children]}] ($ :button.btn {:on-click on-click} children)) (defui app [] (let [[state set-state!] (uix/use-state 0)] ($ :<> ($ button {:on-click #(set-state! dec)} "-") ($ :span state) ($ button {:on-click #(set-state! inc)} "+")))) (defonce root (uix.dom/create-root (js/document.getElementById "root"))) (defn start [] (uix.dom/render-root ($ app) root)) ``` -------------------------------- ### Install UIx Dependencies (npm) Source: https://github.com/pitch-io/uix/blob/master/README.md Install the necessary React and Node.js dependencies using npm. ```bash npm i -D react@19.2.0 react-dom@19.2.0 process ``` -------------------------------- ### Setup Development Tooling Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Configuration for development tooling, including fast-refresh and build error forwarding. ```clojure ;; dev/app/preload.cljs (ns app.preload (:require [uix.dev] [clojure.string :as str])) ;; Initializes fast-refresh runtime. (defonce __init-fast-refresh! (do (uix.dev/init-fast-refresh!) nil)) ;; Called by shadow-cljs after every reload. (defn ^:dev/after-load refresh [] (uix.dev/refresh!)) ;; Forwards cljs build errors to React Native's error view (defn build-notify [{:keys [type report]}] (when (= :build-failure type) (js/console.error (js/Error. report)))) ``` -------------------------------- ### Setup Development Tooling Source: https://github.com/pitch-io/uix/blob/master/docs/react-native.md Configure the preload namespace for UIx development, including initializing fast-refresh and handling build errors. ```clojure ;; dev/app/preload.cljs (ns app.preload (:require [uix.dev] [clojure.string :as str])) ;; Initializes fast-refresh runtime. (defonce __init-fast-refresh! (do (uix.dev/init-fast-refresh!) nil)) ;; Called by shadow-cljs after every reload. (defn ^:dev/after-load refresh [] (uix.dev/refresh!)) ;; Forwards cljs build errors to React Native's error view (defn build-notify [{:keys [type report]}] (when (= :build-failure type) (js/console.error (js/Error. report)))) ``` -------------------------------- ### UIx Quick Start Dependencies (deps.edn) Source: https://github.com/pitch-io/uix/blob/master/README.md Configure project dependencies in deps.edn, including shadow-cljs, UIx core, and UIx DOM. ```clojure {:deps {thheller/shadow-cljs {:mvn/version "3.2.1"} com.pitch/uix.core {:mvn/version "1.4.9"} com.pitch/uix.dom {:mvn/version "1.4.9"}}} ``` -------------------------------- ### Run React Native Project Source: https://github.com/pitch-io/uix/blob/master/docs/react-native.md Commands to start the shadow-cljs build, the React Native Metro bundler, and the application on iOS. ```sh # start cljs build clojure -M -m shadow.cljs.devtools.cli watch app # start RN's Metro bundler yarn start # start ios (or android) simulator, or connect a real device yarn ios ``` -------------------------------- ### Run React Native Project with UIx Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Commands to start the ClojureScript build, Metro bundler, and the React Native application. ```sh # start cljs build clojure -M -m shadow.cljs.devtools.cli watch app # start RN's Metro bundler yarn start # start ios (or android) simulator, or connect a real device yarn ios ``` -------------------------------- ### Install Testing Dependencies Source: https://github.com/pitch-io/uix/blob/master/docs/testing.md Installs the necessary npm dependencies for integration testing with React Testing Library, including `@testing-library/react`, `@testing-library/user-event`, `msw`, and `jsdom`. ```bash npm i -D @testing-library/react @testing-library/user-event msw jsdom global-jsdom ``` -------------------------------- ### Define and Use Basic Components Source: https://github.com/pitch-io/uix/blob/master/docs/components.md Define UIx components using `defui` and create elements with the `$` macro. This example shows a reusable button component and a simple app structure. ```clojure (ns my.app (:require [uix.core :refer [defui $]])) (defui button [{:keys [on-click children]}] ($ :button.btn {:on-click on-click} children)) (defui app [] ($ :div ($ button {:on-click #(js/console.log :minus)} "-") ($ :span "0") ($ button {:on-click #(js/console.log :plus)} "+"))) ``` -------------------------------- ### Install UIx Dependencies (deps.edn) Source: https://github.com/pitch-io/uix/blob/master/README.md Add UIx core and DOM libraries to your project's dependencies in deps.edn. ```clojure {:deps {com.pitch/uix.core {:mvn/version "1.4.9"} com.pitch/uix.dom {:mvn/version "1.4.9"}}} ``` -------------------------------- ### Basic CSS-in-CLJS component with uix.css Source: https://github.com/pitch-io/uix/blob/master/DEVLOG.md Example of creating a component with inline styles using the uix.css library. Dynamic values are handled via the CSS Variables API at runtime. ```clojure (ns my.app (:require [uix.core :as uix :refer [defui $]] [uix.css :refer [css]] [uix.css.adapter.uix])) (defn button [] ($ :button {:style (css {:font-size "14px" :background "#151e2c"})})) ``` -------------------------------- ### React/JavaScript Code Example Source: https://github.com/pitch-io/uix/blob/master/docs/chat-gpt.md This is an example of React/JavaScript code that defines an 'Item' component and a 'PackingList' component. It is used to demonstrate the translation to ClojureScript. ```javascript // input function Item({ name, isPacked }) { return
  • {name}
  • ; } export default function PackingList() { return (

    Sally Ride's Packing List

    ); } ``` -------------------------------- ### UIx Root Component Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Example of a root UI component using UIx and React Native components. ```clojure ;; src/app/core.cljs (ns app.core (:require [react-native :as rn] [uix.core :refer [$ defui]])) (defui root [] ($ rn/View {:style {:flex 1 :align-items :center :justify-content :center}} ($ rn/Text {:style {:font-size 32 :font-weight "500" :text-align :center}} "Hello! 👋"))) (defn start [] (.registerComponent rn/AppRegistry "MyApp" (constantly root))) ``` -------------------------------- ### Props Transferring with Spread Syntax in JavaScript Source: https://github.com/pitch-io/uix/blob/master/docs/components.md A JavaScript example demonstrating the use of object spread syntax for props transferring and merging. ```javascript import * as rhf from "react-hook-form"; function Form({ inputStyle, ...props }) { const { register, handleSubmit } = rhf.useForm(); return ( ); } ``` -------------------------------- ### UIx useEffect Handling Nil Return Source: https://github.com/pitch-io/uix/blob/master/docs/hooks.md Illustrates how UIx's `use-effect` hook automatically handles `nil` return values from the setup function, preventing React errors. The hook implicitly returns `js/undefined` when the setup function returns `nil`. ```clojure (uix/use-effect (fn [] (when false (prn :x))) ;; `nil` is not a function, nothing from here []) ``` -------------------------------- ### Configure Re-frame Linter Rule Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md Customize re-frame linting rules in `.uix/config.edn`. This example shows how to specify an alternative resolution for `subscribe`. ```clojure {:linters {:re-frame {:resolve-as {my.app/subscribe re-frame.core/subscribe}}}} ;; re-frame.core/subscribe is checked by default ``` -------------------------------- ### Configure re-frame interop linter Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md The re-frame interop linter can be configured in `.uix/config.edn`. This example shows how to specify an alternative resolution for `subscribe` calls if your project uses a different namespace. ```clojure {:linters {:re-frame {:resolve-as {my.app/subscribe re-frame.core/subscribe}}}} ;; re-frame.core/subscribe is checked by default ``` -------------------------------- ### UIx useEffect Handling Collection Return Source: https://github.com/pitch-io/uix/blob/master/docs/hooks.md Shows that UIx's `use-effect` hook also handles returning collections from the setup function without issue, as they are not functions and thus not treated as cleanup functions. ```clojure (uix/use-effect (fn [] (map inc [1 2 3])) ;; return value is a collection, nothing wrong here either []) ``` -------------------------------- ### Runtime Props Validation with UIx `defui` Source: https://github.com/pitch-io/uix/blob/master/docs/props-validation.md Shows how UIx's `defui` macro supports `:pre` conditions for runtime props validation, similar to `defn`. This example validates that the 'on-click' prop is a function. ```clojure (defui button [{:keys [children on-click]}] {:pre [(fn? on-click)]} ($ :button {:on-click on-click} children)) ``` -------------------------------- ### Print Component Source String Source: https://github.com/pitch-io/uix/blob/master/docs/utilities.md Use the `uix.core/source` macro to get the compile-time source string of a UIx component. This is useful for design systems to display code alongside live UI without duplication. ```clojure (ns app.ui (:require [uix.core :refer [$ defui]] [uix.dom])) (defui button [props] ($ :button.btn props)) ;; renders code block with `button`s source (uix.dom/render ($ :pre (uix.core/source button)) (js/document.getElementById "root")) ``` -------------------------------- ### Lazy Loading UIx Modal with Suspense Source: https://github.com/pitch-io/uix/blob/master/docs/code-splitting.md Demonstrates creating a lazy-loaded UIx modal component and integrating it with React's Suspense for fallback UI. This setup uses shadow-cljs's lazy loading API. ```clojure (ns app.core (:require [uix.core :refer [defui $]] [shadow.lazy])) ;; create shadow's loadable object that references `app.ui.lib/modal` component (def loadable-modal (shadow.lazy/loadable app.ui.lib/modal)) ;; create React's lazy component that loads the modal using shadow's API (def modal (uix.core/lazy #(shadow.lazy/load loadable-modal))) (defui app [] (let [[show-modal? set-show-modal!] (uix.core/use-state false)] ($ :div ($ :button {:on-click #(set-show-modal! true)}) ;; wrap the "lazy" `modal` with React's `Suspense` component and provide a fallback UI ($ uix.core/suspense {:fallback ($ :div "Loading...")} (when show-modal? ;; when rendered, React will load the module while displaying the fallback ;; and then render the component referenced from the module ($ modal {:on-close #(set-show-modal! false)})))))) ``` -------------------------------- ### Cross-Platform UI Code with Reader Conditionals Source: https://github.com/pitch-io/uix/blob/master/docs/server-side-rendering.md Write UI code that can run on both JVM and JavaScript environments using `.cljc` namespaces and reader conditionals. This example demonstrates conditionally including browser-specific APIs like `js/console.log`. ```clojure ;; ui.cljc (ns app.ui (:require [uix.core :refer [defui $]])) (defui title-bar [] ($ :div.title-bar ($ :h1 "Hello") ;; js/console.log doesn't exist on JVM, thus the code ;; should be included only for ClojureScript ($ :button {:on-click #?(:cljs #(js/console.log %) :clj nil)} "+"))) ;; server.clj (ns app.server (:require [uix.core :refer [$]] [uix.dom.server :as dom.server] [app.ui :as ui])) (defn handle-request "Generates HTML to be sent to the client" [] (dom.server/render-to-string ($ ui/title-bar))) ;; client.cljs (ns app.client (:require [uix.core :refer [$]] [uix.dom :as dom.client] [app.ui :as ui])) ;; Hydrates server generated HTML into dynamic React UI (dom.client/hydrate-root (js/document.getElementById "root") ($ ui/title-bar)) ``` -------------------------------- ### Runtime Props Validation with `defn` Source: https://github.com/pitch-io/uix/blob/master/docs/props-validation.md Demonstrates basic runtime props validation using `:pre` conditions in a standard Clojure `defn` function. This example shows how to ensure string types for 'fname' and 'lname' props. An assertion error occurs when a required prop is missing. ```clojure (defn user->full-name [{:keys [fname lname]}] {:pre [(string? fname) (string? lname)]} (str fname " " lname)) (user->full-name {:lname "Doe"}) ;; Execution error (AssertionError) at user/user->full-name (form-init2978563934614804694.clj:1). ;; Assert failed: (string? fname) ``` -------------------------------- ### Create React Native Project Source: https://github.com/pitch-io/uix/blob/master/docs/react-native.md Initialize a new React Native project and set up the entry point for UIx integration. ```sh npx react-native init MyApp cd MyApp echo 'import "./app/index.js";' > index.js ``` -------------------------------- ### Configure shadow-cljs for UIx Project Source: https://github.com/pitch-io/uix/blob/master/README.md Set up shadow-cljs.edn for browser builds, including module entries, output directories, and UIx preloads. ```clojure {:deps true :builds {:app {:target :browser :modules {:main {:entries [app.core] :init-fn app.core/start}} :output-dir "out" :asset-path "/out" :devtools {:preloads [uix.preload]}}}} ``` -------------------------------- ### React Button Component Example Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md A standard React functional component for a button that accepts an onClick handler and children. ```javascript function Button({ onClick, children }) { return ; } ; ``` -------------------------------- ### Creating and Using React Context in UIx (JS Interop) Source: https://github.com/pitch-io/uix/blob/master/DEVLOG.md Shows how to create a React context using `uix/create-context` and render its Provider component via JavaScript interop. ```clojure (def ctx (uix/create-context)) ($ (.-Provider ctx) {:value color-theme} ...) ``` -------------------------------- ### Hook Dependency Error: Missing Dependency Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md This example demonstrates a `use-effect` hook with an incomplete dependency list, which the linter will flag. ```clojure (defui component [{:keys [active? id]}] (use-effect (fn [] (when active? (rf/dispatch :user/set-id {:id id}))) [active?]) ;; error, update deps vector to [active? id] ...)) ``` -------------------------------- ### Build UIx Application for Production Source: https://github.com/pitch-io/uix/blob/master/README.md Generate a production-ready build of the UIx application using shadow-cljs release mode. ```bash clojure -M -m shadow.cljs.devtools.cli release app ``` -------------------------------- ### Creating a UIX Component for React Interop Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Shows how to create a UIX component and expose it for use in React. The `uix.core/as-react` helper is used to create an interop layer that accepts React props and calls the UIx component. Note that `as-react` does not transform camelCase keys to kebab-case. ```clojure (defui button [{:keys [on-click children]}] ($ :button {:on-click on-click} children)) (def Button (uix.core/as-react (fn [{:keys [onClick children]}] ($ button {:on-click onClick :children children})))) ``` ```javascript ``` -------------------------------- ### Defining and Instantiating a UIx Component Source: https://github.com/pitch-io/uix/blob/master/docs/elements.md Defines a simple UIx button component and shows how to instantiate it with props and children. ```clojure (defui button [{:keys [on-click children]}] ($ :button.btn {:on-click on-click} children)) ($ button {:on-click #(js/console.log :click)} "press me") ``` -------------------------------- ### UIx $ Macro Syntax vs React createElement Source: https://github.com/pitch-io/uix/blob/master/docs/components.md Illustrates the shorthand syntax of the UIx `$` macro for CSS IDs and classes, comparing it to React's `createElement`. ```js // React without JSX React.createElement("div", { onClick: f }, child1, child2); ``` ```clojure ;; UIx ($ :div#id.class {:on-click f} child1 child2) ``` -------------------------------- ### UIx Linter: Hooks in Conditions/Iteration Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Examples of UIx hooks being incorrectly called inside conditional statements or iteration functions, which violates the rules of hooks. ```clojure (defui component [{:keys [active?]}] (when active? (use-effect ...)) ;; error ...)) (defui component [{:keys [items]}] (for [item items] ($ list-item {:item item ;; error :on-click (use-callback #(rf/dispatch %) [item])}))) ``` -------------------------------- ### Using UIx Component in React Source: https://github.com/pitch-io/uix/blob/master/docs/interop-with-react.md Shows how to use the UIx component, exposed via `as-react`, as a standard React component. ```javascript ``` -------------------------------- ### Disable React Key Linter Rule Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md Configure UIx linters via a `.uix/config.edn` file. This example shows how to disable the :react-key linting rule. ```clojure {:linters {:react-key {:enabled? false}}} ;; the rule is enabled by default ``` -------------------------------- ### Run Tests Source: https://github.com/pitch-io/uix/blob/master/README.md Execute the test suite for the project. Ensure the correct Node.js version is used via nvm. ```bash scripts/test ``` -------------------------------- ### Component Syntax: Reagent vs UIx Source: https://github.com/pitch-io/uix/blob/master/docs/migrating-from-reagent.md Shows how to define components using `defn` in Reagent versus `defui` in UIx. ```clojure ;; Reagent (defn avatar [{:keys [src]}] [:img {:src src}]) ;; UIx (defui avatar [{:keys [src]}] ($ :img {:src src})) ``` -------------------------------- ### Hook Dependency Fix: Using Inline Function Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md This corrected example uses an inline function for the effect, allowing the linter to properly check dependencies. ```clojure (defui component [{:keys [active? id]}] (let [do-something (fn [active? id] (when active? (rf/dispatch :user/set-id {:id id})))] ;; now linter is able to check whether the effect meets deps requirements correctly (use-effect #(do-something active? id) [active? id]))) ``` -------------------------------- ### Create React Native App with UIx Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Command to create a new React Native project with UIx integration. ```sh npx create-uix-app@latest {{app-name}} --react-native ``` -------------------------------- ### Incorrect Dependency Type: JS Array Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md UIx expects Clojure vectors for hook dependencies, not JavaScript arrays. This example shows the incorrect usage. ```clojure (defui component [{:keys [html]}] (let [html (use-memo #(sanitize-html html) #js [html])] ;; incorrect ...)) ``` -------------------------------- ### UIx React Context Props Conversion Source: https://github.com/pitch-io/uix/blob/master/DEVLOG.md Example of shallowly converting Clojure props to a JS object for React components. This was previously problematic for non-JS primitives but is now fixed. ```clojure ($ ctx {:value {:bg "#000" :text "#fafafa"}} ...) ``` ```clojure ($ ctx {:value :hello} ...) ``` -------------------------------- ### Component Props: Reagent vs UIx Source: https://github.com/pitch-io/uix/blob/master/docs/migrating-from-reagent.md Demonstrates how component props are handled, with Reagent using positional arguments and UIx using a single map of props. ```clojure ;; Reagent, positional arguments (defn button [{:keys [on-click]} text] …) [button {:on-click f} "press"] ;; UIx, a single argument of props (defui button [{:keys [on-click text]}] …) ($ button {:on-click f :text "press"}) ``` -------------------------------- ### Creating UIx Elements with the `$` Macro Source: https://github.com/pitch-io/uix/blob/master/docs/elements.md Demonstrates the basic usage of the `$` macro for creating DOM elements, UIx components, and JS React components. ```clojure ;; DOM element ($ :button#save.btn.primary {:disabled false} "Save") ;; UIx component instance ($ my-button {:on-click f} "Save") ;; JS React component instance ($ Button {:on-click f} "Save") ``` -------------------------------- ### Verify DOM Attributes at Compile Time Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md UIx attempts to verify DOM attributes during compilation. This snippet shows an example of an invalid DOM property that triggers a warning. ```clojure ($ :div {:autoplay true}) ;; WARNING: Invalid DOM property :autoplay. Did you mean :auto-play? ``` -------------------------------- ### Creating DOM Elements with `$` Source: https://github.com/pitch-io/uix/blob/master/docs/elements.md Shows how to create a simple DOM element with attributes and text content using the `$` macro. ```clojure ($ :button {:title "Submit"} "press me") ``` -------------------------------- ### Basic State Hook Usage Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Demonstrates the basic usage of the `use-state` hook for managing local component state in UIx. ```clojure (defui form [] (let [[value set-value!] (uix.core/use-state "")] ($ :input {:value value :on-change #(set-value! value (.. % -target -value))}))) ``` -------------------------------- ### Using React Component in UIx Source: https://github.com/pitch-io/uix/blob/master/docs/interop-with-react.md Demonstrates how to use a React component within a UIx component, showing prop conversion rules. ```clojure ($ Button {:on-click #(js/console.log :click) :title "this is a button" :style {:border "1px solid red"} :class :button} "press me") ``` -------------------------------- ### Clojure Form Component with Manual Merge Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Illustrates a Clojure form component where props are merged manually. This example shows the limitation when trying to merge JavaScript objects with Clojure maps. ```clojure (ns app.core (:require [uix.core :as uix :refer [defui $]] ["react-hook-form" :as rhf])) (defui form [{:keys [input-style]}] (let [f (rhf/useForm)] ($ :form {:on-submit (.-handleSubmit f)} ($ :input (merge {:style input-style} ;; can't merge JS object returned from .register call ;; with Clojure map above (.register f "first-name")))))) ``` -------------------------------- ### Compile-time Props Validation with UIx `:props` Source: https://github.com/pitch-io/uix/blob/master/docs/props-validation.md Enables compile-time props validation in UIx components by using `:props` assertions with `clojure.spec`. This example defines a spec for a button and applies it to the component. ```clojure (s/def :prop/on-click fn?) (s/def ::button (s/keys :req-un [:prop/on-click])) (defui button [{:keys [children on-click] :as props}] {:props [::button]} ($ :button {:on-click on-click} children)) ``` -------------------------------- ### Use Keyword Elements in UI Source: https://github.com/pitch-io/uix/blob/master/docs/react-native.md Demonstrates writing UI code using keywords for React Native components, leveraging the custom '$' macro. ```clojure (ns app.core (:require [uix.core :refer [defui]] [app.uix :refer [$]])) (defui root [] ($ :view {:style {:flex 1 :align-items :center :justify-content :center}} ($ :text {:style {:font-size 32 :font-weight "500" :text-align :center}} "Hello! 👋"))) ``` -------------------------------- ### UIx Compile-Time Props Validation with Clojure Spec Source: https://github.com/pitch-io/uix/blob/master/DEVLOG.md Example of enabling compile-time props validation using clojure.spec. It defines a spec for a button component and shows how UIx warns about missing required props. ```clojure (s/def :prop/on-click fn?) (s/def ::button (s/keys :req-un [:prop/on-click])) (defui button [{:keys [children on-click] :as props}] {:props [::button]} ($ :button {:on-click on-click} children)) ``` ```clojure ($ button {} "press me") ``` -------------------------------- ### Import UIx Configuration for clj-kondo Source: https://github.com/pitch-io/uix/blob/master/docs/code-linting.md Integrate UIx linting rules with clj-kondo by importing its configuration. This command also copies necessary configs and skips initial linting. ```bash clj-kondo --lint "$(clojure -Spath)" --copy-configs --skip-lint ``` -------------------------------- ### Configure Preact as React Replacement Source: https://github.com/pitch-io/uix/blob/master/docs/preact.md Add this option to your `shadow-cljs.edn` file to map `react` and `react-dom` imports to Preact. ```clojure :js-options {:resolve {"react" {:target :npm :require "preact/compat"} "react-dom" {:target :npm :require "preact/compat"} "react-dom/client" {:target :npm :require "preact/compat/client"}}} ``` -------------------------------- ### Create Expo App with UIx Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Command to create a new Expo project with UIx integration. ```sh npx create-uix-app@latest {{app-name}} --expo ``` -------------------------------- ### Use vector for hook dependencies, not JS array Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md UIx expects a vector of dependencies for hooks, not a JavaScript array, to maintain Clojure idiomaticity and facilitate interop. The 'correct' example demonstrates the expected vector usage. ```clojure (defui component [{:keys [html]}] (let [html (use-memo #(sanitize-html html) #js [html])] ;; incorrect ...)) ``` ```clojure (defui component [{:keys [html]}] (let [html (use-memo #(sanitize-html html) [html])] ;; correct ...)) ``` -------------------------------- ### UIx Defui with Props Spreading Syntax Source: https://github.com/pitch-io/uix/blob/master/DEVLOG.md Demonstrates UIx's syntactic sugar for props spreading, similar to Helix. ```clojure (defui button [{:keys [style] props :&}] ($ :div {:style style} ($ MaterialButton {:theme "light" :& props}))) ``` -------------------------------- ### Reusable State Logic with use-validation Source: https://github.com/pitch-io/uix/blob/master/docs/state.md Encapsulates state management and validation logic into a reusable hook. This example shows how to create a custom hook `use-validation` to manage a value and apply updates only when a validation function passes. ```clojure (defn use-validation [initial-value valid?] (let [[value set-value!] (uix.core/use-state initial-value) on-change #(let [v (.. % -target -value)] (when (valid? v) (set-value! v)))] [value on-change])) (defui form [] (let [[value on-change] (use-validation "" #(not (empty? %)))] ($ :input {:value value :on-change on-change}))) ``` -------------------------------- ### Element Syntax: Reagent vs UIx Source: https://github.com/pitch-io/uix/blob/master/docs/migrating-from-reagent.md Illustrates the difference in element syntax between Reagent's vector-based Hiccup and UIx's '$' macro. ```clojure ;; Reagent [:div#id.class {:on-click f} [:div]] ;; UIx ($ :div#id.class {:on-click f} ($ :div)) ``` -------------------------------- ### React useEffect Returning Nil Value Source: https://github.com/pitch-io/uix/blob/master/docs/hooks.md Shows how returning `nil` (which compiles to `null` in JS) from a React effect hook's setup function also causes an error, as `null` is neither a function nor `undefined`. ```clojure (react/useEffect (fn [] (when false (prn :x))) ;; returns `nil` and thus React throws #js []) ``` -------------------------------- ### Shadow-cljs Build Configuration for Code-Splitting Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Configure shadow-cljs.edn to enable module loading for code-splitting. ```clojure {:module-loader true :modules {:main {:entries [app.core]}} :ui-lib {:entries [app.ui.lib} :depends-on #{:main}}} ``` -------------------------------- ### Cross-Platform Context with defcontext Source: https://github.com/pitch-io/uix/blob/master/docs/hooks.md Demonstrates `defcontext` for creating context that works on both JVM and JS. It defines a theme context, a hook `use-dark-theme?` to consume it, and components that conditionally render based on the theme. ```clojure (defcontext *theme* :light) (defhook use-dark-theme? [] (= :dark (use-context *theme*))) (defui top-bar [] (let [dark-theme? (use-dark-theme?)] ($ :div {:style {:color (if dark-theme? "white" "black")}} "top bar"))) (defui app [] ($ *theme* {:value :dark} ($ top-bar))) ``` -------------------------------- ### Example of Compile-time Props Linter Warning Source: https://github.com/pitch-io/uix/blob/master/docs/props-validation.md Illustrates a scenario where UIx emits a compiler warning due to missing required props when using compile-time validation. This occurs when the `button` component is called with an empty props map. ```clojure ($ button {} "press me") ``` -------------------------------- ### Basic Local State with useState Source: https://github.com/pitch-io/uix/blob/master/docs/state.md Demonstrates how to use `uix.core/use-state` to manage local component state. The state updating function is suffixed with '!' to denote mutation. ```clojure (defui form [] (let [[value set-value!] (uix.core/use-state "")] ($ :input {:value value :on-change #(set-value! (.. % -target -value))}))) ``` -------------------------------- ### Using Refs with DOM Elements in UIx Source: https://github.com/pitch-io/uix/blob/master/docs/components.md Demonstrates how to use `use-ref` to create a reference to a DOM element and interact with it, such as focusing the input. ```clojure (defui form [] (let [ref (uix.core/use-ref)] ($ :form ($ :input {:ref ref}) ($ :button {:on-click #(.focus @ref)} "press to focus on input")))) ``` -------------------------------- ### UIx useEffect Accidental Function Return Source: https://github.com/pitch-io/uix/blob/master/docs/hooks.md Warns about the potential for accidentally returning a function (like a transducer) from a UIx `use-effect` setup function, which would be executed as a cleanup function. This highlights the need to be mindful of implicit returns in ClojureScript. ```clojure (uix/use-effect (fn [] (map inc)) ;; return value is a function (transducer), []) ;; it's gonna be executed as a cleanup function, ## is that intended? ``` -------------------------------- ### Configure shadow-cljs Build Source: https://github.com/pitch-io/uix/blob/master/docs/react-native.md Set up the shadow-cljs build configuration for React Native, specifying the target, init function, and output directory. ```clojure ;; shadow-cljs.edn {:deps true :builds {:app {:target :react-native :init-fn app.core/start :output-dir "app" :compiler-options {:source-map-path "app/" :source-map-include-sources-content true :warnings-as-errors true} :devtools {:preloads [app.preload] :build-notify app.preload/build-notify}}}} ``` -------------------------------- ### React useEffect Returning Non-Function Value Source: https://github.com/pitch-io/uix/blob/master/docs/hooks.md Illustrates a scenario in React where returning a non-function value (like a keyword) from an effect hook's setup function will cause an error. This highlights the need for explicit `js/undefined` return in pure React. ```clojure (react/useEffect (fn [] :keyword) ;; returning `:keyword` here will throw #js []) ``` -------------------------------- ### Syncing UIx with Reagent and re-frame Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Shows how to sync UIx components with Reagent's reactions and re-frame subscriptions using specific hooks. ```clojure (ns my.app (:require [reagent.core :as r] [uix.re-frame :as urf] [uix.core :as uix :refer [defui $]])) (def counter (r/atom 0)) (defui title-bar [] (let [n (urf/use-reaction counter) ;; Reagent's reaction title (urf/use-subscribe [:app/title])] ;; re-frame subscription ($ :div title ($ :button {:on-click #(swap! counter inc)} n)))) ``` -------------------------------- ### Unsafe set-state in effect hook without dependencies Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Avoid calling set-state directly within a use-effect hook without specifying dependencies. This can lead to infinite update loops. The 'fix' example shows how to provide a dependency array to control when the effect runs. ```clojure (defui component [{:keys [active? id]}] (let [[value set-value] (use-state 0)] (use-effect (fn [] (set-value (inc value)))))) ;; error ``` ```clojure (defui component [{:keys [active? id]}] (let [[value set-value] (use-state 0)] (use-effect (fn [] (set-value (inc value))) [value]))) ;; fix: only run hook when value changes ``` -------------------------------- ### Basic HTML Structure for UIx App Source: https://github.com/pitch-io/uix/blob/master/README.md A minimal HTML file with a root element and script tag for the UIx application. ```html
    ``` -------------------------------- ### Creating Class-Based React Components in UIx Source: https://github.com/pitch-io/uix/blob/master/docs/components.md Shows how to create a class-based React component, like an error boundary, using `uix.core/create-class`. ```clojure (def error-boundary (uix.core/create-class {:displayName "error-boundary" :getInitialState (fn [] #js {:error nil}) :getDerivedStateFromError (fn [error] #js {:error error}) :componentDidCatch (fn [error error-info] (this-as this (let [props (.. this -props -argv)] (when-let [on-error (:on-error props)] (on-error error))))) :render (fn [] (this-as this (if (.. this -state -error) ($ :div "error") (.. this -props -children))))})) ($ error-boundary {:on-error js/console.error} ($ some-ui-that-can-error)) ``` -------------------------------- ### shadow-cljs Build Configuration for Modules Source: https://github.com/pitch-io/uix/blob/master/docs/code-splitting.md Configures the shadow-cljs build to enable module loading and define separate modules for the main application and the UI library. ```clojure {:module-loader true :modules {:main {:entries [app.core]} :ui-lib {:entries [app.ui.lib] :depends-on #{:main}}}} ``` -------------------------------- ### Add Build Configuration Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Shadow-cljs build configuration for React Native projects. ```clojure ;; shadow-cljs.edn {:deps true :builds {:app {:target :react-native :init-fn app.core/start :output-dir "app" :compiler-options {:source-map-path "app/" :source-map-include-sources-content true :warnings-as-errors true} :devtools {:preloads [app.preload] :build-notify app.preload/build-notify}}}} ``` -------------------------------- ### Ref Forwarding for UIx Components Source: https://github.com/pitch-io/uix/blob/master/docs/repomix-output.llm.md Illustrates how to use `uix.core/forward-ref` to correctly handle refs injected by non-UIx components into UIx elements. ```clojure (defui button [{:keys [ref children on-click onMouseDown]}] ;; both `ref` and `onMouseDown` were injected by `Menu` ...) (def button-forwarded (uix/forward-ref button)) ($ Menu ($ button-forwarded {:on-click handle-click} "press me)) ``` -------------------------------- ### Memoize Components for Performance Source: https://github.com/pitch-io/uix/blob/master/docs/components.md Demonstrates how to use `uix.core/memo` or the `^:memo` tag to memoize components, preventing unnecessary re-renders when props haven't changed. ```clojure (defui ^:memo child [props] ...) (defui parent [] ($ child {:x 1})) ``` -------------------------------- ### Inline Components with Anonymous Functions Source: https://github.com/pitch-io/uix/blob/master/docs/components.md Demonstrates creating inline components using anonymous functions with `uix.core/fn` for cleaner composition when passing components as props. ```clojure (defui ui-list [{:keys [key-fn data item]}] ($ :div (for [x data] ($ item {:data x :key (key-fn x)})))) (defui list-item [{:keys [data]}] ($ :div (:id data))) ($ ui-list {:key-fn :id :data [{:id 1} {:id 2} {:id 3}] :item list-item}) ``` ```clojure (defui ui-list [{:keys [key-fn data item]}] ($ :div (for [x data] ($ item {:data x :key (key-fn x)})))) ($ ui-list {:key-fn :id :data [{:id 1} {:id 2} {:id 3}] :item (uix/fn [{:keys [data]}] ($ :div (:id data)))}) ``` -------------------------------- ### UIx Defui with Memoization Source: https://github.com/pitch-io/uix/blob/master/DEVLOG.md Shows how to enable React component memoization directly within the defui macro using the :memo meta tag. ```clojure (defui ^:memo component [props] ...) ``` -------------------------------- ### Rendering Reagent Component in UIx Source: https://github.com/pitch-io/uix/blob/master/docs/migrating-from-reagent.md Demonstrates how to render a Reagent component within a UIx component using `r/as-element`. ```clojure [reagent.core :as r] ($ :div (r/as-element [:div "hello"]))) ``` -------------------------------- ### Configure shadow-cljs for UIx Hot Reloading Source: https://github.com/pitch-io/uix/blob/master/docs/hot-reloading.md Add `uix.preload` to your shadow-cljs build's `:preloads` to enable hot reloading. This ensures the necessary modules are loaded only in development environments. ```clojure ;; shadow-cljs.edn {:builds {:build-id {:devtools {:preloads [uix.preload]}}}} ``` -------------------------------- ### Configure Keyword Elements for RN Source: https://github.com/pitch-io/uix/blob/master/docs/react-native.md Set up a macro to enable using keywords as React Native components within UIx. ```clojure ;; src/app/uix.cljc (ns app.uix #?(:cljs (:require-macros [app.uix])) (:require [uix.core] [uix.compiler.attributes :as attrs] #?(:cljs [react-native]))) (defn dash->camel [k] (let [name #?(:cljs (attrs/dash-to-camel (name k)) :clj (name (attrs/camel-case-dom k)))] (str (.toUpperCase ^String (subs name 0 1)) (subs name 1)))) #?(:cljs (defn rn-component [cname] (aget react-native cname))) #?(:clj (defmacro $ [tag & args] (if (and (keyword? tag) (not= :<> tag)) (let [cname (dash->camel tag)] `(uix.core/$ (rn-component ~cname) ~@args)) `(uix.core/$ ~tag ~@args)))) ```