Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5e6105c
Merge main into develop
github-actions[bot] Jan 26, 2026
c5148a6
feat(Truncate): improve text truncation logic, introduced `render` prop
RostyslavNihrutsa Jan 30, 2026
3667446
refactor(Select): add explicit `type` modifier to exported props
RostyslavNihrutsa Jan 30, 2026
bfe60ca
style(Truncate): enhance code readability and consistency with format…
RostyslavNihrutsa Jan 30, 2026
4bde7cf
chore: merge pull request #59 from RostyslavNihrutsa/develop
atldays Jan 30, 2026
46ada1d
refactor(plugin): rename file-related options and add splitChunks opt…
atldays Jan 31, 2026
1a8eaa1
fix(plugin): correct spacing in conditional for resource.includes check
atldays Jan 31, 2026
2cebafc
refactor(UIProvider): add `container` prop for custom DOM element att…
atldays Jan 31, 2026
10206b7
refactor(plugin): enhance splitChunks logic with improved naming and …
atldays Jan 31, 2026
563ad34
refactor(ThemeProvider): add `container` and enhance `storage` prop f…
atldays Feb 1, 2026
894a43c
feat(plugin): extend plugin options and improve splitChunks logic
atldays Feb 1, 2026
dd7c2ee
docs(README): update documentation for components, plugin options, an…
atldays Feb 1, 2026
26c258a
refactor(Truncate): extract `calculateMiddleTruncate` to a utility fi…
RostyslavNihrutsa Feb 1, 2026
09e3a79
feat(TextField): add strict number input mode with sanitization logic
RostyslavNihrutsa Feb 2, 2026
bdb7659
chore: merge pull request #60 from RostyslavNihrutsa/develop
addon-stack Feb 3, 2026
02aeebc
Merge remote-tracking branch 'origin/develop' into develop
atldays Feb 4, 2026
b117c2d
docs: add `strict` prop to TextField and enhance Truncate functionality
atldays Feb 4, 2026
1cb3a58
refactor: enhance theme handling and rename plugin options
atldays Feb 4, 2026
d6a0ba1
chore(deps): update `adnbn` to v0.5.7 and simplify override configura…
atldays Feb 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 51 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ This library now ships with dedicated documentation files for each component in
- [IconButton](docs/IconButton.md)
- [List](docs/List.md) (covers List and ListItem)
- [Modal](docs/Modal.md)
- [Odometer](docs/Odometer.md) (component + useOdometer hook)
- [Odometer](docs/Odometer.md) (component + `useOdometer` hook)
- [ScrollArea](docs/ScrollArea.md)
- [Select](docs/Select.md)
- [SvgSprite](docs/SvgSprite.md)
- [Switch](docs/Switch.md)
- [Tabs](docs/Tabs.md) (includes Tabs, TabsList, TabsTrigger, TabsContent)
- [Tabs](docs/Tabs.md) (includes `Tabs`, `TabsList`, `TabsTrigger`, `TabsContent`)
- [Tag](docs/Tag.md)
- [TextArea](docs/TextArea.md)
- [TextField](docs/TextField.md)
Expand All @@ -83,7 +83,7 @@ This library now ships with dedicated documentation files for each component in
- [View](docs/View.md)
- [ViewDrawer](docs/ViewDrawer.md)
- [ViewModal](docs/ViewModal.md)
- [Viewport](docs/Viewport.md) (ViewportProvider + useViewport)
- [Viewport](docs/Viewport.md) (`ViewportProvider` + `useViewport`)

Notes:

Expand Down Expand Up @@ -134,15 +134,40 @@ export default defineConfig({
plugins: [
ui({
themeDir: "./theme", // Directory for theme files
configFileName: "ui.config", // Name of config files
styleFileName: "ui.style", // Name of style files
configName: "ui.config", // Name of config files
styleName: "ui.style", // Name of style files
mergeConfig: true, // Merge configs from different directories
mergeStyles: true, // Merge styles from different directories
splitChunks: true, // Enable automatic chunk splitting for components
}),
],
});
```

### Plugin Options

| Option | Type | Default | Description |
| :------------ | :------------------------------------------------- | :------------ | :----------------------------------------------------------------------------------------------------- |
| `themeDir` | `string` | `"."` | Directory path where plugin configuration and style files are located. |
| `configName` | `string` | `"config.ui"` | Name of the configuration file. |
| `styleName` | `string` | `"style.ui"` | Name of the SCSS style file. |
| `mergeConfig` | `boolean` | `true` | Whether to merge configuration files from different directories. |
| `mergeStyles` | `boolean` | `true` | Whether to merge style files from different directories. |
| `splitChunks` | `boolean \| (name: string) => string \| undefined` | `true` | Enables automatic chunk splitting. If a function is provided, it can be used to customize chunk names. |

#### Customizing Chunk Names

You can pass a callback function to `splitChunks` to customize the generated chunk names:

```ts
ui({
splitChunks: name => {
if (name === "button") return "ui-core-button";
return `ui-${name}`;
},
});
```

### Configuration Files

The `addon-ui` configuration is designed to retrieve configuration from each extension separately, allowing for
Expand Down Expand Up @@ -271,7 +296,7 @@ extensions with the same functionality but different visual appearances.

### Global Theme Customization

You can customize the theme globally by passing props to the UIProvider:
You can customize the theme globally by passing props to the `UIProvider`:

```jsx
import {UIProvider} from "addon-ui";
Expand All @@ -289,13 +314,26 @@ const customTheme = {
icons: {
// Custom icons
},
// Specify the DOM element to set theme/view/browser attributes on
container: "#app-root",
};

