kang-components 0.9.5 → 0.9.7

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.
@@ -0,0 +1,16 @@
1
+ import { ReactElement, ReactNode } from 'react';
2
+ export interface AnimatedHeightProps {
3
+ children: ReactNode;
4
+ }
5
+ /**
6
+ * Wraps children in a container that smoothly animates height changes.
7
+ * Uses ResizeObserver to detect content size changes and react-spring
8
+ * to animate the container height. First measurement is immediate
9
+ * (no animation); subsequent changes animate with SPRING_RESPONSIVE.
10
+ *
11
+ * Domain-free layout primitive — lives in kang so every app animates
12
+ * expand/collapse with the same physics. Falls back to `auto` height where
13
+ * ResizeObserver is unavailable.
14
+ */
15
+ export declare const AnimatedHeight: ({ children }: AnimatedHeightProps) => ReactElement;
16
+ //# sourceMappingURL=animated-height.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animated-height.d.ts","sourceRoot":"","sources":["../src/animated-height.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAA+B,MAAM,OAAO,CAAC;AAI7E,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,SAAS,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,iBAAkB,mBAAmB,KAAG,YAoClE,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useRef, useEffect, useState } from 'react';
3
+ import { useSpring, animated } from '@react-spring/web';
4
+ import { SPRING_RESPONSIVE } from './spring.js';
5
+ /**
6
+ * Wraps children in a container that smoothly animates height changes.
7
+ * Uses ResizeObserver to detect content size changes and react-spring
8
+ * to animate the container height. First measurement is immediate
9
+ * (no animation); subsequent changes animate with SPRING_RESPONSIVE.
10
+ *
11
+ * Domain-free layout primitive — lives in kang so every app animates
12
+ * expand/collapse with the same physics. Falls back to `auto` height where
13
+ * ResizeObserver is unavailable.
14
+ */
15
+ export const AnimatedHeight = ({ children }) => {
16
+ const contentRef = useRef(null);
17
+ const initializedRef = useRef(false);
18
+ const [isReady, setIsReady] = useState(false);
19
+ const [spring, api] = useSpring(() => ({ height: 0 }));
20
+ useEffect(() => {
21
+ const el = contentRef.current;
22
+ if (!el || typeof ResizeObserver === 'undefined')
23
+ return;
24
+ const observer = new ResizeObserver((entries) => {
25
+ const entry = entries[0];
26
+ if (!entry)
27
+ return;
28
+ const newHeight = entry.contentRect.height;
29
+ if (!initializedRef.current) {
30
+ initializedRef.current = true;
31
+ api.set({ height: newHeight });
32
+ setIsReady(true);
33
+ return;
34
+ }
35
+ api.start({ height: newHeight, config: SPRING_RESPONSIVE });
36
+ });
37
+ observer.observe(el);
38
+ return () => observer.disconnect();
39
+ }, [api]);
40
+ return (_jsx(animated.div, { style: { overflow: 'hidden', height: isReady ? spring.height : 'auto' }, children: _jsx("div", { ref: contentRef, children: children }) }));
41
+ };
42
+ //# sourceMappingURL=animated-height.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animated-height.js","sourceRoot":"","sources":["../src/animated-height.tsx"],"names":[],"mappings":";AAAA,OAAO,EAA2B,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAMhD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAAE,QAAQ,EAAuB,EAAgB,EAAE;IACjF,MAAM,UAAU,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAChD,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACrC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAEvD,SAAS,CAAC,GAAG,EAAE;QACd,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC;QAC9B,IAAI,CAAC,EAAE,IAAI,OAAO,cAAc,KAAK,WAAW;YAAE,OAAO;QAEzD,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE;YAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK;gBAAE,OAAO;YACnB,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;YAE3C,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC7B,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC;gBAC9B,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAC/B,UAAU,CAAC,IAAI,CAAC,CAAC;gBACjB,OAAO;YACR,CAAC;YAED,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrB,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,OAAO,CACN,KAAC,QAAQ,CAAC,GAAG,IAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,YACpF,cAAK,GAAG,EAAE,UAAU,YAClB,QAAQ,GACJ,GACQ,CACf,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface ConfettiProps {
2
+ /** When true, the burst plays once on mount. */
3
+ active: boolean;
4
+ /** Optional text tokens (characters / phonics) sprinkled among the shapes. */
5
+ tokens?: string[];
6
+ /** Total number of pieces. */
7
+ count?: number;
8
+ /** Approximate lifetime of the burst in ms. */
9
+ durationMs?: number;
10
+ }
11
+ /**
12
+ * Lightweight, dependency-free celebratory confetti. Pieces are GPU-animated
13
+ * via a single CSS keyframe; per-piece motion is randomized through inline CSS
14
+ * custom properties (in pixels). Mix in text tokens to rain played
15
+ * characters/phonics.
16
+ *
17
+ * Rendered through a portal to <body> as a viewport-fixed overlay so it lives
18
+ * outside any fixed/overflow/contain subtree — that nesting was freezing the
19
+ * fall mid-viewport on iOS Safari.
20
+ *
21
+ * The burst is computed ONCE when it starts (active false→true) and frozen for
22
+ * its lifetime. Incidental re-renders must not re-roll the pieces: callers may
23
+ * derive `tokens` from objects whose identity churns (e.g. GunJS emits).
24
+ * Recomputing mid-fall would change each piece's animation target
25
+ * (--start/--dx/--dist/duration) while the keyframe is in flight, which
26
+ * stalls/jumps the pieces mid-viewport on iOS.
27
+ */
28
+ export declare function Confetti({ active, tokens, count, durationMs }: ConfettiProps): import("react").ReactPortal | null;
29
+ //# sourceMappingURL=confetti.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confetti.d.ts","sourceRoot":"","sources":["../src/confetti.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,aAAa;IAC7B,gDAAgD;IAChD,MAAM,EAAE,OAAO,CAAC;IAChB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAqDD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAU,EAAE,UAAiB,EAAE,EAAE,aAAa,sCA0DxF"}
@@ -0,0 +1,109 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from 'react';
3
+ import { createPortal } from 'react-dom';
4
+ import { tilePalette } from './tile-palette.js';
5
+ import { ConfettiLayer, ConfettiPiece } from './confetti.styles.js';
6
+ /** Airy pastel fills for the shape pieces — the shared word-tile palette. */
7
+ const SHAPE_COLORS = tilePalette.map((color) => color.bg);
8
+ /** Saturated tones for text pieces so glyphs stay legible on light surfaces. */
9
+ const TEXT_COLORS = [
10
+ '#1976D2', '#388E3C', '#8E24AA', '#F4511E',
11
+ '#0097A7', '#F9A825', '#5E35B1', '#039BE5',
12
+ ];
13
+ /**
14
+ * Build one immutable burst of pieces. Travel is computed in PIXELS from the
15
+ * current viewport (never vh/vw, which iOS recomputes when its address bar
16
+ * collapses). Called once when a burst starts; the result is frozen for the
17
+ * lifetime of that burst (see the component below).
18
+ */
19
+ function buildPieces(tokens, count, durationMs) {
20
+ const toks = tokens?.filter(Boolean) ?? [];
21
+ const vh = typeof window !== 'undefined' ? window.innerHeight : 800;
22
+ const vw = typeof window !== 'undefined' ? window.innerWidth : 400;
23
+ return Array.from({ length: count }, (_, i) => {
24
+ // Roughly 55% text pieces when tokens are available.
25
+ const useText = toks.length > 0 && i % 9 < 5;
26
+ const text = useText ? toks[i % toks.length] : null;
27
+ return {
28
+ key: i,
29
+ text,
30
+ color: useText
31
+ ? TEXT_COLORS[i % TEXT_COLORS.length]
32
+ : SHAPE_COLORS[i % SHAPE_COLORS.length],
33
+ startX: 50 + (Math.random() * 44 - 22), // start near center, spread out
34
+ start: -vh * 0.12, // above the viewport
35
+ drift: (Math.random() * 2 - 1) * vw * 0.5, // px left/right
36
+ dist: vh * (0.95 + Math.random() * 0.35), // px — comfortably past the bottom
37
+ rot: (Math.random() * 6 - 3) * 360, // deg
38
+ delay: Math.random() * 260, // ms
39
+ dur: durationMs * (0.7 + Math.random() * 0.5),
40
+ size: 7 + Math.random() * 8,
41
+ round: Math.random() > 0.6,
42
+ };
43
+ });
44
+ }
45
+ /**
46
+ * Lightweight, dependency-free celebratory confetti. Pieces are GPU-animated
47
+ * via a single CSS keyframe; per-piece motion is randomized through inline CSS
48
+ * custom properties (in pixels). Mix in text tokens to rain played
49
+ * characters/phonics.
50
+ *
51
+ * Rendered through a portal to <body> as a viewport-fixed overlay so it lives
52
+ * outside any fixed/overflow/contain subtree — that nesting was freezing the
53
+ * fall mid-viewport on iOS Safari.
54
+ *
55
+ * The burst is computed ONCE when it starts (active false→true) and frozen for
56
+ * its lifetime. Incidental re-renders must not re-roll the pieces: callers may
57
+ * derive `tokens` from objects whose identity churns (e.g. GunJS emits).
58
+ * Recomputing mid-fall would change each piece's animation target
59
+ * (--start/--dx/--dist/duration) while the keyframe is in flight, which
60
+ * stalls/jumps the pieces mid-viewport on iOS.
61
+ */
62
+ export function Confetti({ active, tokens, count = 64, durationMs = 2600 }) {
63
+ const [pieces, setPieces] = useState([]);
64
+ const [visible, setVisible] = useState(false);
65
+ // Latest tokens, read only at burst start so token-identity churn during a
66
+ // burst never reaches buildPieces.
67
+ const tokensRef = useRef(tokens);
68
+ tokensRef.current = tokens;
69
+ useEffect(() => {
70
+ if (!active) {
71
+ setVisible(false);
72
+ return;
73
+ }
74
+ setPieces(buildPieces(tokensRef.current, count, durationMs));
75
+ setVisible(true);
76
+ const longest = durationMs * 1.2 + 300;
77
+ const t = setTimeout(() => setVisible(false), longest);
78
+ return () => clearTimeout(t);
79
+ }, [active, count, durationMs]);
80
+ if (!visible || typeof document === 'undefined')
81
+ return null;
82
+ const layer = (_jsx(ConfettiLayer, { "aria-hidden": "true", children: pieces.map((p) => {
83
+ const base = {
84
+ left: `${p.startX}%`,
85
+ animationDelay: `${p.delay}ms`,
86
+ animationDuration: `${p.dur}ms`,
87
+ ['--start']: `${p.start}px`,
88
+ ['--dx']: `${p.drift}px`,
89
+ ['--dist']: `${p.dist}px`,
90
+ ['--rot']: `${p.rot}deg`,
91
+ };
92
+ const visual = p.text
93
+ ? {
94
+ color: p.color,
95
+ fontSize: `${p.size + 8}px`,
96
+ fontWeight: 800,
97
+ lineHeight: 1,
98
+ }
99
+ : {
100
+ background: p.color,
101
+ width: `${p.size}px`,
102
+ height: `${p.size * 1.4}px`,
103
+ borderRadius: p.round ? '50%' : '2px',
104
+ };
105
+ return (_jsx(ConfettiPiece, { style: { ...base, ...visual }, children: p.text }, p.key));
106
+ }) }));
107
+ return createPortal(layer, document.body);
108
+ }
109
+ //# sourceMappingURL=confetti.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confetti.js","sourceRoot":"","sources":["../src/confetti.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Viewport-fixed overlay. Rendered via a portal to <body> so it sits OUTSIDE
3
+ * any `position: fixed` + `overflow: hidden` + `contain: layout` subtree — that
4
+ * nesting is what froze the piece animations mid-fall on iOS (compositing
5
+ * desync inside a fixed/clipped ancestor during scroll/toolbar settle). At the
6
+ * document root the pieces composite against the viewport and animate to
7
+ * completion.
8
+ */
9
+ export declare const ConfettiLayer: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>>> & string;
10
+ export declare const ConfettiPiece: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never> & Partial<Pick<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, never>>> & string;
11
+ //# sourceMappingURL=confetti.styles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confetti.styles.d.ts","sourceRoot":"","sources":["../src/confetti.styles.ts"],"names":[],"mappings":"AA6BA;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,uVAMzB,CAAC;AAEF,eAAO,MAAM,aAAa,2VAkBzB,CAAC"}
@@ -0,0 +1,62 @@
1
+ // Named import (not the default) so styled-components resolves consistently
2
+ // when this file is consumed as a published node_modules ESM module.
3
+ import { styled, keyframes } from 'styled-components';
4
+ /**
5
+ * Falls from just above the top, drifting sideways and rotating, then fades.
6
+ * Per-piece motion comes from CSS custom properties set inline, all in PIXELS
7
+ * (computed once at burst time) — NOT viewport units. iOS Safari recomputes
8
+ * `vh`/`vw` when its address bar collapses, which desynced/stalled the
9
+ * animation mid-fall; fixed pixel targets avoid that entirely.
10
+ * --start starting Y (negative px, above viewport)
11
+ * --dx horizontal drift (px)
12
+ * --dist fall distance (px, comfortably past the bottom edge)
13
+ * --rot rotation (deg)
14
+ */
15
+ const fall = keyframes `
16
+ 0% {
17
+ transform: translate3d(0, var(--start, -120px), 0) rotateZ(0deg);
18
+ opacity: 0;
19
+ }
20
+ 8% {
21
+ opacity: 1;
22
+ }
23
+ 100% {
24
+ transform: translate3d(var(--dx, 0), var(--dist, 900px), 0) rotateZ(var(--rot, 360deg));
25
+ opacity: 0;
26
+ }
27
+ `;
28
+ /**
29
+ * Viewport-fixed overlay. Rendered via a portal to <body> so it sits OUTSIDE
30
+ * any `position: fixed` + `overflow: hidden` + `contain: layout` subtree — that
31
+ * nesting is what froze the piece animations mid-fall on iOS (compositing
32
+ * desync inside a fixed/clipped ancestor during scroll/toolbar settle). At the
33
+ * document root the pieces composite against the viewport and animate to
34
+ * completion.
35
+ */
36
+ export const ConfettiLayer = styled.div `
37
+ position: fixed;
38
+ inset: 0;
39
+ overflow: hidden;
40
+ pointer-events: none;
41
+ z-index: 2147483000;
42
+ `;
43
+ export const ConfettiPiece = styled.span `
44
+ position: absolute;
45
+ top: 0;
46
+ display: block;
47
+ white-space: nowrap;
48
+ user-select: none;
49
+ will-change: transform, opacity;
50
+ animation-name: ${fall};
51
+ animation-timing-function: cubic-bezier(0.25, 0.6, 0.45, 1);
52
+ /* 'both' applies the 0% keyframe during the start delay, so each piece waits
53
+ above the viewport (opacity 0) instead of sitting visibly at the top. */
54
+ animation-fill-mode: both;
55
+ animation-iteration-count: 1;
56
+
57
+ @media (prefers-reduced-motion: reduce) {
58
+ animation: none;
59
+ display: none;
60
+ }
61
+ `;
62
+ //# sourceMappingURL=confetti.styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confetti.styles.js","sourceRoot":"","sources":["../src/confetti.styles.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,qEAAqE;AACrE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,IAAI,GAAG,SAAS,CAAA;;;;;;;;;;;;CAYrB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;CAMtC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAA;;;;;;;mBAOrB,IAAI;;;;;;;;;;;CAWtB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -23,6 +23,10 @@ export { default as ToggleSwitch } from './toggle-switch.js';
23
23
  export type { ToggleSwitchProps } from './toggle-switch.js';
