### 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))))
```