function App() {
return <UIProvider {...customTheme}>{/* Your application */}</UIProvider>;
}
```

### UIProvider Props

| Prop | Type | Default | Description |
| :----------- | :----------------------------- | :---------- | :-------------------------------------------------------- |
| `components` | `ComponentsProps` | `{}` | Component-specific configuration overrides. |
| `icons` | `Icons` | `{}` | Custom SVG icons registration. |
| `extra` | `ExtraProps` | `{}` | App-wide extra properties. |
| `storage` | `ThemeStorageContract \| true` | `undefined` | Persistence storage for theme settings. |
| `container` | `string \| Element \| false` | `"html"` | Target element for attributes. Set to `false` to disable. |
| `view` | `string` | `undefined` | Custom view identifier for specific styling. |

### Using Extra Props

Extra Props is a powerful feature that allows you to extend component props with custom properties. This is particularly
Expand Down Expand Up @@ -438,12 +476,13 @@ function App() {

## Theming and style reuse

- Global theme tokens (colors, typography, spacing, transitions) live in your ui.style.scss. Components consume them
through fallbacks.
- Each component also exposes its own `--component-*` variables. See the CSS variables tables in the docs to know
exactly what you can override.
- Light/dark modes: use `@import "addon-ui/theme";` and the provided `@include light { ... }` / `@include dark { ... }`
mixins in your theme SCSS to scope tokens per color scheme.
- Global theme tokens (colors, typography, spacing, transitions) live in your `ui.style.scss`.
- Each component also exposes its own `--component-*` variables. See the CSS variables tables in the docs to know exactly what you can override.
- **Theme Mixins**: Use `@import "addon-ui/theme";` to access `@include light { ... }` and `@include dark { ... }` mixins.
- **Universal Targeting**: These mixins are container-agnostic. They work correctly whether the `theme` attribute is on a parent element or directly on the component itself.
- **Context-Aware**:
- When used at the top level, they generate global selectors: `[theme="dark"] { ... }`.
- When used inside a component, they generate scoped selectors: `[theme="dark"] .my-comp, .my-comp[theme="dark"] { ... }`.

## Radix UI and third-party integrations

Expand Down
21 changes: 19 additions & 2 deletions docs/TextField.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ export function Example() {
<TextField accent={TextFieldAccent.Success} placeholder="Success" />
<TextField accent={TextFieldAccent.Error} placeholder="Error" />

{/* Strict numeric input */}
<TextField type="number" strict placeholder="Only numbers allowed" />

{/* Full width and content slots */}
<TextField fullWidth before={<span>+1</span>} after={<span>USD</span>} placeholder="With addons" />

Expand Down Expand Up @@ -80,6 +83,7 @@ Only the prop name, type, and default are listed below.
| `afterClassName` | `string` | — |
| `beforeClassName` | `string` | — |
| `type` | `ComponentProps<'input'>['type']` | `'text'` |
| `strict` | `boolean` | `false` |
| HTML input attrs | all standard `input` attributes (e.g., `value`, `defaultValue`, `onChange`, `placeholder`, `name`, `id`, etc.) | — |

Note: Defaults may also be provided globally via theme/config (`UIProvider`, `ui.config.ts`). Local props take precedence over global config.
Expand Down Expand Up @@ -123,9 +127,14 @@ Only variables actually referenced in `src/components/TextField/text-field.modul
| `--text-field-line-height` | `var(--text-field-line-height, var(--line-height, 1 rem))` |
| `--text-field-padding` | `var(--text-field-padding, 8px 12px)` |
| `--text-field-border-radius` | `var(--text-field-border-radius, 8px)` |
| `--text-field-speed-border-color` | `var(--text-field-speed-border-color, var(--speed-color))` |
| `--text-field-speed-box-shadow` | `var(--text-field-speed-box-shadow, var(--speed-color))` |
| `--text-field-speed-bg` | `var(--text-field-speed-bg, var(--speed-color))` |
| `--text-field-focus-border-color` | `var(--text-field-focus-border-color, color-mix(in srgb, white 40%, var(--primary-color)))` |
| `--text-field-focus-shadow` | `var(--text-field-focus-shadow, 0 0 4px var(--primary-color))` |
| `--text-field-disabled-opacity` | `var(--text-field-disabled-opacity, 0.7)` |
| `--text-field-speed-color` | `var(--text-field-speed-color, var(--speed-color))` |
| `--text-field-placeholder-color` | `var(--text-field-placeholder-color, var(--text-secondary-color))` |
| `--text-field-regular-color` | `var(--text-field-regular-color, var(--text-field-color, var(--text-primary-color)))` |
| `--text-field-color` | `var(--text-field-color)` (none) |
| `--text-field-regular-bg-color` | `var(--text-field-regular-bg-color, var(--text-field-bg-color, var(--bg-secondary-color)))` |
Expand All @@ -146,15 +155,17 @@ Only variables actually referenced in `src/components/TextField/text-field.modul
| `--text-field-padding-sm` | `var(--text-field-padding-sm, 6px 10px)` |
| `--text-field-padding-md` | `var(--text-field-padding-md, 10px 14px)` |
| `--text-field-padding-lg` | `var(--text-field-padding-lg, 12px 16px)` |
| `--text-field-font-size-sm` | Contextual defaults: `12px` (small), `16px` (medium), `18px` (large) |
| `--text-field-font-size-sm` | `var(--text-field-font-size-sm, 12px)` |
| `--text-field-font-size-md` | `var(--text-field-font-size-md, 16px)` |
| `--text-field-font-size-lg` | `var(--text-field-font-size-lg, 18px)` |
| `--text-field-success-color` | `var(--text-field-success-color, var(--success-color))` |
| `--text-field-accent-border-width` | `var(--text-field-accent-border-width, 2px)` |
| `--text-field-error-color` | `var(--text-field-error-color, var(--error-color))` |

Notes:

- Accents add a stronger border (`--text-field-accent-border-width`) and shadow using success/error colors. If the component variables aren’t defined, they fall back to theme tokens like `--success-color` and `--error-color`.
- The `--text-field-font-size-sm` variable is reused across all three size modifiers with contextual defaults. Define it once to override all sizes at once.
- Size variants use their own font-size variables (`--text-field-font-size-sm`, `--text-field-font-size-md`, `--text-field-font-size-lg`) for more granular control.

### Theming and global configuration

Expand Down Expand Up @@ -206,3 +217,9 @@ import {UIProvider} from "addon-ui";
- The component renders a native `<input>` inside a wrapper; provide a programmatic label. The `label` prop maps to `aria-label` on both wrapper and input.
- For a visible label, associate a `<label htmlFor>` with the input by passing a matching `id` to TextField.
- Ensure sufficient contrast for text and backgrounds, including disabled and error states.

---

### Usage notes

- **Strict Numeric Input**: When `type="number"` and `strict` is enabled, the component uses a custom normalization logic to ensure only valid numeric characters are entered. It also sets `inputMode="decimal"` and uses `type="text"` internally to provide a more consistent experience across browsers and devices (avoiding some native number input bugs).
31 changes: 19 additions & 12 deletions docs/Truncate.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Single-line text truncation component. Supports classic end truncation via CSS a
#### Import and basic usage

```tsx
import {Truncate} from "addon-ui";
import {Truncate, Highlight} from "addon-ui";

