nuxt-ui-elements 0.1.2 → 0.1.4

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/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-ui-elements",
3
3
  "configKey": "uiElements",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -35,6 +35,8 @@ export interface FlickeringGridProps {
35
35
  * - Tailwind colors: 'blue-500', 'red-600', 'slate-200', etc.
36
36
  * - Direct values: '#3b82f6', 'oklch(0.6 0.15 250)', 'rgb(59, 130, 246)'
37
37
  *
38
+ * This controls the base hue/color of the grid. Use `lightness` to adjust how bright/washed out it appears.
39
+ *
38
40
  * @example 'primary' - Nuxt UI semantic color
39
41
  * @example 'blue-500' - Tailwind color
40
42
  * @example '#3b82f6' - Direct hex color value
@@ -43,20 +45,60 @@ export interface FlickeringGridProps {
43
45
  */
44
46
  color?: ColorInput;
45
47
  /**
46
- * Lightness value for the grid (controls how light/subtle the grid appears)
47
- * Range: 0-100, where higher values = lighter/more subtle
48
+ * Lightness adjustment in OKLCH color space (0-100).
49
+ *
50
+ * Controls how bright or washed-out the color appears WITHOUT changing transparency.
51
+ * This modifies the color itself, making it closer to white (higher values) or more saturated (lower values).
52
+ *
53
+ * Think of it as a "color brightness" slider:
54
+ * - Lower values (70-80): Darker, more saturated, vibrant colors
55
+ * - Medium values (85-92): Balanced, natural colors
56
+ * - Higher values (93-100): Very light, pastel, washed-out colors (approaching white)
57
+ *
58
+ * Use cases:
59
+ * - Subtle background: `color="blue-500" lightness={95}` → Very light blue tint
60
+ * - Bold accent: `color="blue-500" lightness={75}` → Vibrant, saturated blue
61
+ * - Combined with opacity: `lightness={90} opacity={0.3}` → Medium-tone color, very transparent
62
+ *
63
+ * Range: 0-100
48
64
  * @default 95
49
65
  */
50
66
  lightness?: number;
51
67
  /**
52
- * Fine-grained element customization (similar to Nuxt UI's ui prop)
68
+ * Opacity/transparency of the grid squares (0-100).
69
+ *
70
+ * Controls how see-through the grid is WITHOUT changing the color itself.
71
+ * This is pure transparency - the color stays the same, just more/less visible.
53
72
  *
54
- * @example { colorDark: 'blue-300' } - Override color for dark mode
73
+ * Think of it as a "visibility" slider:
74
+ * - 0: Completely invisible (transparent)
75
+ * - 30: Very subtle, barely visible
76
+ * - 50: Medium visibility
77
+ * - 80: Bold, prominent
78
+ * - 100: Fully opaque, no transparency
79
+ *
80
+ * Use cases:
81
+ * - Gentle texture: `opacity={20}` → Barely visible background pattern
82
+ * - Strong effect: `opacity={80}` → Prominent, eye-catching grid
83
+ * - Combined with lightness: `lightness={95} opacity={50}` → Light color, medium transparency
84
+ *
85
+ * Range: 0-100
86
+ * @default 50
55
87
  */
88
+ opacity?: number;
56
89
  /**
57
- * Override color specifically for dark mode
90
+ * Dark mode overrides for color, lightness, and opacity.
91
+ *
92
+ * Allows you to customize the grid appearance specifically for dark mode.
93
+ * Any property not specified will use the default light mode value.
94
+ *
95
+ * @example { color: 'blue-300', lightness: 90, opacity: 0.3 }
58
96
  */
59
- colorDark?: ColorInput;
97
+ dark?: {
98
+ color?: ColorInput;
99
+ lightness?: number;
100
+ opacity?: number;
101
+ };
60
102
  /**
61
103
  * UI slot customization
62
104
  */
@@ -7,7 +7,7 @@ import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
7
7
  import { useColorMode } from "#imports";
8
8
  import { tv } from "../../utils/tv";
9
9
  import theme from "../../themes/background-flickering-grid";
10
- import { adjustLightness, oklchToRgb } from "../../composables/useThemeColors";
10
+ import { adjustLightness, darkenColor, oklchToRgb } from "../../composables/useThemeColors";
11
11
  import {
12
12
  resolveColor
13
13
  } from "../../composables/useColorResolver";
@@ -17,6 +17,7 @@ const {
17
17
  speed = 5,
18
18
  color = "neutral",
19
19
  lightness = 95,
20
+ opacity = 50,
20
21
  ...props
21
22
  } = defineProps({
22
23
  size: { type: Number, required: false },
@@ -25,30 +26,30 @@ const {
25
26
  fade: { type: String, required: false },
26
27
  color: { type: null, required: false },
27
28
  lightness: { type: Number, required: false },
28
- colorDark: { type: null, required: false },
29
+ opacity: { type: Number, required: false },
30
+ dark: { type: Object, required: false },
29
31
  ui: { type: null, required: false }
30
32
  });
31
33
  const colorMode = useColorMode();
32
34
  const isDark = computed(() => colorMode.value === "dark");
33
35
  const effectiveColor = computed(() => {
34
- if (isDark.value && props.colorDark) {
35
- return props.colorDark;
36
+ if (isDark.value && props.dark?.color) {
37
+ return props.dark.color;
36
38
  }
37
39
  return color;
38
40
  });
39
- const internalSpeed = computed(() => {
40
- return speed * 0.01;
41
+ const effectiveLightness = computed(() => {
42
+ if (isDark.value && props.dark?.lightness !== void 0) {
43
+ return props.dark.lightness;
44
+ }
45
+ return lightness;
41
46
  });
42
47
  const effectiveOpacity = computed(() => {
43
- const minLightness = 70;
44
- const maxLightness = 100;
45
- const maxOpacity = 0.8;
46
- const minOpacity = 0.15;
47
- const t = Math.max(
48
- 0,
49
- Math.min(1, (lightness - minLightness) / (maxLightness - minLightness))
50
- );
51
- return maxOpacity - t * (maxOpacity - minOpacity);
48
+ const opacityValue = isDark.value && props.dark?.opacity !== void 0 ? props.dark.opacity : opacity;
49
+ return opacityValue / 100;
50
+ });
51
+ const internalSpeed = computed(() => {
52
+ return speed * 0.01;
52
53
  });
53
54
  defineSlots();
54
55
  const ui = computed(() => tv(theme)());
@@ -93,10 +94,10 @@ function parseColor(color2) {
93
94
  }
94
95
  const gridColors = computed(() => {
95
96
  const baseColor = resolveColor(effectiveColor.value);
96
- const lightnessBase = lightness;
97
- const lightnessFlicker = Math.max(0, lightness - 10);
98
- const baseRgb = oklchToRgb(adjustLightness(baseColor, lightnessBase));
99
- const flickerRgb = oklchToRgb(adjustLightness(baseColor, lightnessFlicker));
97
+ const adjustedColor = adjustLightness(baseColor, effectiveLightness.value);
98
+ const baseRgb = oklchToRgb(adjustedColor);
99
+ const darkerColor = darkenColor(adjustedColor, 10);
100
+ const flickerRgb = oklchToRgb(darkerColor);
100
101
  return {
101
102
  base: parseColor(baseRgb),
102
103
  flicker: parseColor(flickerRgb)
@@ -146,13 +147,13 @@ function drawGrid(ctx, canvasWidth, canvasHeight, cols, rows, squares, dpr) {
146
147
  for (let i = 0; i < cols; i++) {
147
148
  for (let j = 0; j < rows; j++) {
148
149
  const idx = i * rows + j;
149
- const opacity = squares[idx] ?? 0;
150
+ const opacity2 = squares[idx] ?? 0;
150
151
  let cellColor = colors.base;
151
- let cellAlpha = opacity;
152
- if (opacity > 0.5 * effectiveOpacity.value) {
153
- const blendT = (opacity - 0.5 * effectiveOpacity.value) / (0.5 * effectiveOpacity.value);
152
+ let cellAlpha = opacity2;
153
+ if (opacity2 > 0.5 * effectiveOpacity.value) {
154
+ const blendT = (opacity2 - 0.5 * effectiveOpacity.value) / (0.5 * effectiveOpacity.value);
154
155
  cellColor = lerpColor(colors.base, colors.flicker, blendT);
155
- cellAlpha = Math.min(1, opacity + 0.2);
156
+ cellAlpha = Math.min(1, opacity2 + 0.2);
156
157
  }
157
158
  ctx.fillStyle = rgbToString(cellColor, cellAlpha);
158
159
  ctx.fillRect(
@@ -219,9 +220,21 @@ onBeforeUnmount(() => {
219
220
  resizeObserver?.disconnect();
220
221
  intersectionObserver?.disconnect();
221
222
  });
222
- watch([() => size, () => gap, () => color, () => lightness], () => {
223
- updateCanvasSize();
224
- });
223
+ watch(
224
+ [
225
+ () => size,
226
+ () => gap,
227
+ () => color,
228
+ () => lightness,
229
+ () => opacity,
230
+ () => props.dark?.color,
231
+ () => props.dark?.lightness,
232
+ () => props.dark?.opacity
233
+ ],
234
+ () => {
235
+ updateCanvasSize();
236
+ }
237
+ );
225
238
  </script>
226
239
 
227
240
  <template>
@@ -35,6 +35,8 @@ export interface FlickeringGridProps {
35
35
  * - Tailwind colors: 'blue-500', 'red-600', 'slate-200', etc.
36
36
  * - Direct values: '#3b82f6', 'oklch(0.6 0.15 250)', 'rgb(59, 130, 246)'
37
37
  *
38
+ * This controls the base hue/color of the grid. Use `lightness` to adjust how bright/washed out it appears.
39
+ *
38
40
  * @example 'primary' - Nuxt UI semantic color
39
41
  * @example 'blue-500' - Tailwind color
40
42
  * @example '#3b82f6' - Direct hex color value
@@ -43,20 +45,60 @@ export interface FlickeringGridProps {
43
45
  */
44
46
  color?: ColorInput;
45
47
  /**
46
- * Lightness value for the grid (controls how light/subtle the grid appears)
47
- * Range: 0-100, where higher values = lighter/more subtle
48
+ * Lightness adjustment in OKLCH color space (0-100).
49
+ *
50
+ * Controls how bright or washed-out the color appears WITHOUT changing transparency.
51
+ * This modifies the color itself, making it closer to white (higher values) or more saturated (lower values).
52
+ *
53
+ * Think of it as a "color brightness" slider:
54
+ * - Lower values (70-80): Darker, more saturated, vibrant colors
55
+ * - Medium values (85-92): Balanced, natural colors
56
+ * - Higher values (93-100): Very light, pastel, washed-out colors (approaching white)
57
+ *
58
+ * Use cases:
59
+ * - Subtle background: `color="blue-500" lightness={95}` → Very light blue tint
60
+ * - Bold accent: `color="blue-500" lightness={75}` → Vibrant, saturated blue
61
+ * - Combined with opacity: `lightness={90} opacity={0.3}` → Medium-tone color, very transparent
62
+ *
63
+ * Range: 0-100
48
64
  * @default 95
49
65
  */
50
66
  lightness?: number;
51
67
  /**
52
- * Fine-grained element customization (similar to Nuxt UI's ui prop)
68
+ * Opacity/transparency of the grid squares (0-100).
69
+ *
70
+ * Controls how see-through the grid is WITHOUT changing the color itself.
71
+ * This is pure transparency - the color stays the same, just more/less visible.
53
72
  *
54
- * @example { colorDark: 'blue-300' } - Override color for dark mode
73
+ * Think of it as a "visibility" slider:
74
+ * - 0: Completely invisible (transparent)
75
+ * - 30: Very subtle, barely visible
76
+ * - 50: Medium visibility
77
+ * - 80: Bold, prominent
78
+ * - 100: Fully opaque, no transparency
79
+ *
80
+ * Use cases:
81
+ * - Gentle texture: `opacity={20}` → Barely visible background pattern
82
+ * - Strong effect: `opacity={80}` → Prominent, eye-catching grid
83
+ * - Combined with lightness: `lightness={95} opacity={50}` → Light color, medium transparency
84
+ *
85
+ * Range: 0-100
86
+ * @default 50
55
87
  */
88
+ opacity?: number;
56
89
  /**
57
- * Override color specifically for dark mode
90
+ * Dark mode overrides for color, lightness, and opacity.
91
+ *
92
+ * Allows you to customize the grid appearance specifically for dark mode.
93
+ * Any property not specified will use the default light mode value.
94
+ *
95
+ * @example { color: 'blue-300', lightness: 90, opacity: 0.3 }
58
96
  */
59
- colorDark?: ColorInput;
97
+ dark?: {
98
+ color?: ColorInput;
99
+ lightness?: number;
100
+ opacity?: number;
101
+ };
60
102
  /**
61
103
  * UI slot customization
62
104
  */
@@ -16,6 +16,13 @@ export declare function createOklch(l: number, c: number, h: number): string;
16
16
  * Accepts any valid CSS color string
17
17
  */
18
18
  export declare function adjustLightness(colorStr: string, targetLightness: number): string;
19
+ /**
20
+ * Darken a color by reducing its lightness
21
+ * @param colorStr - Any valid CSS color string
22
+ * @param amount - Amount to reduce lightness by (in percentage points, 0-100)
23
+ * @returns Darkened color string
24
+ */
25
+ export declare function darkenColor(colorStr: string, amount?: number): string;
19
26
  /**
20
27
  * Adjust the chroma (saturation) of a color while preserving lightness and hue
21
28
  */
@@ -24,6 +24,16 @@ export function adjustLightness(colorStr, targetLightness) {
24
24
  oklch.l = targetLightness / 100;
25
25
  return formatCss(oklch);
26
26
  }
27
+ export function darkenColor(colorStr, amount = 10) {
28
+ const parsed = parse(colorStr);
29
+ if (!parsed) return colorStr;
30
+ const oklch = toOklch(parsed);
31
+ if (!oklch || oklch.l === void 0) return colorStr;
32
+ const currentLightness = oklch.l * 100;
33
+ const newLightness = Math.max(0, currentLightness - amount);
34
+ oklch.l = newLightness / 100;
35
+ return formatCss(oklch);
36
+ }
27
37
  export function adjustChroma(colorStr, targetChroma) {
28
38
  const parsed = parse(colorStr);
29
39
  if (!parsed) return colorStr;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-ui-elements",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "A collection of beautiful, animated UI components for Nuxt applications",
5
5
  "license": "MIT",
6
6
  "repository": "https://github.com/genu/nuxt-ui-elements.git",
@@ -55,7 +55,7 @@
55
55
  "lint:fix": "oxlint --fix --type-aware",
56
56
  "format": "oxfmt --write",
57
57
  "format:check": "oxfmt --check",
58
- "release": "pnpm lint && pnpm test && pnpm prepack && changelogen --release && pnpm publish && git push --follow-tags",
58
+ "release": "pnpm lint && pnpm test && pnpm prepack && changelogen --release",
59
59
  "test": "vitest run",
60
60
  "test:watch": "vitest watch",
61
61
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"