@tenerife.music/ui 2.0.0 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,6 +4,7 @@
4
4
  Strict. Predictable. Built for system-level consistency.
5
5
 
6
6
  ![Release](https://img.shields.io/github/v/tag/Tureckiy-zart/tenerife-ui?style=for-the-badge&sort=semver)
7
+ ![Version](https://img.shields.io/badge/version-2.0.3-blue?style=for-the-badge)
7
8
  ![React](https://img.shields.io/badge/React-18+-blue?style=for-the-badge)
8
9
  ![TypeScript](https://img.shields.io/badge/TypeScript-Strict-blue?style=for-the-badge)
9
10
  ![TailwindCSS](https://img.shields.io/badge/TailwindCSS-3.4-38b2ac?style=for-the-badge)
@@ -128,7 +129,7 @@ export default function App() {
128
129
  - **Component Creation**: [Extension Component Creation Checklist](docs/workflows/tasks/COMPONENT_CREATION_CHECKLIST.md)
129
130
  - **CLI Generator**: Use `pnpm run component:generate -- <ComponentName> [--category <category>]` to generate component scaffold
130
131
  - See checklist for complete process and requirements
131
- - **Component Refactoring**: [Component Review & Improvement Pipeline (18A)](docs/workflows/foundation/FOUNDATION_STEP_PIPELINE.md)
132
+ - **Component Refactoring**: [Component Refactoring Pipeline (18A)](docs/workflows/foundation/COMPONENT_REFACTORING_PIPELINE.md)
132
133
  - **Canonical process** for reviewing, improving, and validating existing components
133
134
  - Mandatory 12-step pipeline (STEP 0-11) for Foundation and Extension components
134
135
  - See pipeline for complete refactoring process and requirements
@@ -186,6 +187,41 @@ Tokens are **immutable contracts**, not convenience variables.
186
187
 
187
188
  ---
188
189
 
190
+ ## 🎨 Theme Tooling
191
+
192
+ TUI provides **build-time CLI tooling** for generating and validating themes.
193
+
194
+ **Theme Tooling is a build-time compiler, not a runtime system.**
195
+
196
+ - **Theme Generator** (`pnpm theme:generate`) — creates Theme Contract v1 compliant themes
197
+ - **Theme Validator** (`pnpm theme:validate`) — validates themes against contract
198
+ - **Parity Checker** (`pnpm theme:parity-check`) — ensures token consistency
199
+
200
+ **Key Points:**
201
+
202
+ - Themes are generated at **build time**, not runtime
203
+ - All themes live in `src/EXTENSIONS/themes/` (canonical path)
204
+ - Validation is **mandatory** — invalid themes cannot be committed (CI enforced)
205
+ - UI library **never generates themes** — it only consumes pre-generated CSS
206
+
207
+ **Quick Start:**
208
+
209
+ ```bash
210
+ # Generate a theme
211
+ pnpm theme:generate -- --palette my-brand --base-color "210 40% 50%" --modes light,dark
212
+
213
+ # Validate themes
214
+ pnpm theme:validate -- src/EXTENSIONS/themes/*.css
215
+ ```
216
+
217
+ **Documentation:**
218
+
219
+ - [Theme System — Contract & Tooling](tools/theme-contract/README.md) - **Complete guide** (start here)
220
+ - [Theme Generator](tools/theme-generator/README.md) - Generator documentation
221
+ - [Theme Validator](tools/theme-validator/README.md) - Validator documentation
222
+
223
+ ---
224
+
189
225
  ## 🧩 Domain-Specific Components
190
226
 
191
227
  The following components are **used internally** in Tenerife Music projects
@@ -242,6 +242,10 @@ declare const tailwindThemeColors: {
242
242
  readonly DEFAULT: "hsl(var(--muted))";
243
243
  readonly foreground: "hsl(var(--muted-foreground))";
244
244
  };
245
+ readonly disabled: {
246
+ readonly DEFAULT: "hsl(var(--tm-disabled))";
247
+ readonly foreground: "hsl(var(--tm-disabled-foreground))";
248
+ };
245
249
  readonly destructive: {
246
250
  readonly DEFAULT: "hsl(var(--destructive))";
247
251
  readonly foreground: "hsl(var(--destructive-foreground))";
@@ -242,6 +242,10 @@ declare const tailwindThemeColors: {
242
242
  readonly DEFAULT: "hsl(var(--muted))";
243
243
  readonly foreground: "hsl(var(--muted-foreground))";
244
244
  };
245
+ readonly disabled: {
246
+ readonly DEFAULT: "hsl(var(--tm-disabled))";
247
+ readonly foreground: "hsl(var(--tm-disabled-foreground))";
248
+ };
245
249
  readonly destructive: {
246
250
  readonly DEFAULT: "hsl(var(--destructive))";
247
251
  readonly foreground: "hsl(var(--destructive-foreground))";
@@ -242,13 +242,14 @@ var LINK_TOKENS = {
242
242
  },
243
243
  /**
244
244
  * Disabled state tokens
245
+ * Uses explicit disabled semantic tokens for better accessibility
245
246
  */
246
247
  state: {
247
248
  disabled: {
248
249
  pointerEvents: "disabled:pointer-events-none",
249
250
  // Disable pointer events
250
- opacity: "disabled:opacity-50"
251
- // Disabled opacity
251
+ text: "disabled:text-[hsl(var(--tm-disabled-foreground))]"
252
+ // Disabled text color using explicit disabled semantic token
252
253
  }
253
254
  },
254
255
  /**
@@ -324,7 +325,7 @@ function renderIcon(icon) {
324
325
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ICON_WRAPPER_CLASS, children: icon });
325
326
  }
326
327
  var linkVariants = tokenCVA({
327
- base: `${LINK_TOKENS.layout} ${LINK_TOKENS.fontWeight} ${LINK_TOKENS.transition.colors} ${LINK_TOKENS.focus.outline} ${LINK_TOKENS.focus.ring} ${LINK_TOKENS.focus.offset} ${LINK_TOKENS.state.disabled.pointerEvents} ${LINK_TOKENS.state.disabled.opacity}`,
328
+ base: `${LINK_TOKENS.layout} ${LINK_TOKENS.fontWeight} ${LINK_TOKENS.transition.colors} ${LINK_TOKENS.focus.outline} ${LINK_TOKENS.focus.ring} ${LINK_TOKENS.focus.offset} ${LINK_TOKENS.state.disabled.pointerEvents} ${LINK_TOKENS.state.disabled.text}`,
328
329
  variants: {
329
330
  variant: {
330
331
  primary: `${LINK_TOKENS.variant.primary.text} ${LINK_TOKENS.variant.primary.hover} ${LINK_TOKENS.underlineOffset} ${LINK_TOKENS.variant.primary.underline}`,
@@ -217,13 +217,14 @@ var LINK_TOKENS = {
217
217
  },
218
218
  /**
219
219
  * Disabled state tokens
220
+ * Uses explicit disabled semantic tokens for better accessibility
220
221
  */
221
222
  state: {
222
223
  disabled: {
223
224
  pointerEvents: "disabled:pointer-events-none",
224
225
  // Disable pointer events
225
- opacity: "disabled:opacity-50"
226
- // Disabled opacity
226
+ text: "disabled:text-[hsl(var(--tm-disabled-foreground))]"
227
+ // Disabled text color using explicit disabled semantic token
227
228
  }
228
229
  },
229
230
  /**
@@ -299,7 +300,7 @@ function renderIcon(icon) {
299
300
  return /* @__PURE__ */ jsx("span", { className: ICON_WRAPPER_CLASS, children: icon });
300
301
  }
301
302
  var linkVariants = tokenCVA({
302
- base: `${LINK_TOKENS.layout} ${LINK_TOKENS.fontWeight} ${LINK_TOKENS.transition.colors} ${LINK_TOKENS.focus.outline} ${LINK_TOKENS.focus.ring} ${LINK_TOKENS.focus.offset} ${LINK_TOKENS.state.disabled.pointerEvents} ${LINK_TOKENS.state.disabled.opacity}`,
303
+ base: `${LINK_TOKENS.layout} ${LINK_TOKENS.fontWeight} ${LINK_TOKENS.transition.colors} ${LINK_TOKENS.focus.outline} ${LINK_TOKENS.focus.ring} ${LINK_TOKENS.focus.offset} ${LINK_TOKENS.state.disabled.pointerEvents} ${LINK_TOKENS.state.disabled.text}`,
303
304
  variants: {
304
305
  variant: {
305
306
  primary: `${LINK_TOKENS.variant.primary.text} ${LINK_TOKENS.variant.primary.hover} ${LINK_TOKENS.underlineOffset} ${LINK_TOKENS.variant.primary.underline}`,
@@ -1045,15 +1045,15 @@ declare const SWITCH_TOKENS: {
1045
1045
  readonly track: {
1046
1046
  readonly default: "bg-[hsl(var(--input))]";
1047
1047
  readonly checked: "bg-[hsl(var(--tm-primary))]";
1048
- readonly disabled: "bg-[hsl(var(--muted))]";
1049
- readonly disabledChecked: "bg-[hsl(var(--muted))]";
1048
+ readonly disabled: "bg-[hsl(var(--tm-disabled))]";
1049
+ readonly disabledChecked: "bg-[hsl(var(--tm-disabled))]";
1050
1050
  readonly error: "bg-[hsl(var(--destructive))]";
1051
1051
  };
1052
1052
  readonly handle: {
1053
1053
  readonly default: "bg-[hsl(var(--muted-foreground))]";
1054
1054
  readonly checked: "bg-[hsl(var(--tm-primary-foreground))]";
1055
- readonly disabled: "bg-[hsl(var(--muted-foreground))]";
1056
- readonly disabledChecked: "bg-[hsl(var(--muted-foreground))]";
1055
+ readonly disabled: "bg-[hsl(var(--tm-disabled-foreground))]";
1056
+ readonly disabledChecked: "bg-[hsl(var(--tm-disabled-foreground))]";
1057
1057
  readonly error: "bg-[hsl(var(--destructive-foreground))]";
1058
1058
  };
1059
1059
  readonly opacity: {
@@ -5173,6 +5173,10 @@ declare const UI_COLORS: {
5173
5173
  readonly DEFAULT: "hsl(var(--muted))";
5174
5174
  readonly foreground: "hsl(var(--muted-foreground))";
5175
5175
  };
5176
+ readonly disabled: {
5177
+ readonly DEFAULT: "hsl(var(--tm-disabled))";
5178
+ readonly foreground: "hsl(var(--tm-disabled-foreground))";
5179
+ };
5176
5180
  readonly destructive: {
5177
5181
  readonly DEFAULT: "hsl(var(--destructive))";
5178
5182
  readonly foreground: "hsl(var(--destructive-foreground))";
@@ -1045,15 +1045,15 @@ declare const SWITCH_TOKENS: {
1045
1045
  readonly track: {
1046
1046
  readonly default: "bg-[hsl(var(--input))]";
1047
1047
  readonly checked: "bg-[hsl(var(--tm-primary))]";
1048
- readonly disabled: "bg-[hsl(var(--muted))]";
1049
- readonly disabledChecked: "bg-[hsl(var(--muted))]";
1048
+ readonly disabled: "bg-[hsl(var(--tm-disabled))]";
1049
+ readonly disabledChecked: "bg-[hsl(var(--tm-disabled))]";
1050
1050
  readonly error: "bg-[hsl(var(--destructive))]";
1051
1051
  };
1052
1052
  readonly handle: {
1053
1053
  readonly default: "bg-[hsl(var(--muted-foreground))]";
1054
1054
  readonly checked: "bg-[hsl(var(--tm-primary-foreground))]";
1055
- readonly disabled: "bg-[hsl(var(--muted-foreground))]";
1056
- readonly disabledChecked: "bg-[hsl(var(--muted-foreground))]";
1055
+ readonly disabled: "bg-[hsl(var(--tm-disabled-foreground))]";
1056
+ readonly disabledChecked: "bg-[hsl(var(--tm-disabled-foreground))]";
1057
1057
  readonly error: "bg-[hsl(var(--destructive-foreground))]";
1058
1058
  };
1059
1059
  readonly opacity: {
@@ -5173,6 +5173,10 @@ declare const UI_COLORS: {
5173
5173
  readonly DEFAULT: "hsl(var(--muted))";
5174
5174
  readonly foreground: "hsl(var(--muted-foreground))";
5175
5175
  };
5176
+ readonly disabled: {
5177
+ readonly DEFAULT: "hsl(var(--tm-disabled))";
5178
+ readonly foreground: "hsl(var(--tm-disabled-foreground))";
5179
+ };
5176
5180
  readonly destructive: {
5177
5181
  readonly DEFAULT: "hsl(var(--destructive))";
5178
5182
  readonly foreground: "hsl(var(--destructive-foreground))";