export function Example() {
return (
Expand All @@ -18,6 +18,13 @@ export function Example() {

{/* Middle truncation with custom separator */}
<Truncate text="0x5fC2e1A9B2C3D4E5F6A7B8C9D0abcdef12345678" middle separator=" ··· " />

{/* Middle truncation with highlighting */}
<Truncate
middle
text="search_term_in_the_middle_of_the_string"
render={text => <Highlight textToHighlight={text} searchWords={["search_term"]} />}
/>
</div>
);
}
Expand All @@ -29,12 +36,14 @@ export function Example() {

Only the prop name, type, and default are listed below.

| Prop | Type | Default |
| --------------- | ------------------------------ | ------- |
| `text` | `string` | `""` |
| `middle` | `boolean` | — |
| `separator` | `string` | `"..."` |
| HTML span attrs | all standard `span` attributes | — |
| Prop | Type | Default |
| ------------------ | ------------------------------ | ------- |
| `text` | `string` | `""` |
| `middle` | `boolean` | — |
| `separator` | `string` | `"..."` |
| `contentClassname` | `string` | — |
| `render` | `(text: string) => ReactNode` | — |
| HTML span attrs | all standard `span` attributes | — |

Notes:

Expand All @@ -48,14 +57,12 @@ Notes:

Only variables actually referenced in `src/components/Truncate/truncate.module.scss` are listed, with their exact fallback chains.

| Variable | Fallback chain |
| ------------------------- | ------------------------------------------------- |
| `--truncate-around-space` | `var(--truncate-around-space, 8px)` |
| `--truncate-speed-color` | `var(--truncate-speed-color, var(--speed-color))` |
| Variable | Fallback chain |
| ------------------------ | ------------------------------------------------- |
| `--truncate-speed-color` | `var(--truncate-speed-color, var(--speed-color))` |

Notes:

- `--truncate-around-space` adds right (or left in RTL) inner padding when `middle` is enabled to ensure the separator remains visible.
- Color transitions use the component-scoped `--truncate-speed-color` with a fallback to the global `--speed-color`.

---
Expand Down
Loading