@splenddev/kreativ-core 0.1.16 → 0.1.18
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/hooks/index.d.ts +10 -3
- package/dist/hooks/index.js +33 -28
- package/dist/hooks/index.js.map +1 -1
- package/package.json +1 -1
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseBreakpoint, ColorMode, ResponsiveValue, ResponsiveStyles, SizeToken, Theme, Size } from '../types/index.js';
|
|
1
|
+
import { BaseBreakpoint, ColorMode, ResponsiveValue, ResponsiveStyles, CSSPropertiesWithVars, SizeToken, Theme, Size } from '../types/index.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { CSSProperties } from 'react';
|
|
4
4
|
|
|
@@ -87,12 +87,15 @@ interface UseSizeStyleOptions {
|
|
|
87
87
|
*/
|
|
88
88
|
interface ResolvedSize {
|
|
89
89
|
/**
|
|
90
|
-
*
|
|
90
|
+
* CSS custom properties (`--kui-<componentName>-*`) for sizing.
|
|
91
|
+
* Consumed by the matching recipe's Tailwind arbitrary-value classes
|
|
92
|
+
* (e.g. `h-[var(--kui-button-height)]`), not applied as literal
|
|
93
|
+
* CSS properties directly — recipes own the actual property mapping.
|
|
91
94
|
*
|
|
92
95
|
* For responsive values this is intentionally empty so that
|
|
93
96
|
* breakpoint styles can override each other through CSS.
|
|
94
97
|
*/
|
|
95
|
-
style:
|
|
98
|
+
style: CSSPropertiesWithVars;
|
|
96
99
|
/**
|
|
97
100
|
* Styles generated for responsive sizing.
|
|
98
101
|
*/
|
|
@@ -103,6 +106,10 @@ interface ResolvedSize {
|
|
|
103
106
|
fontSize?: CSSProperties["fontSize"];
|
|
104
107
|
/** Resolved gap between child elements. */
|
|
105
108
|
gap?: CSSProperties["gap"];
|
|
109
|
+
/** Resolved horizontal padding, for callers that need the raw value in JS (e.g. a `calc()` computed on top of it). */
|
|
110
|
+
paddingX?: CSSProperties["paddingLeft"];
|
|
111
|
+
/** Resolved vertical padding, for callers that need the raw value in JS (e.g. a `calc()` computed on top of it). */
|
|
112
|
+
paddingY?: CSSProperties["paddingTop"];
|
|
106
113
|
}
|
|
107
114
|
/**
|
|
108
115
|
* Builds size-related inline styles from a theme size token.
|
package/dist/hooks/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ThemeContext, useTheme } from '../chunk-QP6G3F24.js';
|
|
2
2
|
export { useThemeModePersistence } from '../chunk-QP6G3F24.js';
|
|
3
|
-
import { isResponsiveValue, resolveTypography,
|
|
3
|
+
import { isResponsiveValue, resolveTypography, resolveFontSize, resolveTokenReference, resolveResponsiveValue } from '../chunk-O4WVNYS5.js';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { useState, useEffect, useContext, useMemo, useId, useRef, useCallback } from 'react';
|
|
6
6
|
|
|
@@ -162,54 +162,62 @@ function useSizeStyle(size, iconOnly = false, componentName = "component", optio
|
|
|
162
162
|
const resolveValue = (value) => String(resolveTokenReference(value, tokens));
|
|
163
163
|
const resolveFont = (value) => String(resolveFontSize(value, typography, tokens));
|
|
164
164
|
const resolveToken = (sizeName) => scale[sizeName] ?? scale[fallbackSize] ?? Object.values(scale)[0] ?? {};
|
|
165
|
+
const setVar = (style, prop, value) => {
|
|
166
|
+
if (value === void 0) return;
|
|
167
|
+
style[`--kui-${componentName}-${prop}`] = value;
|
|
168
|
+
};
|
|
165
169
|
const buildStyle = (sizeName) => {
|
|
166
|
-
const
|
|
170
|
+
const token = resolveToken(sizeName);
|
|
167
171
|
const style = {};
|
|
168
|
-
const height = resolveValue(
|
|
169
|
-
const width = resolveValue(
|
|
170
|
-
const paddingX = resolveValue(
|
|
171
|
-
const paddingY = resolveValue(
|
|
172
|
-
const fontSize = resolveFont(
|
|
173
|
-
const gap = resolveValue(
|
|
174
|
-
const radius = resolveValue(
|
|
172
|
+
const height = resolveValue(token.height);
|
|
173
|
+
const width = resolveValue(token.width);
|
|
174
|
+
const paddingX = resolveValue(token.paddingX);
|
|
175
|
+
const paddingY = resolveValue(token.paddingY);
|
|
176
|
+
const fontSize = resolveFont(token.fontSize);
|
|
177
|
+
const gap = resolveValue(token.gap);
|
|
178
|
+
const radius = resolveValue(token.radius);
|
|
175
179
|
if (includeHeight && height) {
|
|
176
|
-
style
|
|
180
|
+
setVar(style, "height", applySizeOffset(height, sizeOffset));
|
|
177
181
|
}
|
|
178
182
|
if (includeWidth) {
|
|
179
183
|
if (iconOnly && width) {
|
|
180
|
-
style
|
|
184
|
+
setVar(style, "width", applySizeOffset(width, sizeOffset));
|
|
181
185
|
} else if ((iconOnly || widthFromHeight) && includeHeight && height) {
|
|
182
|
-
style
|
|
186
|
+
setVar(style, "width", applySizeOffset(height, sizeOffset));
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
189
|
if (!iconOnly && paddingX) {
|
|
186
|
-
style
|
|
187
|
-
style.paddingRight = paddingX;
|
|
190
|
+
setVar(style, "padding-x", paddingX);
|
|
188
191
|
}
|
|
189
192
|
if (paddingY) {
|
|
190
|
-
style
|
|
191
|
-
style.paddingBottom = paddingY;
|
|
193
|
+
setVar(style, "padding-y", paddingY);
|
|
192
194
|
}
|
|
193
195
|
if (fontSize) {
|
|
194
|
-
style
|
|
196
|
+
setVar(style, "font-size", applySizeOffset(fontSize, fontSizeOffset));
|
|
195
197
|
}
|
|
196
198
|
if (gap) {
|
|
197
|
-
style
|
|
199
|
+
setVar(style, "gap", iconOnly ? "0" : gap);
|
|
198
200
|
}
|
|
199
201
|
if (radius) {
|
|
200
|
-
|
|
201
|
-
style[varName] = radius;
|
|
202
|
+
setVar(style, "radius", radius);
|
|
202
203
|
}
|
|
203
204
|
return style;
|
|
204
205
|
};
|
|
206
|
+
const buildResolvedExtras = (sizeName) => {
|
|
207
|
+
const token = resolveToken(sizeName);
|
|
208
|
+
return {
|
|
209
|
+
iconSize: resolveValue(token.iconSize),
|
|
210
|
+
fontSize: applySizeOffset(resolveFont(token.fontSize), fontSizeOffset),
|
|
211
|
+
gap: resolveValue(token.gap),
|
|
212
|
+
paddingX: !iconOnly ? resolveValue(token.paddingX) : void 0,
|
|
213
|
+
paddingY: resolveValue(token.paddingY)
|
|
214
|
+
};
|
|
215
|
+
};
|
|
205
216
|
if (!isResponsiveValue(size)) {
|
|
206
217
|
const style = buildStyle(size);
|
|
207
|
-
const token2 = resolveToken(size);
|
|
208
218
|
return {
|
|
209
219
|
style,
|
|
210
|
-
|
|
211
|
-
fontSize: applySizeOffset(resolveFont(token2.fontSize), fontSizeOffset),
|
|
212
|
-
gap: resolveValue(token2.gap)
|
|
220
|
+
...buildResolvedExtras(size)
|
|
213
221
|
};
|
|
214
222
|
}
|
|
215
223
|
const { base, ...breakpoints } = size;
|
|
@@ -221,13 +229,10 @@ function useSizeStyle(size, iconOnly = false, componentName = "component", optio
|
|
|
221
229
|
if (breakpointSize === void 0) continue;
|
|
222
230
|
responsiveStyles[breakpoint] = buildStyle(breakpointSize);
|
|
223
231
|
}
|
|
224
|
-
const token = resolveToken(baseSize);
|
|
225
232
|
return {
|
|
226
233
|
style: {},
|
|
227
234
|
responsiveStyles,
|
|
228
|
-
|
|
229
|
-
fontSize: applySizeOffset(resolveFont(token.fontSize), fontSizeOffset),
|
|
230
|
-
gap: resolveValue(token.gap)
|
|
235
|
+
...buildResolvedExtras(baseSize)
|
|
231
236
|
};
|
|
232
237
|
}, [
|
|
233
238
|
theme,
|
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/hooks/useBreakpoint.ts","../../src/hooks/useColorMode.ts","../../src/hooks/useControllableState.ts","../../src/hooks/useMergedResponsiveStyles.ts","../../src/hooks/useResponsiveStyles.ts","../../src/hooks/useSizeStyle.ts","../../src/hooks/useSizeToken.ts","../../src/hooks/useSizes.ts","../../src/hooks/useTypography.ts","../../src/hooks/useUndoRedo.ts"],"names":["useMemo","token","useState","useRef","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\r\n\r\nimport { BaseBreakpoint } from \"@/types\";\r\nimport { useEffect, useState } from \"react\";\r\n\r\nconst BREAKPOINTS: Record<BaseBreakpoint, number> = {\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n \"2xl\": 1536,\r\n};\r\n\r\nexport function useBreakpoint(breakpoint: BaseBreakpoint): boolean {\r\n const query = `(min-width: ${BREAKPOINTS[breakpoint]}px)`;\r\n const [matches, setMatches] = useState(\r\n () => typeof window !== \"undefined\" && window.matchMedia(query).matches,\r\n );\r\n\r\n useEffect(() => {\r\n const mql = window.matchMedia(query);\r\n const listener = (e: MediaQueryListEvent) => setMatches(e.matches);\r\n mql.addEventListener(\"change\", listener);\r\n setMatches(mql.matches);\r\n return () => mql.removeEventListener(\"change\", listener);\r\n }, [query]);\r\n\r\n return matches;\r\n}\r\n","import { useContext } from \"react\";\nimport { ThemeContext } from \"../provider/ThemeContext\";\nimport { ColorMode } from \"@/types/theme\";\n\nexport interface UseColorModeReturn {\n mode: ColorMode;\n setMode: (mode: ColorMode) => void;\n toggleColorMode: () => void;\n}\n\nexport function useColorMode(): UseColorModeReturn {\n const ctx = useContext(ThemeContext);\n\n if (!ctx) {\n throw new Error(\"useColorMode must be used within a ThemeProvider\");\n }\n\n return {\n mode: ctx.mode,\n setMode: ctx.setMode,\n toggleColorMode: () => {\n throw new Error(\"not implemented\");\n },\n };\n}\n","import * as React from \"react\";\n\nexport interface UseControllableStateOptions<T> {\n value?: T;\n defaultValue: T;\n onChange?: (next: T) => void;\n}\n\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T, (next: T) => void] {\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const isControlled = value !== undefined;\n const current = isControlled ? (value as T) : internal;\n const currentRef = React.useRef(current);\n currentRef.current = current;\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n\n const set = React.useCallback(\n (next: T) => {\n if (Object.is(next, currentRef.current)) return;\n if (!isControlled) setInternal(next);\n onChangeRef.current?.(next);\n },\n [isControlled],\n );\n return [current, set];\n}\n","\"use client\";\r\n\r\nimport { useMemo } from \"react\";\r\nimport type { CSSProperties } from \"react\";\r\nimport type { ResponsiveValue, ResponsiveStyles } from \"@/types\";\r\nimport { resolveResponsiveValue } from \"@/utils/responsive\";\r\n\r\n/**\r\n * One entry: a responsive prop value plus a mapper from that value to a\r\n * partial CSSProperties object.\r\n *\r\n * Using `any` for the value type because different entries may have different\r\n * value types, and we only need to call the mapper with the resolved value.\r\n */\r\nexport type ResponsivePropEntry = [\r\n value: ResponsiveValue<any> | undefined,\r\n toCss: (value: any) => Partial<CSSProperties>,\r\n];\r\n\r\nfunction mergeResponsiveProps(\r\n entries: ResponsivePropEntry[],\r\n): ResponsiveStyles {\r\n const result: ResponsiveStyles = {};\r\n\r\n for (const [value, toCss] of entries) {\r\n if (value === undefined) continue;\r\n\r\n const { base, responsive } = resolveResponsiveValue(value);\r\n\r\n if (base !== undefined) {\r\n result.base = { ...result.base, ...toCss(base) };\r\n }\r\n\r\n for (const [bp, v] of Object.entries(responsive)) {\r\n result[bp] = { ...result[bp], ...toCss(v) };\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Merges multiple ResponsiveValue<T> props into one ResponsiveStyles map,\r\n * memoized on the entries' values.\r\n *\r\n * @example\r\n * const responsiveStyles = useMergedResponsiveStyles([\r\n * [gap, (v) => ({ gap: spaceVar(v) })],\r\n * [align, (v) => ({ alignItems: v })],\r\n * ]);\r\n */\r\nexport function useMergedResponsiveStyles(\r\n entries: ResponsivePropEntry[],\r\n): ResponsiveStyles {\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n return useMemo(\r\n () => mergeResponsiveProps(entries),\r\n entries.map(([value]) => value),\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { type CSSProperties, useId, useMemo } from \"react\";\r\n\r\nimport type { ResponsiveStyles } from \"@/types\";\r\nimport { useTheme } from \"@/provider/useTheme\";\r\n\r\nconst cssPropertyToKebab = (property: string) =>\r\n property.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\r\n\r\nconst cssValue = (value: CSSProperties[keyof CSSProperties]) => {\r\n if (typeof value === \"number\") {\r\n return String(value);\r\n }\r\n\r\n return value;\r\n};\r\n\r\nexport function useResponsiveStyles(responsiveStyles?: ResponsiveStyles) {\r\n const { theme } = useTheme();\r\n const id = useId();\r\n\r\n return useMemo(() => {\r\n if (!responsiveStyles || Object.keys(responsiveStyles).length === 0) {\r\n return {\r\n attribute: undefined,\r\n style: undefined,\r\n };\r\n }\r\n\r\n const breakpoints = theme.tokens.breakpoints;\r\n\r\n if (!breakpoints) {\r\n return {\r\n attribute: undefined,\r\n style: undefined,\r\n };\r\n }\r\n\r\n const attribute = id.replace(/:/g, \"\");\r\n\r\n const selector = `[data-kui-responsive=\"${attribute}\"]`;\r\n\r\n const rules: string[] = [];\r\n\r\n for (const [breakpoint, styles] of Object.entries(responsiveStyles)) {\r\n const declarations = Object.entries(styles)\r\n .filter(([, value]) => value !== undefined)\r\n .map(\r\n ([property, value]) =>\r\n `${cssPropertyToKebab(property)}:${cssValue(value)};`,\r\n )\r\n .join(\"\");\r\n\r\n if (!declarations) continue;\r\n\r\n if (breakpoint === \"base\") {\r\n rules.push(`\r\n ${selector} {\r\n ${declarations}\r\n }\r\n `);\r\n\r\n continue;\r\n }\r\n\r\n const breakpointToken = breakpoints[breakpoint];\r\n\r\n if (!breakpointToken) continue;\r\n\r\n rules.push(`\r\n @media (min-width: ${breakpointToken.value}) {\r\n ${selector} {\r\n ${declarations}\r\n }\r\n }\r\n `);\r\n }\r\n\r\n if (rules.length === 0) {\r\n return {\r\n attribute: undefined,\r\n style: undefined,\r\n };\r\n }\r\n\r\n return {\r\n attribute,\r\n style: rules.join(\"\\n\"),\r\n };\r\n }, [responsiveStyles, theme.tokens.breakpoints, id]);\r\n}\r\n","\"use client\";\n\nimport { useMemo, type CSSProperties } from \"react\";\n\nimport type {\n CSSPropertiesWithVars,\n ResponsiveStyles,\n ResponsiveValue,\n} from \"@/types\";\nimport { isResponsiveValue } from \"@/utils/responsive\";\nimport { useTheme } from \"@/provider/useTheme\";\n\n/**\n * Options for {@link useSizeStyle}.\n */\nexport interface UseSizeStyleOptions {\n /**\n * Include `height` in the resolved style.\n * @default true\n */\n includeHeight?: boolean;\n\n /**\n * Include `width` in the resolved style.\n *\n * When enabled, width is derived from the token's own `width` if\n * `iconOnly` is set, otherwise from the token's `height`.\n * @default false\n */\n includeWidth?: boolean;\n\n /**\n * Force `width` to mirror `height`, even when not in icon-only mode.\n * @default false\n */\n widthFromHeight?: boolean;\n\n /**\n * CSS length subtracted from the resolved `height` / `width`\n * (e.g. `\"2px\"`). Applied via `calc(...)`.\n */\n sizeOffset?: string;\n\n /**\n * CSS length subtracted from the resolved `fontSize`.\n * Applied via `calc(...)`.\n */\n fontSizeOffset?: string;\n}\n\n/**\n * Result of {@link useSizeStyle}.\n */\nexport interface ResolvedSize {\n /**\n * Inline styles for non-responsive sizing.\n *\n * For responsive values this is intentionally empty so that\n * breakpoint styles can override each other through CSS.\n */\n style: CSSProperties;\n\n /**\n * Styles generated for responsive sizing.\n */\n responsiveStyles?: ResponsiveStyles;\n\n /** Resolved icon size, if defined on the token. */\n iconSize?: CSSProperties[\"width\"];\n\n /** Resolved font size, after applying `fontSizeOffset`. */\n fontSize?: CSSProperties[\"fontSize\"];\n\n /** Resolved gap between child elements. */\n gap?: CSSProperties[\"gap\"];\n}\n\nconst applySizeOffset = (\n value: string | undefined,\n offset: string | undefined,\n) => {\n if (!value || !offset) return value;\n\n return `calc(${value} - ${offset})`;\n};\n\nimport type { DesignTokens } from \"@/types\";\nimport { resolveFontSize, resolveTokenReference } from \"@/utils\";\n\n/**\n * Builds size-related inline styles from a theme size token.\n *\n * Accepts either a plain size name (e.g. `\"md\"`) or a responsive value\n * (e.g. `{ base: \"sm\", lg: \"md\" }`). All token values are expanded through\n * `resolveTokenReference`, so aliases like `\"{spacing.4}\"` become concrete\n * values.\n *\n * Behavior notes:\n * - Padding is skipped when `iconOnly` is `true`.\n * - `gap` is forced to `0` when `iconOnly` is `true`.\n * - The token's `radius` is exposed as the CSS variable\n * `--kui-<componentName>-radius` so consumers can reuse it in CSS.\n * - For responsive inputs, breakpoint styles are returned in\n * `responsiveStyles` and `style` stays empty.\n *\n * @param size - Size name or responsive size object to resolve.\n * @param iconOnly - When `true`, applies icon-specific sizing (square,\n * no horizontal padding, no gap).\n * @param componentName - Namespace used for generated CSS variables.\n * @param options - See {@link UseSizeStyleOptions}.\n * @returns A {@link ResolvedSize} containing inline and/or responsive styles.\n *\n * @example\n * ```ts\n * const { style } = useSizeStyle(\"md\");\n * // <button style={style} />\n * ```\n *\n * @example\n * ```ts\n * const { responsiveStyles } = useSizeStyle(\n * { base: \"sm\", lg: \"md\" },\n * false,\n * \"button\",\n * { includeWidth: true, sizeOffset: \"2px\" },\n * );\n * ```\n */\nexport function useSizeStyle(\n size: ResponsiveValue<string>,\n iconOnly = false,\n componentName = \"component\",\n options: UseSizeStyleOptions = {},\n): ResolvedSize {\n const {\n widthFromHeight = false,\n includeHeight = true,\n includeWidth = false,\n sizeOffset,\n fontSizeOffset,\n } = options;\n\n const { theme, fallbackSize } = useTheme();\n\n return useMemo(() => {\n const scale = theme.sizes;\n const tokens = theme.tokens as unknown as DesignTokens;\n const typography = theme.typography;\n\n const resolveValue = (value: unknown) =>\n String(resolveTokenReference(value, tokens));\n\n const resolveFont = (value: unknown) =>\n String(resolveFontSize(value, typography, tokens));\n\n const resolveToken = (sizeName: string) =>\n scale[sizeName] ?? scale[fallbackSize] ?? Object.values(scale)[0] ?? {};\n\n const buildStyle = (sizeName: string): CSSPropertiesWithVars => {\n const token = resolveToken(sizeName);\n const style: CSSPropertiesWithVars = {};\n\n const height = resolveValue(token.height);\n const width = resolveValue(token.width);\n const paddingX = resolveValue(token.paddingX);\n const paddingY = resolveValue(token.paddingY);\n const fontSize = resolveFont(token.fontSize);\n const gap = resolveValue(token.gap);\n const radius = resolveValue(token.radius);\n\n if (includeHeight && height) {\n style.height = applySizeOffset(height, sizeOffset);\n }\n\n if (includeWidth) {\n if (iconOnly && width) {\n style.width = applySizeOffset(width, sizeOffset);\n } else if ((iconOnly || widthFromHeight) && includeHeight && height) {\n style.width = applySizeOffset(height, sizeOffset);\n }\n }\n\n if (!iconOnly && paddingX) {\n style.paddingLeft = paddingX;\n style.paddingRight = paddingX;\n }\n\n if (paddingY) {\n style.paddingTop = paddingY;\n style.paddingBottom = paddingY;\n }\n\n if (fontSize) {\n style.fontSize = applySizeOffset(fontSize, fontSizeOffset);\n }\n\n if (gap) {\n style.gap = iconOnly ? 0 : gap;\n }\n\n if (radius) {\n const varName = `--kui-${componentName}-radius` as `--kui-${string}`;\n style[varName] = radius;\n }\n\n return style;\n };\n\n if (!isResponsiveValue(size)) {\n const style = buildStyle(size);\n const token = resolveToken(size);\n\n return {\n style,\n iconSize: resolveValue(token.iconSize),\n fontSize: applySizeOffset(resolveFont(token.fontSize), fontSizeOffset),\n gap: resolveValue(token.gap),\n };\n }\n\n const { base, ...breakpoints } = size;\n\n const baseSize = base ?? fallbackSize;\n\n const responsiveStyles: ResponsiveStyles = {\n base: buildStyle(baseSize),\n };\n\n for (const [breakpoint, breakpointSize] of Object.entries(breakpoints)) {\n if (breakpointSize === undefined) continue;\n\n responsiveStyles[breakpoint] = buildStyle(breakpointSize);\n }\n\n const token = resolveToken(baseSize);\n\n return {\n style: {},\n responsiveStyles,\n iconSize: resolveValue(token.iconSize),\n fontSize: applySizeOffset(resolveFont(token.fontSize), fontSizeOffset),\n gap: resolveValue(token.gap),\n };\n }, [\n theme,\n size,\n fallbackSize,\n iconOnly,\n includeHeight,\n includeWidth,\n widthFromHeight,\n componentName,\n sizeOffset,\n fontSizeOffset,\n ]);\n}\n","import type { ResponsiveValue, SizeToken, DesignTokens } from \"@/types\";\r\n\r\nimport { useMemo } from \"react\";\r\nimport { useTheme } from \"@/provider/useTheme\";\r\nimport { isResponsiveValue } from \"@/utils/responsive\";\r\nimport { resolveTokenReference } from \"@/utils/resolveTokenReference\";\r\nimport { resolveFontSize } from \"@/utils/resolveFontSize\";\r\n\r\ntype SizeTokenValue = SizeToken[keyof SizeToken];\r\n\r\nfunction applyOffset(value: SizeTokenValue, offset?: string): SizeTokenValue {\r\n if (offset == null || value == null) {\r\n return value;\r\n }\r\n\r\n if (typeof value !== \"string\") {\r\n return value;\r\n }\r\n\r\n return `calc(${value} - ${offset})`;\r\n}\r\n\r\n/**\r\n * Resolves a size token from the active theme.\r\n *\r\n * Accepts either a plain size name (e.g. `\"md\"`) or a responsive value\r\n * (e.g. `{ base: \"md\", lg: \"xl\" }`). When a responsive object is passed,\r\n * the `base` key is used, falling back to the theme's `fallbackSize`.\r\n *\r\n * All token values are passed through `resolveTokenReference`, so token\r\n * aliases like `\"{spacing.4}\"` are expanded to their concrete value.\r\n * `fontSize` is the one exception: it's a reference into `typography`,\r\n * not `tokens` directly, and is resolved via `resolveFontSize`.\r\n *\r\n * @param size - Size name or responsive size object to resolve.\r\n * @returns The full resolved {@link SizeToken} for the requested size.\r\n *\r\n * @example\r\n * ```ts\r\n * const token = useSizeToken(\"md\");\r\n * // { height: \"40px\", paddingX: \"16px\", fontSize: \"14px\", ... }\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * const token = useSizeToken({ base: \"sm\", lg: \"md\" });\r\n * ```\r\n */\r\nexport function useSizeToken(size: ResponsiveValue<string>): SizeToken;\r\n\r\n/**\r\n * Resolves a single value from a size token.\r\n *\r\n * Like the object overload, this accepts a plain or responsive size name and\r\n * expands token references. When `offset` is provided, the resolved value is\r\n * wrapped in a `calc(...)` expression subtracting the offset — useful for\r\n * trimming sizes without redefining a token.\r\n *\r\n * @typeParam K - The key of {@link SizeToken} to read (e.g. `\"height\"`, `\"fontSize\"`).\r\n * @param size - Size name or responsive size object to resolve.\r\n * @param key - The token field to read.\r\n * @param offset - Optional CSS length to subtract from the resolved value.\r\n * @returns The resolved (and optionally offset) token field.\r\n *\r\n * @example\r\n * ```ts\r\n * const height = useSizeToken(\"md\", \"height\");\r\n * // \"40px\"\r\n *\r\n * const height = useSizeToken(\"md\", \"height\", \"4px\");\r\n * // \"calc(40px - 4px)\"\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * const fontSize = useSizeToken({ base: \"sm\", lg: \"md\" }, \"fontSize\");\r\n * ```\r\n */\r\nexport function useSizeToken<K extends keyof SizeToken>(\r\n size: ResponsiveValue<string>,\r\n key: K,\r\n offset?: string,\r\n): SizeToken[K];\r\n\r\nexport function useSizeToken<K extends keyof SizeToken>(\r\n size: ResponsiveValue<string>,\r\n key?: K,\r\n offset?: string,\r\n): SizeToken | SizeToken[K] {\r\n const { theme, fallbackSize } = useTheme();\r\n\r\n return useMemo(() => {\r\n const scale = theme.sizes;\r\n const tokens = theme.tokens as unknown as DesignTokens;\r\n const typography = theme.typography;\r\n\r\n const baseSize = isResponsiveValue(size)\r\n ? (size.base ?? fallbackSize)\r\n : size;\r\n\r\n const token =\r\n scale[baseSize] ?? scale[fallbackSize] ?? Object.values(scale)[0] ?? {};\r\n\r\n const resolve = (value: unknown, field?: string) =>\r\n field === \"fontSize\"\r\n ? resolveFontSize(value, typography, tokens)\r\n : value == null\r\n ? value\r\n : resolveTokenReference(value, tokens);\r\n\r\n if (!key) {\r\n const resolved = Object.fromEntries(\r\n Object.entries(token).map(([k, v]) => [k, resolve(v, k)]),\r\n ) as SizeToken;\r\n\r\n return resolved;\r\n }\r\n\r\n return applyOffset(\r\n resolve(token[key], key) as SizeTokenValue,\r\n offset,\r\n ) as SizeToken[K];\r\n }, [theme, size, fallbackSize, key, offset]);\r\n}\r\n","import { useTheme } from \"@/provider/useTheme\";\r\nimport type { Size, Theme } from \"@/types\";\r\n\r\nexport function getSizes(theme: Theme): Size[] {\r\n return Object.keys(theme.sizes ?? {}) as Size[];\r\n}\r\n\r\nexport function useSizes(): Size[] {\r\n const { theme } = useTheme();\r\n return getSizes(theme);\r\n}\r\n","import { useTheme } from \"@/provider\";\r\nimport { resolveTypography } from \"@/utils\";\r\n\r\nexport function useTypography(name?: string) {\r\n const { theme } = useTheme();\r\n\r\n return resolveTypography(\r\n name ? theme.typography[name] : undefined,\r\n theme.tokens,\r\n );\r\n}","import { useCallback, useRef, useState } from \"react\";\r\n\r\ninterface UseUndoRedoOptions {\r\n /**\r\n * Maximum number of history entries to keep.\r\n * Only applies when `undoable` is `true` and the component manages its own history.\r\n * @default 30\r\n */\r\n maxHistory?: number;\r\n}\r\n\r\n/**\r\n * Manages a history stack for a value, providing undo/redo capabilities.\r\n * The hook stores the current value in its own state, but you can also\r\n * sync it with external state by calling `push` when the external value changes.\r\n *\r\n * @param initialValue - The starting value.\r\n * @param options - Configuration (maxHistory).\r\n * @returns An object with the current value, setters, and undo/redo controls.\r\n */\r\nexport function useUndoRedo<T>(\r\n initialValue: T,\r\n options: UseUndoRedoOptions & {\r\n onValueChange?: (value: T | undefined) => void;\r\n } = {},\r\n) {\r\n const { maxHistory = 30, onValueChange } = options;\r\n\r\n const [value, setValue] = useState<T | undefined>(initialValue);\r\n const historyRef = useRef<T[]>([initialValue]);\r\n const indexRef = useRef(0);\r\n\r\n const push = useCallback(\r\n (newValue: T) => {\r\n if (newValue === historyRef.current[indexRef.current]) return;\r\n\r\n historyRef.current = historyRef.current.slice(0, indexRef.current + 1);\r\n\r\n historyRef.current.push(newValue);\r\n if (historyRef.current.length > maxHistory) {\r\n historyRef.current = historyRef.current.slice(-maxHistory);\r\n indexRef.current = historyRef.current.length - 1;\r\n } else {\r\n indexRef.current = historyRef.current.length - 1;\r\n }\r\n\r\n setValue(newValue);\r\n onValueChange?.(newValue);\r\n },\r\n [maxHistory, onValueChange],\r\n );\r\n\r\n const undo = useCallback(() => {\r\n if (indexRef.current <= 0) return;\r\n indexRef.current -= 1;\r\n const newValue = historyRef.current[indexRef.current];\r\n setValue(newValue);\r\n onValueChange?.(newValue);\r\n }, [onValueChange]);\r\n\r\n const redo = useCallback(() => {\r\n if (indexRef.current >= historyRef.current.length - 1) return;\r\n indexRef.current += 1;\r\n const newVal = historyRef.current[indexRef.current];\r\n setValue(newVal);\r\n }, []);\r\n\r\n const reset = useCallback(\r\n (newValue: T) => {\r\n historyRef.current = [newValue];\r\n indexRef.current = 0;\r\n setValue(newValue);\r\n onValueChange?.(newValue);\r\n },\r\n [onValueChange],\r\n );\r\n\r\n const canUndo = indexRef.current > 0;\r\n const canRedo = indexRef.current < historyRef.current.length - 1;\r\n\r\n return {\r\n value,\r\n setValue,\r\n push,\r\n undo,\r\n redo,\r\n reset,\r\n canUndo,\r\n canRedo,\r\n history: historyRef.current,\r\n currentIndex: indexRef.current,\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useBreakpoint.ts","../../src/hooks/useColorMode.ts","../../src/hooks/useControllableState.ts","../../src/hooks/useMergedResponsiveStyles.ts","../../src/hooks/useResponsiveStyles.ts","../../src/hooks/useSizeStyle.ts","../../src/hooks/useSizeToken.ts","../../src/hooks/useSizes.ts","../../src/hooks/useTypography.ts","../../src/hooks/useUndoRedo.ts"],"names":["useMemo","useState","useRef","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\r\n\r\nimport { BaseBreakpoint } from \"@/types\";\r\nimport { useEffect, useState } from \"react\";\r\n\r\nconst BREAKPOINTS: Record<BaseBreakpoint, number> = {\r\n sm: 640,\r\n md: 768,\r\n lg: 1024,\r\n xl: 1280,\r\n \"2xl\": 1536,\r\n};\r\n\r\nexport function useBreakpoint(breakpoint: BaseBreakpoint): boolean {\r\n const query = `(min-width: ${BREAKPOINTS[breakpoint]}px)`;\r\n const [matches, setMatches] = useState(\r\n () => typeof window !== \"undefined\" && window.matchMedia(query).matches,\r\n );\r\n\r\n useEffect(() => {\r\n const mql = window.matchMedia(query);\r\n const listener = (e: MediaQueryListEvent) => setMatches(e.matches);\r\n mql.addEventListener(\"change\", listener);\r\n setMatches(mql.matches);\r\n return () => mql.removeEventListener(\"change\", listener);\r\n }, [query]);\r\n\r\n return matches;\r\n}\r\n","import { useContext } from \"react\";\nimport { ThemeContext } from \"../provider/ThemeContext\";\nimport { ColorMode } from \"@/types/theme\";\n\nexport interface UseColorModeReturn {\n mode: ColorMode;\n setMode: (mode: ColorMode) => void;\n toggleColorMode: () => void;\n}\n\nexport function useColorMode(): UseColorModeReturn {\n const ctx = useContext(ThemeContext);\n\n if (!ctx) {\n throw new Error(\"useColorMode must be used within a ThemeProvider\");\n }\n\n return {\n mode: ctx.mode,\n setMode: ctx.setMode,\n toggleColorMode: () => {\n throw new Error(\"not implemented\");\n },\n };\n}\n","import * as React from \"react\";\n\nexport interface UseControllableStateOptions<T> {\n value?: T;\n defaultValue: T;\n onChange?: (next: T) => void;\n}\n\nexport function useControllableState<T>({\n value,\n defaultValue,\n onChange,\n}: UseControllableStateOptions<T>): [T, (next: T) => void] {\n const [internal, setInternal] = React.useState<T>(defaultValue);\n const isControlled = value !== undefined;\n const current = isControlled ? (value as T) : internal;\n const currentRef = React.useRef(current);\n currentRef.current = current;\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n\n const set = React.useCallback(\n (next: T) => {\n if (Object.is(next, currentRef.current)) return;\n if (!isControlled) setInternal(next);\n onChangeRef.current?.(next);\n },\n [isControlled],\n );\n return [current, set];\n}\n","\"use client\";\r\n\r\nimport { useMemo } from \"react\";\r\nimport type { CSSProperties } from \"react\";\r\nimport type { ResponsiveValue, ResponsiveStyles } from \"@/types\";\r\nimport { resolveResponsiveValue } from \"@/utils/responsive\";\r\n\r\n/**\r\n * One entry: a responsive prop value plus a mapper from that value to a\r\n * partial CSSProperties object.\r\n *\r\n * Using `any` for the value type because different entries may have different\r\n * value types, and we only need to call the mapper with the resolved value.\r\n */\r\nexport type ResponsivePropEntry = [\r\n value: ResponsiveValue<any> | undefined,\r\n toCss: (value: any) => Partial<CSSProperties>,\r\n];\r\n\r\nfunction mergeResponsiveProps(\r\n entries: ResponsivePropEntry[],\r\n): ResponsiveStyles {\r\n const result: ResponsiveStyles = {};\r\n\r\n for (const [value, toCss] of entries) {\r\n if (value === undefined) continue;\r\n\r\n const { base, responsive } = resolveResponsiveValue(value);\r\n\r\n if (base !== undefined) {\r\n result.base = { ...result.base, ...toCss(base) };\r\n }\r\n\r\n for (const [bp, v] of Object.entries(responsive)) {\r\n result[bp] = { ...result[bp], ...toCss(v) };\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n\r\n/**\r\n * Merges multiple ResponsiveValue<T> props into one ResponsiveStyles map,\r\n * memoized on the entries' values.\r\n *\r\n * @example\r\n * const responsiveStyles = useMergedResponsiveStyles([\r\n * [gap, (v) => ({ gap: spaceVar(v) })],\r\n * [align, (v) => ({ alignItems: v })],\r\n * ]);\r\n */\r\nexport function useMergedResponsiveStyles(\r\n entries: ResponsivePropEntry[],\r\n): ResponsiveStyles {\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n return useMemo(\r\n () => mergeResponsiveProps(entries),\r\n entries.map(([value]) => value),\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { type CSSProperties, useId, useMemo } from \"react\";\r\n\r\nimport type { ResponsiveStyles } from \"@/types\";\r\nimport { useTheme } from \"@/provider/useTheme\";\r\n\r\nconst cssPropertyToKebab = (property: string) =>\r\n property.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);\r\n\r\nconst cssValue = (value: CSSProperties[keyof CSSProperties]) => {\r\n if (typeof value === \"number\") {\r\n return String(value);\r\n }\r\n\r\n return value;\r\n};\r\n\r\nexport function useResponsiveStyles(responsiveStyles?: ResponsiveStyles) {\r\n const { theme } = useTheme();\r\n const id = useId();\r\n\r\n return useMemo(() => {\r\n if (!responsiveStyles || Object.keys(responsiveStyles).length === 0) {\r\n return {\r\n attribute: undefined,\r\n style: undefined,\r\n };\r\n }\r\n\r\n const breakpoints = theme.tokens.breakpoints;\r\n\r\n if (!breakpoints) {\r\n return {\r\n attribute: undefined,\r\n style: undefined,\r\n };\r\n }\r\n\r\n const attribute = id.replace(/:/g, \"\");\r\n\r\n const selector = `[data-kui-responsive=\"${attribute}\"]`;\r\n\r\n const rules: string[] = [];\r\n\r\n for (const [breakpoint, styles] of Object.entries(responsiveStyles)) {\r\n const declarations = Object.entries(styles)\r\n .filter(([, value]) => value !== undefined)\r\n .map(\r\n ([property, value]) =>\r\n `${cssPropertyToKebab(property)}:${cssValue(value)};`,\r\n )\r\n .join(\"\");\r\n\r\n if (!declarations) continue;\r\n\r\n if (breakpoint === \"base\") {\r\n rules.push(`\r\n ${selector} {\r\n ${declarations}\r\n }\r\n `);\r\n\r\n continue;\r\n }\r\n\r\n const breakpointToken = breakpoints[breakpoint];\r\n\r\n if (!breakpointToken) continue;\r\n\r\n rules.push(`\r\n @media (min-width: ${breakpointToken.value}) {\r\n ${selector} {\r\n ${declarations}\r\n }\r\n }\r\n `);\r\n }\r\n\r\n if (rules.length === 0) {\r\n return {\r\n attribute: undefined,\r\n style: undefined,\r\n };\r\n }\r\n\r\n return {\r\n attribute,\r\n style: rules.join(\"\\n\"),\r\n };\r\n }, [responsiveStyles, theme.tokens.breakpoints, id]);\r\n}\r\n","\"use client\";\n\nimport { useMemo, type CSSProperties } from \"react\";\nimport type { DesignTokens } from \"@/types\";\nimport { resolveFontSize, resolveTokenReference } from \"@/utils\";\nimport type {\n CSSPropertiesWithVars,\n ResponsiveStyles,\n ResponsiveValue,\n} from \"@/types\";\nimport { isResponsiveValue } from \"@/utils/responsive\";\nimport { useTheme } from \"@/provider/useTheme\";\n\n/**\n * Options for {@link useSizeStyle}.\n */\nexport interface UseSizeStyleOptions {\n /**\n * Include `height` in the resolved style.\n * @default true\n */\n includeHeight?: boolean;\n\n /**\n * Include `width` in the resolved style.\n *\n * When enabled, width is derived from the token's own `width` if\n * `iconOnly` is set, otherwise from the token's `height`.\n * @default false\n */\n includeWidth?: boolean;\n\n /**\n * Force `width` to mirror `height`, even when not in icon-only mode.\n * @default false\n */\n widthFromHeight?: boolean;\n\n /**\n * CSS length subtracted from the resolved `height` / `width`\n * (e.g. `\"2px\"`). Applied via `calc(...)`.\n */\n sizeOffset?: string;\n\n /**\n * CSS length subtracted from the resolved `fontSize`.\n * Applied via `calc(...)`.\n */\n fontSizeOffset?: string;\n}\n\n/**\n * Result of {@link useSizeStyle}.\n */\nexport interface ResolvedSize {\n /**\n * CSS custom properties (`--kui-<componentName>-*`) for sizing.\n * Consumed by the matching recipe's Tailwind arbitrary-value classes\n * (e.g. `h-[var(--kui-button-height)]`), not applied as literal\n * CSS properties directly — recipes own the actual property mapping.\n *\n * For responsive values this is intentionally empty so that\n * breakpoint styles can override each other through CSS.\n */\n style: CSSPropertiesWithVars;\n\n /**\n * Styles generated for responsive sizing.\n */\n responsiveStyles?: ResponsiveStyles;\n\n /** Resolved icon size, if defined on the token. */\n iconSize?: CSSProperties[\"width\"];\n\n /** Resolved font size, after applying `fontSizeOffset`. */\n fontSize?: CSSProperties[\"fontSize\"];\n\n /** Resolved gap between child elements. */\n gap?: CSSProperties[\"gap\"];\n\n /** Resolved horizontal padding, for callers that need the raw value in JS (e.g. a `calc()` computed on top of it). */\n paddingX?: CSSProperties[\"paddingLeft\"];\n\n /** Resolved vertical padding, for callers that need the raw value in JS (e.g. a `calc()` computed on top of it). */\n paddingY?: CSSProperties[\"paddingTop\"];\n}\n\nconst applySizeOffset = (\n value: string | undefined,\n offset: string | undefined,\n) => {\n if (!value || !offset) return value;\n\n return `calc(${value} - ${offset})`;\n};\n\n/**\n * Builds size-related inline styles from a theme size token.\n *\n * Accepts either a plain size name (e.g. `\"md\"`) or a responsive value\n * (e.g. `{ base: \"sm\", lg: \"md\" }`). All token values are expanded through\n * `resolveTokenReference`, so aliases like `\"{spacing.4}\"` become concrete\n * values.\n *\n * Behavior notes:\n * - Padding is skipped when `iconOnly` is `true`.\n * - `gap` is forced to `0` when `iconOnly` is `true`.\n * - The token's `radius` is exposed as the CSS variable\n * `--kui-<componentName>-radius` so consumers can reuse it in CSS.\n * - For responsive inputs, breakpoint styles are returned in\n * `responsiveStyles` and `style` stays empty.\n *\n * @param size - Size name or responsive size object to resolve.\n * @param iconOnly - When `true`, applies icon-specific sizing (square,\n * no horizontal padding, no gap).\n * @param componentName - Namespace used for generated CSS variables.\n * @param options - See {@link UseSizeStyleOptions}.\n * @returns A {@link ResolvedSize} containing inline and/or responsive styles.\n *\n * @example\n * ```ts\n * const { style } = useSizeStyle(\"md\");\n * // <button style={style} />\n * ```\n *\n * @example\n * ```ts\n * const { responsiveStyles } = useSizeStyle(\n * { base: \"sm\", lg: \"md\" },\n * false,\n * \"button\",\n * { includeWidth: true, sizeOffset: \"2px\" },\n * );\n * ```\n */\nexport function useSizeStyle(\n size: ResponsiveValue<string>,\n iconOnly = false,\n componentName = \"component\",\n options: UseSizeStyleOptions = {},\n): ResolvedSize {\n const {\n widthFromHeight = false,\n includeHeight = true,\n includeWidth = false,\n sizeOffset,\n fontSizeOffset,\n } = options;\n\n const { theme, fallbackSize } = useTheme();\n\n return useMemo(() => {\n const scale = theme.sizes;\n const tokens = theme.tokens as unknown as DesignTokens;\n const typography = theme.typography;\n\n const resolveValue = (value: unknown) =>\n String(resolveTokenReference(value, tokens));\n\n const resolveFont = (value: unknown) =>\n String(resolveFontSize(value, typography, tokens));\n\n const resolveToken = (sizeName: string) =>\n scale[sizeName] ?? scale[fallbackSize] ?? Object.values(scale)[0] ?? {};\n\n const setVar = (\n style: CSSPropertiesWithVars,\n prop: string,\n value: string | undefined,\n ) => {\n if (value === undefined) return;\n style[`--kui-${componentName}-${prop}` as `--kui-${string}`] = value;\n };\n\n const buildStyle = (sizeName: string): CSSPropertiesWithVars => {\n const token = resolveToken(sizeName);\n const style: CSSPropertiesWithVars = {};\n\n const height = resolveValue(token.height);\n const width = resolveValue(token.width);\n const paddingX = resolveValue(token.paddingX);\n const paddingY = resolveValue(token.paddingY);\n const fontSize = resolveFont(token.fontSize);\n const gap = resolveValue(token.gap);\n const radius = resolveValue(token.radius);\n\n if (includeHeight && height) {\n setVar(style, \"height\", applySizeOffset(height, sizeOffset));\n }\n\n if (includeWidth) {\n if (iconOnly && width) {\n setVar(style, \"width\", applySizeOffset(width, sizeOffset));\n } else if ((iconOnly || widthFromHeight) && includeHeight && height) {\n setVar(style, \"width\", applySizeOffset(height, sizeOffset));\n }\n }\n\n if (!iconOnly && paddingX) {\n setVar(style, \"padding-x\", paddingX);\n }\n\n if (paddingY) {\n setVar(style, \"padding-y\", paddingY);\n }\n\n if (fontSize) {\n setVar(style, \"font-size\", applySizeOffset(fontSize, fontSizeOffset));\n }\n\n if (gap) {\n setVar(style, \"gap\", iconOnly ? \"0\" : gap);\n }\n\n if (radius) {\n setVar(style, \"radius\", radius);\n }\n\n return style;\n };\n\n const buildResolvedExtras = (sizeName: string) => {\n const token = resolveToken(sizeName);\n\n return {\n iconSize: resolveValue(token.iconSize),\n fontSize: applySizeOffset(resolveFont(token.fontSize), fontSizeOffset),\n gap: resolveValue(token.gap),\n paddingX: !iconOnly ? resolveValue(token.paddingX) : undefined,\n paddingY: resolveValue(token.paddingY),\n };\n };\n\n if (!isResponsiveValue(size)) {\n const style = buildStyle(size);\n\n return {\n style,\n ...buildResolvedExtras(size),\n };\n }\n\n const { base, ...breakpoints } = size;\n const baseSize = base ?? fallbackSize;\n\n const responsiveStyles: ResponsiveStyles = {\n base: buildStyle(baseSize),\n };\n\n for (const [breakpoint, breakpointSize] of Object.entries(breakpoints)) {\n if (breakpointSize === undefined) continue;\n responsiveStyles[breakpoint] = buildStyle(breakpointSize);\n }\n\n return {\n style: {},\n responsiveStyles,\n ...buildResolvedExtras(baseSize),\n };\n }, [\n theme,\n size,\n fallbackSize,\n iconOnly,\n includeHeight,\n includeWidth,\n widthFromHeight,\n componentName,\n sizeOffset,\n fontSizeOffset,\n ]);\n}\n","import type { ResponsiveValue, SizeToken, DesignTokens } from \"@/types\";\r\n\r\nimport { useMemo } from \"react\";\r\nimport { useTheme } from \"@/provider/useTheme\";\r\nimport { isResponsiveValue } from \"@/utils/responsive\";\r\nimport { resolveTokenReference } from \"@/utils/resolveTokenReference\";\r\nimport { resolveFontSize } from \"@/utils/resolveFontSize\";\r\n\r\ntype SizeTokenValue = SizeToken[keyof SizeToken];\r\n\r\nfunction applyOffset(value: SizeTokenValue, offset?: string): SizeTokenValue {\r\n if (offset == null || value == null) {\r\n return value;\r\n }\r\n\r\n if (typeof value !== \"string\") {\r\n return value;\r\n }\r\n\r\n return `calc(${value} - ${offset})`;\r\n}\r\n\r\n/**\r\n * Resolves a size token from the active theme.\r\n *\r\n * Accepts either a plain size name (e.g. `\"md\"`) or a responsive value\r\n * (e.g. `{ base: \"md\", lg: \"xl\" }`). When a responsive object is passed,\r\n * the `base` key is used, falling back to the theme's `fallbackSize`.\r\n *\r\n * All token values are passed through `resolveTokenReference`, so token\r\n * aliases like `\"{spacing.4}\"` are expanded to their concrete value.\r\n * `fontSize` is the one exception: it's a reference into `typography`,\r\n * not `tokens` directly, and is resolved via `resolveFontSize`.\r\n *\r\n * @param size - Size name or responsive size object to resolve.\r\n * @returns The full resolved {@link SizeToken} for the requested size.\r\n *\r\n * @example\r\n * ```ts\r\n * const token = useSizeToken(\"md\");\r\n * // { height: \"40px\", paddingX: \"16px\", fontSize: \"14px\", ... }\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * const token = useSizeToken({ base: \"sm\", lg: \"md\" });\r\n * ```\r\n */\r\nexport function useSizeToken(size: ResponsiveValue<string>): SizeToken;\r\n\r\n/**\r\n * Resolves a single value from a size token.\r\n *\r\n * Like the object overload, this accepts a plain or responsive size name and\r\n * expands token references. When `offset` is provided, the resolved value is\r\n * wrapped in a `calc(...)` expression subtracting the offset — useful for\r\n * trimming sizes without redefining a token.\r\n *\r\n * @typeParam K - The key of {@link SizeToken} to read (e.g. `\"height\"`, `\"fontSize\"`).\r\n * @param size - Size name or responsive size object to resolve.\r\n * @param key - The token field to read.\r\n * @param offset - Optional CSS length to subtract from the resolved value.\r\n * @returns The resolved (and optionally offset) token field.\r\n *\r\n * @example\r\n * ```ts\r\n * const height = useSizeToken(\"md\", \"height\");\r\n * // \"40px\"\r\n *\r\n * const height = useSizeToken(\"md\", \"height\", \"4px\");\r\n * // \"calc(40px - 4px)\"\r\n * ```\r\n *\r\n * @example\r\n * ```ts\r\n * const fontSize = useSizeToken({ base: \"sm\", lg: \"md\" }, \"fontSize\");\r\n * ```\r\n */\r\nexport function useSizeToken<K extends keyof SizeToken>(\r\n size: ResponsiveValue<string>,\r\n key: K,\r\n offset?: string,\r\n): SizeToken[K];\r\n\r\nexport function useSizeToken<K extends keyof SizeToken>(\r\n size: ResponsiveValue<string>,\r\n key?: K,\r\n offset?: string,\r\n): SizeToken | SizeToken[K] {\r\n const { theme, fallbackSize } = useTheme();\r\n\r\n return useMemo(() => {\r\n const scale = theme.sizes;\r\n const tokens = theme.tokens as unknown as DesignTokens;\r\n const typography = theme.typography;\r\n\r\n const baseSize = isResponsiveValue(size)\r\n ? (size.base ?? fallbackSize)\r\n : size;\r\n\r\n const token =\r\n scale[baseSize] ?? scale[fallbackSize] ?? Object.values(scale)[0] ?? {};\r\n\r\n const resolve = (value: unknown, field?: string) =>\r\n field === \"fontSize\"\r\n ? resolveFontSize(value, typography, tokens)\r\n : value == null\r\n ? value\r\n : resolveTokenReference(value, tokens);\r\n\r\n if (!key) {\r\n const resolved = Object.fromEntries(\r\n Object.entries(token).map(([k, v]) => [k, resolve(v, k)]),\r\n ) as SizeToken;\r\n\r\n return resolved;\r\n }\r\n\r\n return applyOffset(\r\n resolve(token[key], key) as SizeTokenValue,\r\n offset,\r\n ) as SizeToken[K];\r\n }, [theme, size, fallbackSize, key, offset]);\r\n}\r\n","import { useTheme } from \"@/provider/useTheme\";\r\nimport type { Size, Theme } from \"@/types\";\r\n\r\nexport function getSizes(theme: Theme): Size[] {\r\n return Object.keys(theme.sizes ?? {}) as Size[];\r\n}\r\n\r\nexport function useSizes(): Size[] {\r\n const { theme } = useTheme();\r\n return getSizes(theme);\r\n}\r\n","import { useTheme } from \"@/provider\";\r\nimport { resolveTypography } from \"@/utils\";\r\n\r\nexport function useTypography(name?: string) {\r\n const { theme } = useTheme();\r\n\r\n return resolveTypography(\r\n name ? theme.typography[name] : undefined,\r\n theme.tokens,\r\n );\r\n}","import { useCallback, useRef, useState } from \"react\";\r\n\r\ninterface UseUndoRedoOptions {\r\n /**\r\n * Maximum number of history entries to keep.\r\n * Only applies when `undoable` is `true` and the component manages its own history.\r\n * @default 30\r\n */\r\n maxHistory?: number;\r\n}\r\n\r\n/**\r\n * Manages a history stack for a value, providing undo/redo capabilities.\r\n * The hook stores the current value in its own state, but you can also\r\n * sync it with external state by calling `push` when the external value changes.\r\n *\r\n * @param initialValue - The starting value.\r\n * @param options - Configuration (maxHistory).\r\n * @returns An object with the current value, setters, and undo/redo controls.\r\n */\r\nexport function useUndoRedo<T>(\r\n initialValue: T,\r\n options: UseUndoRedoOptions & {\r\n onValueChange?: (value: T | undefined) => void;\r\n } = {},\r\n) {\r\n const { maxHistory = 30, onValueChange } = options;\r\n\r\n const [value, setValue] = useState<T | undefined>(initialValue);\r\n const historyRef = useRef<T[]>([initialValue]);\r\n const indexRef = useRef(0);\r\n\r\n const push = useCallback(\r\n (newValue: T) => {\r\n if (newValue === historyRef.current[indexRef.current]) return;\r\n\r\n historyRef.current = historyRef.current.slice(0, indexRef.current + 1);\r\n\r\n historyRef.current.push(newValue);\r\n if (historyRef.current.length > maxHistory) {\r\n historyRef.current = historyRef.current.slice(-maxHistory);\r\n indexRef.current = historyRef.current.length - 1;\r\n } else {\r\n indexRef.current = historyRef.current.length - 1;\r\n }\r\n\r\n setValue(newValue);\r\n onValueChange?.(newValue);\r\n },\r\n [maxHistory, onValueChange],\r\n );\r\n\r\n const undo = useCallback(() => {\r\n if (indexRef.current <= 0) return;\r\n indexRef.current -= 1;\r\n const newValue = historyRef.current[indexRef.current];\r\n setValue(newValue);\r\n onValueChange?.(newValue);\r\n }, [onValueChange]);\r\n\r\n const redo = useCallback(() => {\r\n if (indexRef.current >= historyRef.current.length - 1) return;\r\n indexRef.current += 1;\r\n const newVal = historyRef.current[indexRef.current];\r\n setValue(newVal);\r\n }, []);\r\n\r\n const reset = useCallback(\r\n (newValue: T) => {\r\n historyRef.current = [newValue];\r\n indexRef.current = 0;\r\n setValue(newValue);\r\n onValueChange?.(newValue);\r\n },\r\n [onValueChange],\r\n );\r\n\r\n const canUndo = indexRef.current > 0;\r\n const canRedo = indexRef.current < historyRef.current.length - 1;\r\n\r\n return {\r\n value,\r\n setValue,\r\n push,\r\n undo,\r\n redo,\r\n reset,\r\n canUndo,\r\n canRedo,\r\n history: historyRef.current,\r\n currentIndex: indexRef.current,\r\n };\r\n}\r\n"]}
|
package/package.json
CHANGED