24
24
  export { ConfirmDialog } from './confirm-dialog.js';
25
25
  export type { ConfirmDialogProps } from './confirm-dialog.js';
26
+ export { Confetti } from './confetti.js';
27
+ export type { ConfettiProps } from './confetti.js';
28
+ export { AnimatedHeight } from './animated-height.js';
29
+ export type { AnimatedHeightProps } from './animated-height.js';
26
30
  export { BottomSheet } from './bottom-sheet.js';
27
31
  export type { BottomSheetProps } from './bottom-sheet.js';
28
32
  export { SearchField } from './search-field.js';
@@ -33,6 +37,8 @@ export { buildTheme, theme, hexToRgb } from './theme.js';
33
37
  export type { ThemeType } from './theme.js';
34
38
  export { lightPalette, darkPalette } from './palettes.js';
35
39
  export type { ModeColorPalette } from './palettes.js';
40
+ export { tilePalette, tileColorIndex, tileColorForKey } from './tile-palette.js';
41
+ export type { TileColor } from './tile-palette.js';
36
42
  export type { DynamicLanguage, CharacterPreference, StaticLanguage, } from './language.js';
37
43
  export { ListItem, UnorderedListItemContainer } from './list-item.js';
38
44
  export type { ListItemProps, ListItemIconName, ListItemActionName, } from './list-item.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -12,10 +12,13 @@ export { default as BannerButton } from './banner-button.js';
12
12
  export { Badge } from './badge.js';
13
13
  export { default as ToggleSwitch } from './toggle-switch.js';
14
14
  export { ConfirmDialog } from './confirm-dialog.js';
15
+ export { Confetti } from './confetti.js';
16
+ export { AnimatedHeight } from './animated-height.js';
15
17
  export { BottomSheet } from './bottom-sheet.js';
16
18
  export { SearchField } from './search-field.js';
17
19
  export { SearchBar } from './search-bar.js';
18
20
  export { buildTheme, theme, hexToRgb } from './theme.js';
19
21
  export { lightPalette, darkPalette } from './palettes.js';
22
+ export { tilePalette, tileColorIndex, tileColorForKey } from './tile-palette.js';
20
23
  export { ListItem, UnorderedListItemContainer } from './list-item.js';
21
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAS1D,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAG1D,OAAO,EACN,oBAAoB,EACpB,eAAe,EACf,cAAc,GACd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjE,OAAO,EACN,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,cAAc,EACd,aAAa,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG7D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AASjF,OAAO,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Word-tile palette — the airy pastel fills used behind tappable word tiles,
3
+ * flashcards, browse-grid cells and celebratory confetti.
4
+ *
5
+ * These eight pastels are **mode-independent**: they read on both light and
6
+ * dark surfaces and always pair with near-black text, so they live here as a
7
+ * standalone constant rather than inside `ModeColorPalette` (which is per-mode).
8
+ *
9
+ * This is the single source of truth. It was previously copy-pasted across six
10
+ * xunzi surfaces; consumers should import `tilePalette` / `tileColorForKey`
11
+ * instead of redeclaring the hex values or the hashing logic. An app that needs
12
+ * a different look should compose an explicit override, not fork the palette.
13
+ */
14
+ /** A tile fill paired with the text color that stays legible on it. */
15
+ export interface TileColor {
16
+ bg: string;
17
+ text: string;
18
+ }
19
+ /** The eight airy pastels, in stable order (index is part of the contract). */
20
+ export declare const tilePalette: readonly TileColor[];
21
+ /**
22
+ * Deterministic index into {@link tilePalette} for an arbitrary key — the same
23
+ * key always maps to the same color, so a given word keeps its tile color
24
+ * everywhere it appears. Preserves the historical
25
+ * `(hash + charCodeAt) * 31` algorithm the xunzi copies used.
26
+ */
27
+ export declare function tileColorIndex(key: string): number;
28
+ /** Deterministic tile color for a key (see {@link tileColorIndex}). */
29
+ export declare function tileColorForKey(key: string): TileColor;
30
+ //# sourceMappingURL=tile-palette.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-palette.d.ts","sourceRoot":"","sources":["../src/tile-palette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uEAAuE;AACvE,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACb;AAED,+EAA+E;AAC/E,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAS3C,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAEtD"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Word-tile palette — the airy pastel fills used behind tappable word tiles,
3
+ * flashcards, browse-grid cells and celebratory confetti.
4
+ *
5
+ * These eight pastels are **mode-independent**: they read on both light and
6
+ * dark surfaces and always pair with near-black text, so they live here as a
7
+ * standalone constant rather than inside `ModeColorPalette` (which is per-mode).
8
+ *
9
+ * This is the single source of truth. It was previously copy-pasted across six
10
+ * xunzi surfaces; consumers should import `tilePalette` / `tileColorForKey`
11
+ * instead of redeclaring the hex values or the hashing logic. An app that needs
12
+ * a different look should compose an explicit override, not fork the palette.
13
+ */
14
+ /** The eight airy pastels, in stable order (index is part of the contract). */
15
+ export const tilePalette = [
16
+ { bg: '#90CAF9', text: '#1A1A1A' }, // Soft blue
17
+ { bg: '#A5D6A7', text: '#1A1A1A' }, // Mint
18
+ { bg: '#CE93D8', text: '#1A1A1A' }, // Lavender
19
+ { bg: '#FFAB91', text: '#1A1A1A' }, // Peach
20
+ { bg: '#80DEEA', text: '#1A1A1A' }, // Light teal
21
+ { bg: '#FFF59D', text: '#1A1A1A' }, // Butter
22
+ { bg: '#B39DDB', text: '#1A1A1A' }, // Wisteria
23
+ { bg: '#81D4FA', text: '#1A1A1A' }, // Sky
24
+ ];
25
+ /**
26
+ * Deterministic index into {@link tilePalette} for an arbitrary key — the same
27
+ * key always maps to the same color, so a given word keeps its tile color
28
+ * everywhere it appears. Preserves the historical
29
+ * `(hash + charCodeAt) * 31` algorithm the xunzi copies used.
30
+ */
31
+ export function tileColorIndex(key) {
32
+ let hash = 0;
33
+ for (let i = 0; i < key.length; i++) {
34
+ hash = (hash + key.charCodeAt(i)) * 31;
35
+ }
36
+ return Math.abs(hash) % tilePalette.length;
37
+ }
38
+ /** Deterministic tile color for a key (see {@link tileColorIndex}). */
39
+ export function tileColorForKey(key) {
40
+ return tilePalette[tileColorIndex(key)];
41
+ }
42
+ //# sourceMappingURL=tile-palette.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tile-palette.js","sourceRoot":"","sources":["../src/tile-palette.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAyB;IAChD,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,YAAY;IAChD,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,OAAO;IAC3C,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,WAAW;IAC/C,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,QAAQ;IAC5C,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,aAAa;IACjD,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS;IAC7C,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,WAAW;IAC/C,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM;CAC1C,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACzC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;IACxC,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC;AAC5C,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,GAAW;IAC1C,OAAO,WAAW,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;AACzC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kang-components",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "description": "Generic, domain-free React UI primitives (CSS-first press feedback, delayed-action hook, spring presets, cross-fading text, circle icon button).",
5
5
  "type": "module",
6
6
  "license": "MIT",