@better-i18n/core 0.4.0 → 0.6.0
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/cdn.d.ts.map +1 -1
- package/dist/cdn.js +8 -2
- package/dist/cdn.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +18 -2
- package/dist/config.js.map +1 -1
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/locale-dropdown-base.d.ts +161 -0
- package/dist/react/locale-dropdown-base.d.ts.map +1 -0
- package/dist/react/locale-dropdown-base.js +432 -0
- package/dist/react/locale-dropdown-base.js.map +1 -0
- package/dist/utils/locale.d.ts +11 -1
- package/dist/utils/locale.d.ts.map +1 -1
- package/dist/utils/locale.js +16 -0
- package/dist/utils/locale.js.map +1 -1
- package/package.json +19 -1
package/dist/cdn.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAMf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAMf,MAAM,YAAY,CAAC;AAsVpB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,cAAc,KAAG,QAmCvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAO,IAErC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAO,IAErC,CAAC"}
|
package/dist/cdn.js
CHANGED
|
@@ -95,7 +95,10 @@ const fetchManifestFromCdn = async (config, fetchFn) => {
|
|
|
95
95
|
const logger = createLogger(config, "manifest");
|
|
96
96
|
const url = `${getProjectBaseUrl(config)}/manifest.json`;
|
|
97
97
|
logger.debug("fetching", url);
|
|
98
|
-
const response = await fetchWithRetry(fetchFn, url,
|
|
98
|
+
const response = await fetchWithRetry(fetchFn, url,
|
|
99
|
+
// cache: "no-store" bypasses browser disk cache (fetch API option).
|
|
100
|
+
// The header alone is not enough — browser ignores it for disk cache reads.
|
|
101
|
+
{ headers: { "Cache-Control": "no-store" }, cache: "no-store" }, config.fetchTimeout, config.retryCount);
|
|
99
102
|
if (!response.ok) {
|
|
100
103
|
const message = `Manifest fetch failed (${response.status})`;
|
|
101
104
|
logger.error(message);
|
|
@@ -158,7 +161,10 @@ const fetchMessagesFromCdn = async (config, locale, fetchFn, ifNoneMatch) => {
|
|
|
158
161
|
if (ifNoneMatch) {
|
|
159
162
|
headers["If-None-Match"] = ifNoneMatch;
|
|
160
163
|
}
|
|
161
|
-
const response = await fetchWithRetry(fetchFn, url,
|
|
164
|
+
const response = await fetchWithRetry(fetchFn, url,
|
|
165
|
+
// cache: "no-store" bypasses browser disk cache (fetch API option).
|
|
166
|
+
// The header alone is not enough — browser ignores it for disk cache reads.
|
|
167
|
+
{ headers, cache: "no-store" }, config.fetchTimeout, config.retryCount);
|
|
162
168
|
// 304 Not Modified — cached content is still fresh
|
|
163
169
|
if (response.status === 304) {
|
|
164
170
|
logger.debug("304 Not Modified", { locale });
|
package/dist/cdn.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cdn.js","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"cdn.js","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAuBlF;;GAEG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,aAW9C,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,cAAc,KAAG,gBAuBxD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,gBAAgB,KAAG,MACO,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
const DEFAULT_CDN_BASE_URL = "https://cdn.better-i18n.com";
|
|
2
|
-
const
|
|
2
|
+
const DEFAULT_CACHE_TTL_MS_PROD = 5 * 60 * 1000; // 5 minutes
|
|
3
|
+
const DEFAULT_CACHE_TTL_MS_DEV = 0; // no cache in dev — always fetch fresh
|
|
3
4
|
const DEFAULT_FETCH_TIMEOUT_MS = 10_000; // 10 seconds
|
|
4
5
|
const DEFAULT_RETRY_COUNT = 1;
|
|
6
|
+
/**
|
|
7
|
+
* Detect development mode from NODE_ENV.
|
|
8
|
+
* Safe to call in CF Workers (process may not exist).
|
|
9
|
+
*/
|
|
10
|
+
const isDevMode = () => {
|
|
11
|
+
try {
|
|
12
|
+
return (typeof process !== "undefined" &&
|
|
13
|
+
process.env?.NODE_ENV === "development");
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
5
19
|
/**
|
|
6
20
|
* Parse project string "org/slug" into workspaceId and projectSlug
|
|
7
21
|
*/
|
|
@@ -26,12 +40,14 @@ export const normalizeConfig = (config) => {
|
|
|
26
40
|
throw new Error("[better-i18n] defaultLocale is required");
|
|
27
41
|
}
|
|
28
42
|
const { workspaceId, projectSlug } = parseProject(config.project);
|
|
43
|
+
const devMode = isDevMode();
|
|
29
44
|
return {
|
|
30
45
|
...config,
|
|
31
46
|
workspaceId,
|
|
32
47
|
projectSlug,
|
|
33
48
|
cdnBaseUrl: config.cdnBaseUrl?.replace(/\/$/, "") || DEFAULT_CDN_BASE_URL,
|
|
34
|
-
manifestCacheTtlMs: config.manifestCacheTtlMs ??
|
|
49
|
+
manifestCacheTtlMs: config.manifestCacheTtlMs ??
|
|
50
|
+
(devMode ? DEFAULT_CACHE_TTL_MS_DEV : DEFAULT_CACHE_TTL_MS_PROD),
|
|
35
51
|
fetchTimeout: config.fetchTimeout ?? DEFAULT_FETCH_TIMEOUT_MS,
|
|
36
52
|
retryCount: config.retryCount ?? DEFAULT_RETRY_COUNT,
|
|
37
53
|
};
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAC3D,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAC3D,MAAM,yBAAyB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAC7D,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,uCAAuC;AAC3E,MAAM,wBAAwB,GAAG,MAAM,CAAC,CAAC,aAAa;AACtD,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAE9B;;;GAGG;AACH,MAAM,SAAS,GAAG,GAAY,EAAE;IAC9B,IAAI,CAAC;QACH,OAAO,CACL,OAAO,OAAO,KAAK,WAAW;YAC9B,OAAO,CAAC,GAAG,EAAE,QAAQ,KAAK,aAAa,CACxC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAe,EAAiB,EAAE;IAC7D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,MAAM,IAAI,KAAK,CACb,yCAAyC,OAAO,oDAAoD,CACrG,CAAC;IACJ,CAAC;IACD,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;QACrB,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;KACtB,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAsB,EAAoB,EAAE;IAC1E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAE5B,OAAO;QACL,GAAG,MAAM;QACT,WAAW;QACX,WAAW;QACX,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,oBAAoB;QACzE,kBAAkB,EAChB,MAAM,CAAC,kBAAkB;YACzB,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,yBAAyB,CAAC;QAClE,YAAY,EAAE,MAAM,CAAC,YAAY,IAAI,wBAAwB;QAC7D,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,mBAAmB;KACrD,CAAC;AACJ,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAwB,EAAU,EAAE,CACpE,GAAG,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,QAAQ,EACR,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,GAClC,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,QAAQ,GAIT,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { LanguageOption } from "../types.js";
|
|
3
|
+
import { type ResolvedFlag } from "../utils/locale-ui.js";
|
|
4
|
+
/**
|
|
5
|
+
* Internal CSS custom properties (`--_bl-*`) provide dark-mode-aware
|
|
6
|
+
* defaults. Consumer-set `--better-locale-*` properties always win.
|
|
7
|
+
*
|
|
8
|
+
* Supports: `.dark` class (Tailwind), `[data-theme="dark"]` attribute.
|
|
9
|
+
* Does NOT use `prefers-color-scheme` — dark mode must be explicit via
|
|
10
|
+
* site markup, so light-only sites aren't affected by OS dark mode.
|
|
11
|
+
*
|
|
12
|
+
* Menu uses `data-state` attribute for animation:
|
|
13
|
+
* - no attribute → hidden (visibility:hidden, pointer-events:none)
|
|
14
|
+
* - `data-state="open"` → entrance animation
|
|
15
|
+
* - `data-state="closing"` → exit animation
|
|
16
|
+
*/
|
|
17
|
+
export declare const LOCALE_DROPDOWN_CSS: string;
|
|
18
|
+
/**
|
|
19
|
+
* Data attribute names used by `LocaleDropdownBase`.
|
|
20
|
+
*
|
|
21
|
+
* Use these when building custom styled components on top of `variant="unstyled"`,
|
|
22
|
+
* or when writing CSS selectors targeting the dropdown's DOM structure.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```css
|
|
26
|
+
* [data-better-locale-trigger] { ... }
|
|
27
|
+
* [data-better-locale-item][data-active] { font-weight: 600; }
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <LocaleDropdownBase variant="unstyled" />
|
|
33
|
+
* // then target with DATA_ATTRS.trigger, DATA_ATTRS.item, etc.
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const DATA_ATTRS: {
|
|
37
|
+
/** Root wrapper element. */
|
|
38
|
+
readonly root: "data-better-locale-dropdown";
|
|
39
|
+
/** Trigger button (or custom trigger wrapper). */
|
|
40
|
+
readonly trigger: "data-better-locale-trigger";
|
|
41
|
+
/** Floating menu list. */
|
|
42
|
+
readonly menu: "data-better-locale-menu";
|
|
43
|
+
/** Each language option `<li>`. */
|
|
44
|
+
readonly item: "data-better-locale-item";
|
|
45
|
+
/** Present on the active (selected) item. */
|
|
46
|
+
readonly active: "data-active";
|
|
47
|
+
/** Present on the keyboard-focused item. */
|
|
48
|
+
readonly focused: "data-focused";
|
|
49
|
+
/** `"top"` or `"bottom"` — resolved placement direction on the menu. */
|
|
50
|
+
readonly placement: "data-placement";
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* CSS custom property names consumed by `LocaleDropdownBase` in styled mode.
|
|
54
|
+
*
|
|
55
|
+
* Set these on any ancestor element to theme the dropdown without touching its markup.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```tsx
|
|
59
|
+
* <div style={{ [CSS_VARS.hoverBg]: "oklch(0.95 0 0)", [CSS_VARS.accent]: "#7c3aed" }}>
|
|
60
|
+
* <LocaleDropdown />
|
|
61
|
+
* </div>
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare const CSS_VARS: {
|
|
65
|
+
/** Text color for trigger and menu items. */
|
|
66
|
+
readonly text: "--better-locale-text";
|
|
67
|
+
/** Menu panel background. */
|
|
68
|
+
readonly menuBg: "--better-locale-menu-bg";
|
|
69
|
+
/** Menu panel border color. */
|
|
70
|
+
readonly border: "--better-locale-border";
|
|
71
|
+
/** Item hover background. */
|
|
72
|
+
readonly hoverBg: "--better-locale-hover-bg";
|
|
73
|
+
/** Active (selected) item background. */
|
|
74
|
+
readonly activeBg: "--better-locale-active-bg";
|
|
75
|
+
/** Muted text color (locale code badge, chevron). */
|
|
76
|
+
readonly codeText: "--better-locale-code-text";
|
|
77
|
+
/** Checkmark / accent color. */
|
|
78
|
+
readonly accent: "--better-locale-accent";
|
|
79
|
+
/** Trigger button padding. */
|
|
80
|
+
readonly triggerPadding: "--better-locale-trigger-padding";
|
|
81
|
+
/** Trigger button border-radius. */
|
|
82
|
+
readonly triggerRadius: "--better-locale-trigger-radius";
|
|
83
|
+
/** Trigger button border. */
|
|
84
|
+
readonly triggerBorder: "--better-locale-trigger-border";
|
|
85
|
+
/** Trigger button background. */
|
|
86
|
+
readonly triggerBg: "--better-locale-trigger-bg";
|
|
87
|
+
};
|
|
88
|
+
export interface LocaleDropdownTriggerContext {
|
|
89
|
+
language: LanguageOption | undefined;
|
|
90
|
+
isOpen: boolean;
|
|
91
|
+
isLoading: boolean;
|
|
92
|
+
flag: ResolvedFlag | null;
|
|
93
|
+
label: string;
|
|
94
|
+
}
|
|
95
|
+
export interface LocaleDropdownRenderContext {
|
|
96
|
+
language: LanguageOption;
|
|
97
|
+
isActive: boolean;
|
|
98
|
+
flag: ResolvedFlag;
|
|
99
|
+
label: string;
|
|
100
|
+
}
|
|
101
|
+
export interface LocaleDropdownBaseProps {
|
|
102
|
+
/** Current active locale code. */
|
|
103
|
+
locale: string;
|
|
104
|
+
/** Available languages list. */
|
|
105
|
+
languages: LanguageOption[];
|
|
106
|
+
/** Called when user selects a new locale. */
|
|
107
|
+
onLocaleChange: (locale: string) => void;
|
|
108
|
+
/** Show loading skeleton. @default false */
|
|
109
|
+
isLoading?: boolean;
|
|
110
|
+
/** Display variant. "styled" = inline styles + CSS vars, "unstyled" = data attributes only. @default "styled" */
|
|
111
|
+
variant?: "styled" | "unstyled";
|
|
112
|
+
/** Additional className on the root wrapper. */
|
|
113
|
+
className?: string;
|
|
114
|
+
/** Additional className on the trigger button. */
|
|
115
|
+
triggerClassName?: string;
|
|
116
|
+
/** Additional className on the dropdown menu. */
|
|
117
|
+
menuClassName?: string;
|
|
118
|
+
/** Show flag icon/emoji. @default true */
|
|
119
|
+
showFlag?: boolean;
|
|
120
|
+
/** Show native language name. @default true */
|
|
121
|
+
showNativeName?: boolean;
|
|
122
|
+
/** Show locale code badge (e.g., "EN"). @default true */
|
|
123
|
+
showLocaleCode?: boolean;
|
|
124
|
+
/** Menu placement. "auto" detects available viewport space. @default "auto" */
|
|
125
|
+
placement?: "auto" | "top" | "bottom";
|
|
126
|
+
/** Custom render for the trigger button. */
|
|
127
|
+
renderTrigger?: (ctx: LocaleDropdownTriggerContext) => ReactNode;
|
|
128
|
+
/** Custom render for each menu item. */
|
|
129
|
+
renderItem?: (ctx: LocaleDropdownRenderContext) => ReactNode;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Headless-friendly locale dropdown UI.
|
|
133
|
+
*
|
|
134
|
+
* Pure presentational component — no routing hooks, no framework assumptions.
|
|
135
|
+
* Pass `locale`, `languages`, and `onLocaleChange` from your adapter.
|
|
136
|
+
*
|
|
137
|
+
* The menu element is **always in the DOM** so floating-ui can pre-calculate
|
|
138
|
+
* position. Visibility is controlled via CSS `data-state` attribute — this
|
|
139
|
+
* eliminates the positioning flash that occurs with conditional rendering.
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```tsx
|
|
143
|
+
* // Minimal usage
|
|
144
|
+
* <LocaleDropdownBase
|
|
145
|
+
* locale={locale}
|
|
146
|
+
* languages={languages}
|
|
147
|
+
* onLocaleChange={navigate}
|
|
148
|
+
* />
|
|
149
|
+
*
|
|
150
|
+
* // Headless — bring your own styles
|
|
151
|
+
* <LocaleDropdownBase
|
|
152
|
+
* locale={locale}
|
|
153
|
+
* languages={languages}
|
|
154
|
+
* onLocaleChange={navigate}
|
|
155
|
+
* variant="unstyled"
|
|
156
|
+
* renderItem={({ language, isActive }) => <MyItem ... />}
|
|
157
|
+
* />
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
export declare function LocaleDropdownBase({ locale, languages, onLocaleChange, isLoading, variant, className, triggerClassName, menuClassName, showFlag, showNativeName, showLocaleCode, placement: placementProp, renderTrigger, renderItem, }: LocaleDropdownBaseProps): import("react/jsx-runtime").JSX.Element;
|
|
161
|
+
//# sourceMappingURL=locale-dropdown-base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-dropdown-base.d.ts","sourceRoot":"","sources":["../../src/react/locale-dropdown-base.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAQf,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAiC,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAwGzF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,mBAAmB,QAuDtB,CAAC;AAgGX;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,UAAU;IACrB,4BAA4B;;IAE5B,kDAAkD;;IAElD,0BAA0B;;IAE1B,mCAAmC;;IAEnC,6CAA6C;;IAE7C,4CAA4C;;IAE5C,wEAAwE;;CAEhE,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,QAAQ;IACnB,6CAA6C;;IAE7C,6BAA6B;;IAE7B,+BAA+B;;IAE/B,6BAA6B;;IAE7B,yCAAyC;;IAEzC,qDAAqD;;IAErD,gCAAgC;;IAEhC,8BAA8B;;IAE9B,oCAAoC;;IAEpC,6BAA6B;;IAE7B,iCAAiC;;CAEzB,CAAC;AAIX,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,YAAY,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,6CAA6C;IAC7C,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,4CAA4C;IAC5C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,iHAAiH;IACjH,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAChC,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iDAAiD;IACjD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IACtC,4CAA4C;IAC5C,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,4BAA4B,KAAK,SAAS,CAAC;IACjE,wCAAwC;IACxC,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,2BAA2B,KAAK,SAAS,CAAC;CAC9D;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,SAAS,EACT,cAAc,EACd,SAAiB,EACjB,OAAkB,EAClB,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,QAAe,EACf,cAAqB,EACrB,cAAqB,EACrB,SAAS,EAAE,aAAsB,EACjC,aAAa,EACb,UAAU,GACX,EAAE,uBAAuB,2CAuRzB"}
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from "react";
|
|
4
|
+
import { useFloating, offset, flip, shift, autoUpdate, } from "@floating-ui/react";
|
|
5
|
+
import { getLanguageLabel, resolveFlag } from "../utils/locale-ui.js";
|
|
6
|
+
// ─── Inline SVG Icons ────────────────────────────────────────────────
|
|
7
|
+
function GlobeIcon() {
|
|
8
|
+
return (_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "square", "aria-hidden": "true", children: [_jsx("path", { d: "M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" }), _jsx("path", { d: "M21 12H3" }), _jsx("path", { d: "M12 21C10.067 21 8.5 16.9706 8.5 12C8.5 7.02944 10.067 3 12 3C13.933 3 15.5 7.02944 15.5 12C15.5 16.9706 13.933 21 12 21Z" })] }));
|
|
9
|
+
}
|
|
10
|
+
function ChevronDownIcon({ style }) {
|
|
11
|
+
return (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", style: style, children: _jsx("path", { d: "M20 9L13.4142 15.5858C12.6332 16.3668 11.3669 16.3668 10.5858 15.5858L4 9" }) }));
|
|
12
|
+
}
|
|
13
|
+
function CheckIcon() {
|
|
14
|
+
return (_jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: _jsx("path", { d: "M6 12l4.243 4.243L18.485 8" }) }));
|
|
15
|
+
}
|
|
16
|
+
// ─── Flag Component ──────────────────────────────────────────────────
|
|
17
|
+
function FlagDisplay({ flag, label }) {
|
|
18
|
+
const [hasError, setHasError] = useState(false);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
setHasError(false);
|
|
21
|
+
}, [flag.type === "url" ? flag.url : null]);
|
|
22
|
+
if (flag.type === "url" && !hasError) {
|
|
23
|
+
return (_jsx("img", { src: flag.url, alt: label, style: { width: 18, height: 18, borderRadius: "50%", objectFit: "cover", flexShrink: 0 }, loading: "lazy", onError: () => setHasError(true) }));
|
|
24
|
+
}
|
|
25
|
+
if (flag.type === "emoji" || (flag.type === "url" && hasError)) {
|
|
26
|
+
const emoji = flag.type === "emoji" ? flag.emoji : null;
|
|
27
|
+
if (emoji) {
|
|
28
|
+
return (_jsx("span", { style: { display: "inline-flex", alignItems: "center", justifyContent: "center", width: 18, height: 18, fontSize: 14, lineHeight: 1, flexShrink: 0 }, "aria-hidden": "true", children: emoji }));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return (_jsx("span", { style: { color: "var(--better-locale-code-text, var(--_bl-muted))" }, children: _jsx(GlobeIcon, {}) }));
|
|
32
|
+
}
|
|
33
|
+
// ─── Theme CSS ──────────────────────────────────────────────────────
|
|
34
|
+
/**
|
|
35
|
+
* Internal CSS custom properties (`--_bl-*`) provide dark-mode-aware
|
|
36
|
+
* defaults. Consumer-set `--better-locale-*` properties always win.
|
|
37
|
+
*
|
|
38
|
+
* Supports: `.dark` class (Tailwind), `[data-theme="dark"]` attribute.
|
|
39
|
+
* Does NOT use `prefers-color-scheme` — dark mode must be explicit via
|
|
40
|
+
* site markup, so light-only sites aren't affected by OS dark mode.
|
|
41
|
+
*
|
|
42
|
+
* Menu uses `data-state` attribute for animation:
|
|
43
|
+
* - no attribute → hidden (visibility:hidden, pointer-events:none)
|
|
44
|
+
* - `data-state="open"` → entrance animation
|
|
45
|
+
* - `data-state="closing"` → exit animation
|
|
46
|
+
*/
|
|
47
|
+
export const LOCALE_DROPDOWN_CSS = [
|
|
48
|
+
/* Base tokens */
|
|
49
|
+
`[data-better-locale-dropdown]{position:relative;--_bl-text:#374151;--_bl-menu-bg:#fff;--_bl-border:#e5e7eb;--_bl-hover:#f3f4f6;--_bl-active:#eff0f1;--_bl-muted:#9ca3af;--_bl-shadow:0 8px 32px rgba(0,0,0,.12),0 2px 8px rgba(0,0,0,.06)}`,
|
|
50
|
+
`.dark [data-better-locale-dropdown],[data-theme=dark] [data-better-locale-dropdown]{--_bl-text:#d1d5db;--_bl-menu-bg:#1a1a1a;--_bl-border:rgba(255,255,255,.08);--_bl-hover:rgba(255,255,255,.06);--_bl-active:rgba(255,255,255,.09);--_bl-muted:#6b7280;--_bl-shadow:0 8px 32px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3)}`,
|
|
51
|
+
/* Keyframes */
|
|
52
|
+
`@keyframes better-locale-pulse{0%,100%{opacity:1}50%{opacity:.4}}`,
|
|
53
|
+
`@keyframes bl-in{from{opacity:0;transform:translateY(-8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}`,
|
|
54
|
+
`@keyframes bl-out{from{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(-6px) scale(.97)}}`,
|
|
55
|
+
`@keyframes bl-in-top{from{opacity:0;transform:translateY(8px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}`,
|
|
56
|
+
`@keyframes bl-out-top{from{opacity:1;transform:translateY(0) scale(1)}to{opacity:0;transform:translateY(6px) scale(.97)}}`,
|
|
57
|
+
`@keyframes bl-item-in{from{opacity:0}to{opacity:1}}`,
|
|
58
|
+
/* Menu — always in DOM, hidden by default */
|
|
59
|
+
`[data-better-locale-menu]{visibility:hidden;pointer-events:none;opacity:0}`,
|
|
60
|
+
/* Menu — open state */
|
|
61
|
+
`[data-better-locale-menu][data-state=open]{visibility:visible;pointer-events:auto;opacity:1;animation:bl-in .26s cubic-bezier(.16,1,.3,1) both;transform-origin:top center}`,
|
|
62
|
+
`[data-better-locale-menu][data-state=open][data-placement=top]{animation-name:bl-in-top;transform-origin:bottom center}`,
|
|
63
|
+
/* Menu — closing state */
|
|
64
|
+
`[data-better-locale-menu][data-state=closing]{visibility:visible;pointer-events:none;animation:bl-out .14s ease-in forwards}`,
|
|
65
|
+
`[data-better-locale-menu][data-state=closing][data-placement=top]{animation-name:bl-out-top}`,
|
|
66
|
+
/* Scrollbar */
|
|
67
|
+
`[data-better-locale-menu]::-webkit-scrollbar{width:4px}`,
|
|
68
|
+
`[data-better-locale-menu]::-webkit-scrollbar-track{background:transparent}`,
|
|
69
|
+
`[data-better-locale-menu]::-webkit-scrollbar-thumb{background:var(--better-locale-border,var(--_bl-border));border-radius:2px}`,
|
|
70
|
+
/* Item — staggered entrance (only in open state) */
|
|
71
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]{animation:bl-item-in .12s ease-out both}`,
|
|
72
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(1){animation-delay:0ms}`,
|
|
73
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(2){animation-delay:12ms}`,
|
|
74
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(3){animation-delay:24ms}`,
|
|
75
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(4){animation-delay:36ms}`,
|
|
76
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(5){animation-delay:48ms}`,
|
|
77
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(6){animation-delay:58ms}`,
|
|
78
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(7){animation-delay:66ms}`,
|
|
79
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(8){animation-delay:72ms}`,
|
|
80
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(9){animation-delay:76ms}`,
|
|
81
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(10){animation-delay:78ms}`,
|
|
82
|
+
`[data-better-locale-menu][data-state=open] [data-better-locale-item]:nth-child(n+11){animation-delay:80ms}`,
|
|
83
|
+
/* Item — hover / focus pseudo-element */
|
|
84
|
+
`[data-better-locale-item]{position:relative}`,
|
|
85
|
+
`[data-better-locale-item]>*{position:relative;z-index:1}`,
|
|
86
|
+
`[data-better-locale-item]::before{content:'';position:absolute;inset:0;border-radius:8px;background:var(--better-locale-hover-bg,var(--_bl-hover));opacity:0;transform:scale(.97);transition:opacity .12s ease-out,transform .12s ease-out;z-index:0}`,
|
|
87
|
+
`[data-better-locale-item]:hover::before,[data-better-locale-item][data-focused]::before{opacity:1;transform:scale(1)}`,
|
|
88
|
+
`[data-better-locale-item][data-active]::before{opacity:1;transform:scale(1);background:var(--better-locale-active-bg,var(--_bl-active))}`,
|
|
89
|
+
/* Trigger hover pseudo-element */
|
|
90
|
+
`[data-better-locale-trigger]{position:relative}`,
|
|
91
|
+
`[data-better-locale-trigger]:not([disabled])::before{content:'';position:absolute;inset:0;border-radius:var(--better-locale-trigger-radius,8px);background:var(--better-locale-hover-bg,var(--_bl-hover));opacity:0;transform:scale(.97);transition:opacity .12s ease-out,transform .12s ease-out}`,
|
|
92
|
+
`[data-better-locale-trigger]:not([disabled]):hover::before{opacity:1;transform:scale(1)}`,
|
|
93
|
+
`[data-better-locale-trigger]>*{position:relative;z-index:1}`,
|
|
94
|
+
].join("");
|
|
95
|
+
// ─── Styles ──────────────────────────────────────────────────────────
|
|
96
|
+
const styles = {
|
|
97
|
+
trigger: {
|
|
98
|
+
display: "inline-flex",
|
|
99
|
+
alignItems: "center",
|
|
100
|
+
gap: 8,
|
|
101
|
+
padding: "var(--better-locale-trigger-padding, 6px 10px)",
|
|
102
|
+
borderRadius: "var(--better-locale-trigger-radius, 8px)",
|
|
103
|
+
border: "var(--better-locale-trigger-border, 1px solid transparent)",
|
|
104
|
+
background: "var(--better-locale-trigger-bg, transparent)",
|
|
105
|
+
color: "var(--better-locale-text, var(--_bl-text))",
|
|
106
|
+
fontSize: 14,
|
|
107
|
+
fontWeight: 500,
|
|
108
|
+
cursor: "pointer",
|
|
109
|
+
lineHeight: 1,
|
|
110
|
+
fontFamily: "inherit",
|
|
111
|
+
},
|
|
112
|
+
triggerDisabled: {
|
|
113
|
+
opacity: 0.7,
|
|
114
|
+
cursor: "default",
|
|
115
|
+
},
|
|
116
|
+
menu: {
|
|
117
|
+
minWidth: 210,
|
|
118
|
+
maxHeight: "min(420px, 70vh)",
|
|
119
|
+
overflowY: "auto",
|
|
120
|
+
borderRadius: 14,
|
|
121
|
+
border: "1px solid var(--better-locale-border, var(--_bl-border))",
|
|
122
|
+
background: "var(--better-locale-menu-bg, var(--_bl-menu-bg))",
|
|
123
|
+
boxShadow: "var(--_bl-shadow)",
|
|
124
|
+
padding: "6px",
|
|
125
|
+
display: "flex",
|
|
126
|
+
flexDirection: "column",
|
|
127
|
+
gap: 2,
|
|
128
|
+
zIndex: 50,
|
|
129
|
+
listStyle: "none",
|
|
130
|
+
margin: 0,
|
|
131
|
+
},
|
|
132
|
+
item: {
|
|
133
|
+
display: "flex",
|
|
134
|
+
alignItems: "center",
|
|
135
|
+
gap: 10,
|
|
136
|
+
width: "100%",
|
|
137
|
+
padding: "8px 10px",
|
|
138
|
+
border: "none",
|
|
139
|
+
background: "transparent",
|
|
140
|
+
color: "var(--better-locale-text, var(--_bl-text))",
|
|
141
|
+
fontSize: 14,
|
|
142
|
+
cursor: "pointer",
|
|
143
|
+
textAlign: "left",
|
|
144
|
+
fontFamily: "inherit",
|
|
145
|
+
lineHeight: 1.2,
|
|
146
|
+
borderRadius: 8,
|
|
147
|
+
boxSizing: "border-box",
|
|
148
|
+
},
|
|
149
|
+
itemActive: { fontWeight: 500 },
|
|
150
|
+
itemHovered: {},
|
|
151
|
+
label: { flex: 1, textAlign: "left" },
|
|
152
|
+
code: {
|
|
153
|
+
fontSize: 10,
|
|
154
|
+
fontFamily: "monospace",
|
|
155
|
+
textTransform: "uppercase",
|
|
156
|
+
color: "var(--better-locale-code-text, var(--_bl-muted))",
|
|
157
|
+
letterSpacing: "0.05em",
|
|
158
|
+
},
|
|
159
|
+
check: { color: "var(--better-locale-accent, currentColor)", flexShrink: 0 },
|
|
160
|
+
skeleton: {
|
|
161
|
+
display: "inline-flex",
|
|
162
|
+
alignItems: "center",
|
|
163
|
+
gap: 8,
|
|
164
|
+
padding: "6px 10px",
|
|
165
|
+
borderRadius: 8,
|
|
166
|
+
border: "1px solid transparent",
|
|
167
|
+
background: "transparent",
|
|
168
|
+
},
|
|
169
|
+
skeletonFlag: {
|
|
170
|
+
width: 18,
|
|
171
|
+
height: 18,
|
|
172
|
+
borderRadius: "50%",
|
|
173
|
+
background: "var(--better-locale-border, var(--_bl-border))",
|
|
174
|
+
animation: "better-locale-pulse 1.5s ease-in-out infinite",
|
|
175
|
+
flexShrink: 0,
|
|
176
|
+
},
|
|
177
|
+
skeletonText: {
|
|
178
|
+
width: 56,
|
|
179
|
+
height: 14,
|
|
180
|
+
borderRadius: 4,
|
|
181
|
+
background: "var(--better-locale-border, var(--_bl-border))",
|
|
182
|
+
animation: "better-locale-pulse 1.5s ease-in-out infinite",
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
// ─── Public API Constants ────────────────────────────────────────────
|
|
186
|
+
/**
|
|
187
|
+
* Data attribute names used by `LocaleDropdownBase`.
|
|
188
|
+
*
|
|
189
|
+
* Use these when building custom styled components on top of `variant="unstyled"`,
|
|
190
|
+
* or when writing CSS selectors targeting the dropdown's DOM structure.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```css
|
|
194
|
+
* [data-better-locale-trigger] { ... }
|
|
195
|
+
* [data-better-locale-item][data-active] { font-weight: 600; }
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* @example
|
|
199
|
+
* ```tsx
|
|
200
|
+
* <LocaleDropdownBase variant="unstyled" />
|
|
201
|
+
* // then target with DATA_ATTRS.trigger, DATA_ATTRS.item, etc.
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export const DATA_ATTRS = {
|
|
205
|
+
/** Root wrapper element. */
|
|
206
|
+
root: "data-better-locale-dropdown",
|
|
207
|
+
/** Trigger button (or custom trigger wrapper). */
|
|
208
|
+
trigger: "data-better-locale-trigger",
|
|
209
|
+
/** Floating menu list. */
|
|
210
|
+
menu: "data-better-locale-menu",
|
|
211
|
+
/** Each language option `<li>`. */
|
|
212
|
+
item: "data-better-locale-item",
|
|
213
|
+
/** Present on the active (selected) item. */
|
|
214
|
+
active: "data-active",
|
|
215
|
+
/** Present on the keyboard-focused item. */
|
|
216
|
+
focused: "data-focused",
|
|
217
|
+
/** `"top"` or `"bottom"` — resolved placement direction on the menu. */
|
|
218
|
+
placement: "data-placement",
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* CSS custom property names consumed by `LocaleDropdownBase` in styled mode.
|
|
222
|
+
*
|
|
223
|
+
* Set these on any ancestor element to theme the dropdown without touching its markup.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```tsx
|
|
227
|
+
* <div style={{ [CSS_VARS.hoverBg]: "oklch(0.95 0 0)", [CSS_VARS.accent]: "#7c3aed" }}>
|
|
228
|
+
* <LocaleDropdown />
|
|
229
|
+
* </div>
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export const CSS_VARS = {
|
|
233
|
+
/** Text color for trigger and menu items. */
|
|
234
|
+
text: "--better-locale-text",
|
|
235
|
+
/** Menu panel background. */
|
|
236
|
+
menuBg: "--better-locale-menu-bg",
|
|
237
|
+
/** Menu panel border color. */
|
|
238
|
+
border: "--better-locale-border",
|
|
239
|
+
/** Item hover background. */
|
|
240
|
+
hoverBg: "--better-locale-hover-bg",
|
|
241
|
+
/** Active (selected) item background. */
|
|
242
|
+
activeBg: "--better-locale-active-bg",
|
|
243
|
+
/** Muted text color (locale code badge, chevron). */
|
|
244
|
+
codeText: "--better-locale-code-text",
|
|
245
|
+
/** Checkmark / accent color. */
|
|
246
|
+
accent: "--better-locale-accent",
|
|
247
|
+
/** Trigger button padding. */
|
|
248
|
+
triggerPadding: "--better-locale-trigger-padding",
|
|
249
|
+
/** Trigger button border-radius. */
|
|
250
|
+
triggerRadius: "--better-locale-trigger-radius",
|
|
251
|
+
/** Trigger button border. */
|
|
252
|
+
triggerBorder: "--better-locale-trigger-border",
|
|
253
|
+
/** Trigger button background. */
|
|
254
|
+
triggerBg: "--better-locale-trigger-bg",
|
|
255
|
+
};
|
|
256
|
+
// ─── Component ───────────────────────────────────────────────────────
|
|
257
|
+
/**
|
|
258
|
+
* Headless-friendly locale dropdown UI.
|
|
259
|
+
*
|
|
260
|
+
* Pure presentational component — no routing hooks, no framework assumptions.
|
|
261
|
+
* Pass `locale`, `languages`, and `onLocaleChange` from your adapter.
|
|
262
|
+
*
|
|
263
|
+
* The menu element is **always in the DOM** so floating-ui can pre-calculate
|
|
264
|
+
* position. Visibility is controlled via CSS `data-state` attribute — this
|
|
265
|
+
* eliminates the positioning flash that occurs with conditional rendering.
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```tsx
|
|
269
|
+
* // Minimal usage
|
|
270
|
+
* <LocaleDropdownBase
|
|
271
|
+
* locale={locale}
|
|
272
|
+
* languages={languages}
|
|
273
|
+
* onLocaleChange={navigate}
|
|
274
|
+
* />
|
|
275
|
+
*
|
|
276
|
+
* // Headless — bring your own styles
|
|
277
|
+
* <LocaleDropdownBase
|
|
278
|
+
* locale={locale}
|
|
279
|
+
* languages={languages}
|
|
280
|
+
* onLocaleChange={navigate}
|
|
281
|
+
* variant="unstyled"
|
|
282
|
+
* renderItem={({ language, isActive }) => <MyItem ... />}
|
|
283
|
+
* />
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
export function LocaleDropdownBase({ locale, languages, onLocaleChange, isLoading = false, variant = "styled", className, triggerClassName, menuClassName, showFlag = true, showNativeName = true, showLocaleCode = true, placement: placementProp = "auto", renderTrigger, renderItem, }) {
|
|
287
|
+
// "closed" → hidden | "open" → visible + entrance animation | "closing" → exit animation
|
|
288
|
+
const [menuState, setMenuState] = useState("closed");
|
|
289
|
+
const [openCount, setOpenCount] = useState(0); // increments on each open → forces item re-mount → CSS animation replays
|
|
290
|
+
const [focusIndex, setFocusIndex] = useState(-1);
|
|
291
|
+
const containerRef = useRef(null);
|
|
292
|
+
const closeTimerRef = useRef(null);
|
|
293
|
+
const isOpen = menuState === "open";
|
|
294
|
+
const openMenu = useCallback(() => {
|
|
295
|
+
if (closeTimerRef.current) {
|
|
296
|
+
clearTimeout(closeTimerRef.current);
|
|
297
|
+
closeTimerRef.current = null;
|
|
298
|
+
}
|
|
299
|
+
setOpenCount((c) => c + 1);
|
|
300
|
+
setMenuState("open");
|
|
301
|
+
}, []);
|
|
302
|
+
const closeMenu = useCallback(() => {
|
|
303
|
+
setMenuState("closing");
|
|
304
|
+
closeTimerRef.current = setTimeout(() => {
|
|
305
|
+
setMenuState("closed");
|
|
306
|
+
closeTimerRef.current = null;
|
|
307
|
+
}, 150);
|
|
308
|
+
}, []);
|
|
309
|
+
useEffect(() => {
|
|
310
|
+
return () => {
|
|
311
|
+
if (closeTimerRef.current)
|
|
312
|
+
clearTimeout(closeTimerRef.current);
|
|
313
|
+
};
|
|
314
|
+
}, []);
|
|
315
|
+
// Use top/left instead of floatingStyles (which uses transform: translate).
|
|
316
|
+
// Our CSS animations also use transform — they'd override the positioning.
|
|
317
|
+
const { refs, x, y, placement: resolvedPlacement } = useFloating({
|
|
318
|
+
open: true,
|
|
319
|
+
strategy: "absolute",
|
|
320
|
+
placement: placementProp === "top" ? "top-end" : "bottom-end",
|
|
321
|
+
middleware: [offset(4), flip({ padding: 16 }), shift({ padding: 8 })],
|
|
322
|
+
whileElementsMounted: autoUpdate,
|
|
323
|
+
});
|
|
324
|
+
const menuPositionStyle = {
|
|
325
|
+
position: "absolute",
|
|
326
|
+
top: y ?? 0,
|
|
327
|
+
left: x ?? 0,
|
|
328
|
+
};
|
|
329
|
+
const isStyled = variant === "styled";
|
|
330
|
+
const currentLanguage = useMemo(() => languages.find((l) => l.code === locale), [languages, locale]);
|
|
331
|
+
const currentLabel = currentLanguage ? getLanguageLabel(currentLanguage) : locale.toUpperCase();
|
|
332
|
+
const currentFlag = currentLanguage ? resolveFlag(currentLanguage) : null;
|
|
333
|
+
const canToggle = languages.length > 1;
|
|
334
|
+
// Close on outside click
|
|
335
|
+
useEffect(() => {
|
|
336
|
+
if (menuState === "closed")
|
|
337
|
+
return;
|
|
338
|
+
function handleClick(e) {
|
|
339
|
+
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
340
|
+
closeMenu();
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
document.addEventListener("mousedown", handleClick);
|
|
344
|
+
return () => document.removeEventListener("mousedown", handleClick);
|
|
345
|
+
}, [menuState, closeMenu]);
|
|
346
|
+
// Keyboard navigation
|
|
347
|
+
const handleKeyDown = useCallback((e) => {
|
|
348
|
+
if (!isOpen) {
|
|
349
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
350
|
+
e.preventDefault();
|
|
351
|
+
openMenu();
|
|
352
|
+
setFocusIndex(0);
|
|
353
|
+
}
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
switch (e.key) {
|
|
357
|
+
case "Escape":
|
|
358
|
+
e.preventDefault();
|
|
359
|
+
closeMenu();
|
|
360
|
+
setFocusIndex(-1);
|
|
361
|
+
break;
|
|
362
|
+
case "ArrowDown":
|
|
363
|
+
e.preventDefault();
|
|
364
|
+
setFocusIndex((prev) => (prev < languages.length - 1 ? prev + 1 : 0));
|
|
365
|
+
break;
|
|
366
|
+
case "ArrowUp":
|
|
367
|
+
e.preventDefault();
|
|
368
|
+
setFocusIndex((prev) => (prev > 0 ? prev - 1 : languages.length - 1));
|
|
369
|
+
break;
|
|
370
|
+
case "Enter":
|
|
371
|
+
case " ": {
|
|
372
|
+
e.preventDefault();
|
|
373
|
+
const lang = languages[focusIndex];
|
|
374
|
+
if (lang) {
|
|
375
|
+
onLocaleChange(lang.code);
|
|
376
|
+
closeMenu();
|
|
377
|
+
setFocusIndex(-1);
|
|
378
|
+
}
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
case "Home":
|
|
382
|
+
e.preventDefault();
|
|
383
|
+
setFocusIndex(0);
|
|
384
|
+
break;
|
|
385
|
+
case "End":
|
|
386
|
+
e.preventDefault();
|
|
387
|
+
setFocusIndex(languages.length - 1);
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
}, [isOpen, focusIndex, languages, onLocaleChange, openMenu, closeMenu]);
|
|
391
|
+
// Scroll focused item into view
|
|
392
|
+
useEffect(() => {
|
|
393
|
+
const menu = refs.floating.current;
|
|
394
|
+
if (focusIndex >= 0 && menu) {
|
|
395
|
+
const items = menu.querySelectorAll("[data-better-locale-item]");
|
|
396
|
+
items[focusIndex]?.scrollIntoView({ block: "nearest" });
|
|
397
|
+
}
|
|
398
|
+
}, [focusIndex, refs.floating]);
|
|
399
|
+
// Loading skeleton
|
|
400
|
+
if (isLoading) {
|
|
401
|
+
if (renderTrigger) {
|
|
402
|
+
return (_jsxs("div", { "data-better-locale-dropdown": true, className: className, children: [renderTrigger({ language: undefined, isOpen: false, isLoading: true, flag: null, label: "" }), isStyled && _jsx("style", { children: LOCALE_DROPDOWN_CSS })] }));
|
|
403
|
+
}
|
|
404
|
+
return (_jsxs("div", { "data-better-locale-dropdown": true, className: className, children: [_jsxs("div", { "aria-busy": "true", "data-better-locale-trigger": true, className: triggerClassName, style: isStyled ? styles.skeleton : undefined, children: [_jsx("span", { style: isStyled ? styles.skeletonFlag : undefined }), _jsx("span", { style: isStyled ? styles.skeletonText : undefined })] }), isStyled && _jsx("style", { children: LOCALE_DROPDOWN_CSS })] }));
|
|
405
|
+
}
|
|
406
|
+
const handleTriggerClick = () => {
|
|
407
|
+
if (!canToggle)
|
|
408
|
+
return;
|
|
409
|
+
if (isOpen) {
|
|
410
|
+
closeMenu();
|
|
411
|
+
}
|
|
412
|
+
else {
|
|
413
|
+
openMenu();
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
// data-state: "open" | "closing" | undefined (closed → hidden via CSS)
|
|
417
|
+
const dataState = menuState === "closed" ? undefined : menuState;
|
|
418
|
+
const placementDir = resolvedPlacement.startsWith("top") ? "top" : "bottom";
|
|
419
|
+
return (_jsxs("div", { ref: containerRef, "data-better-locale-dropdown": true, className: className, style: !className ? { position: "relative", display: "inline-block" } : { position: "relative" }, children: [renderTrigger ? (_jsx("div", { ref: refs.setReference, onClick: handleTriggerClick, onKeyDown: handleKeyDown, role: "button", tabIndex: 0, "aria-haspopup": "listbox", "aria-expanded": isOpen, "data-better-locale-trigger": true, className: triggerClassName, children: renderTrigger({ language: currentLanguage, isOpen, isLoading: false, flag: currentFlag, label: currentLabel }) })) : (_jsxs("button", { ref: refs.setReference, type: "button", onClick: handleTriggerClick, onKeyDown: handleKeyDown, "aria-haspopup": "listbox", "aria-expanded": isOpen, "aria-label": "Select language", disabled: !canToggle, "data-better-locale-trigger": true, className: triggerClassName, style: isStyled ? { ...styles.trigger, ...(!canToggle ? styles.triggerDisabled : {}) } : undefined, children: [showFlag && currentFlag && _jsx(FlagDisplay, { flag: currentFlag, label: currentLabel }), showNativeName && _jsx("span", { children: currentLabel }), canToggle && (_jsx(ChevronDownIcon, { style: { transition: "transform 0.2s", transform: isOpen ? "rotate(180deg)" : "rotate(0deg)", color: "var(--better-locale-code-text, var(--_bl-muted))" } }))] })), _jsx("ul", { ref: refs.setFloating, role: "listbox", "aria-label": "Available languages", "aria-hidden": menuState === "closed", "data-better-locale-menu": true, "data-state": dataState, "data-placement": placementDir, className: menuClassName, style: isStyled ? { ...styles.menu, ...menuPositionStyle } : menuPositionStyle, children: languages.map((language, index) => {
|
|
420
|
+
const label = getLanguageLabel(language);
|
|
421
|
+
const isActive = language.code === locale;
|
|
422
|
+
const isFocused = index === focusIndex;
|
|
423
|
+
const flag = resolveFlag(language);
|
|
424
|
+
if (renderItem) {
|
|
425
|
+
return (_jsx("li", { role: "option", "aria-selected": isActive, "data-better-locale-item": true, "data-active": isActive || undefined, "data-focused": isFocused || undefined, onClick: () => { onLocaleChange(language.code); closeMenu(); }, onMouseEnter: () => setFocusIndex(index), style: { cursor: "pointer" }, children: renderItem({ language, isActive, flag, label }) }, `${language.code}-${openCount}`));
|
|
426
|
+
}
|
|
427
|
+
return (_jsxs("li", { role: "option", "aria-selected": isActive, "data-better-locale-item": true, "data-active": isActive || undefined, "data-focused": isFocused || undefined, onClick: () => { onLocaleChange(language.code); closeMenu(); }, onMouseEnter: () => setFocusIndex(index), style: isStyled
|
|
428
|
+
? { ...styles.item, ...(isActive ? styles.itemActive : {}), ...(isFocused ? styles.itemHovered : {}) }
|
|
429
|
+
: undefined, children: [showFlag && _jsx(FlagDisplay, { flag: flag, label: label }), _jsx("span", { style: isStyled ? styles.label : undefined, children: showNativeName ? label : language.code.toUpperCase() }), showLocaleCode && (_jsx("span", { style: isStyled ? styles.code : undefined, children: language.code })), isActive && (_jsx("span", { style: isStyled ? styles.check : undefined, children: _jsx(CheckIcon, {}) }))] }, language.code));
|
|
430
|
+
}) }), isStyled && _jsx("style", { children: LOCALE_DROPDOWN_CSS })] }));
|
|
431
|
+
}
|
|
432
|
+
//# sourceMappingURL=locale-dropdown-base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale-dropdown-base.js","sourceRoot":"","sources":["../../src/react/locale-dropdown-base.tsx"],"names":[],"mappings":"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"}
|
package/dist/utils/locale.d.ts
CHANGED
|
@@ -31,10 +31,12 @@ export interface LocaleConfig {
|
|
|
31
31
|
* Follows next-intl / Paraglide JS convention.
|
|
32
32
|
* - `"always"`: ALL locales get a prefix, including the default (`/en/about`, `/tr/about`).
|
|
33
33
|
* Use with TanStack Router `$locale/` route segments.
|
|
34
|
+
* - `"never"`: NO locale prefix in URL for any locale. Locale is stored only in cookie.
|
|
35
|
+
* Ideal for dashboards and apps where URL structure shouldn't change per locale.
|
|
34
36
|
*
|
|
35
37
|
* @default "as-needed"
|
|
36
38
|
*/
|
|
37
|
-
localePrefix?: "always" | "as-needed";
|
|
39
|
+
localePrefix?: "always" | "as-needed" | "never";
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
40
42
|
* Extract locale from URL pathname
|
|
@@ -83,6 +85,7 @@ export declare function removeLocalePrefix(pathname: string, config: LocaleConfi
|
|
|
83
85
|
* Respects `localePrefix` config:
|
|
84
86
|
* - `"as-needed"` (default): default locale has no prefix
|
|
85
87
|
* - `"always"`: all locales get a prefix
|
|
88
|
+
* - `"never"`: no locale prefix for any locale (cookie-only)
|
|
86
89
|
*
|
|
87
90
|
* @example
|
|
88
91
|
* // as-needed (default)
|
|
@@ -91,6 +94,9 @@ export declare function removeLocalePrefix(pathname: string, config: LocaleConfi
|
|
|
91
94
|
*
|
|
92
95
|
* // always
|
|
93
96
|
* addLocalePrefix('/about', 'en', { ...config, localePrefix: 'always' }) // '/en/about'
|
|
97
|
+
*
|
|
98
|
+
* // never
|
|
99
|
+
* addLocalePrefix('/about', 'tr', { ...config, localePrefix: 'never' }) // '/about'
|
|
94
100
|
*/
|
|
95
101
|
export declare function addLocalePrefix(pathname: string, locale: string, config: LocaleConfig): string;
|
|
96
102
|
/**
|
|
@@ -99,6 +105,7 @@ export declare function addLocalePrefix(pathname: string, locale: string, config
|
|
|
99
105
|
* Respects `localePrefix` config:
|
|
100
106
|
* - `"as-needed"` (default): default locale has no prefix
|
|
101
107
|
* - `"always"`: all locales always get a prefix
|
|
108
|
+
* - `"never"`: no locale prefix for any locale (cookie-only)
|
|
102
109
|
*
|
|
103
110
|
* @example
|
|
104
111
|
* // as-needed (default)
|
|
@@ -107,6 +114,9 @@ export declare function addLocalePrefix(pathname: string, locale: string, config
|
|
|
107
114
|
*
|
|
108
115
|
* // always
|
|
109
116
|
* replaceLocaleInPath('/tr/about', 'en', { ...config, localePrefix: 'always' }) // '/en/about'
|
|
117
|
+
*
|
|
118
|
+
* // never
|
|
119
|
+
* replaceLocaleInPath('/tr/about', 'de', { ...config, localePrefix: 'never' }) // '/about'
|
|
110
120
|
*/
|
|
111
121
|
export declare function replaceLocaleInPath(pathname: string, newLocale: string, config: LocaleConfig): string;
|
|
112
122
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/utils/locale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,MACR,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB
|
|
1
|
+
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/utils/locale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,MAAM,KAAG,MACR,CAAC;AAE1C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;IAElB;;;OAGG;IACH,aAAa,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,WAAW,GAAG,OAAO,CAAC;CACjD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GACnB,MAAM,GAAG,IAAI,CASf;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GACnB,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GACnB,OAAO,CAET;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,YAAY,GACnB,MAAM,CAMR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,YAAY,GACnB,MAAM,CAeR;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GACnB,MAAM,CAgBR;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,IAC3C,MAAM,MAAM,EAAE,SAAS,MAAM,KAAG,MAAM,CAI/C"}
|
package/dist/utils/locale.js
CHANGED
|
@@ -74,6 +74,7 @@ export function removeLocalePrefix(pathname, config) {
|
|
|
74
74
|
* Respects `localePrefix` config:
|
|
75
75
|
* - `"as-needed"` (default): default locale has no prefix
|
|
76
76
|
* - `"always"`: all locales get a prefix
|
|
77
|
+
* - `"never"`: no locale prefix for any locale (cookie-only)
|
|
77
78
|
*
|
|
78
79
|
* @example
|
|
79
80
|
* // as-needed (default)
|
|
@@ -82,8 +83,15 @@ export function removeLocalePrefix(pathname, config) {
|
|
|
82
83
|
*
|
|
83
84
|
* // always
|
|
84
85
|
* addLocalePrefix('/about', 'en', { ...config, localePrefix: 'always' }) // '/en/about'
|
|
86
|
+
*
|
|
87
|
+
* // never
|
|
88
|
+
* addLocalePrefix('/about', 'tr', { ...config, localePrefix: 'never' }) // '/about'
|
|
85
89
|
*/
|
|
86
90
|
export function addLocalePrefix(pathname, locale, config) {
|
|
91
|
+
// Never add prefix — locale is cookie-only
|
|
92
|
+
if (config.localePrefix === "never") {
|
|
93
|
+
return pathname;
|
|
94
|
+
}
|
|
87
95
|
// Don't add prefix for default locale in "as-needed" mode
|
|
88
96
|
if (config.localePrefix !== "always" && locale === config.defaultLocale) {
|
|
89
97
|
return pathname;
|
|
@@ -99,6 +107,7 @@ export function addLocalePrefix(pathname, locale, config) {
|
|
|
99
107
|
* Respects `localePrefix` config:
|
|
100
108
|
* - `"as-needed"` (default): default locale has no prefix
|
|
101
109
|
* - `"always"`: all locales always get a prefix
|
|
110
|
+
* - `"never"`: no locale prefix for any locale (cookie-only)
|
|
102
111
|
*
|
|
103
112
|
* @example
|
|
104
113
|
* // as-needed (default)
|
|
@@ -107,10 +116,17 @@ export function addLocalePrefix(pathname, locale, config) {
|
|
|
107
116
|
*
|
|
108
117
|
* // always
|
|
109
118
|
* replaceLocaleInPath('/tr/about', 'en', { ...config, localePrefix: 'always' }) // '/en/about'
|
|
119
|
+
*
|
|
120
|
+
* // never
|
|
121
|
+
* replaceLocaleInPath('/tr/about', 'de', { ...config, localePrefix: 'never' }) // '/about'
|
|
110
122
|
*/
|
|
111
123
|
export function replaceLocaleInPath(pathname, newLocale, config) {
|
|
112
124
|
// Remove existing locale prefix if present
|
|
113
125
|
const cleanPath = removeLocalePrefix(pathname, config);
|
|
126
|
+
// Never add prefix — locale is cookie-only
|
|
127
|
+
if (config.localePrefix === "never") {
|
|
128
|
+
return cleanPath;
|
|
129
|
+
}
|
|
114
130
|
// In "as-needed" mode, don't add prefix for default locale
|
|
115
131
|
if (config.localePrefix !== "always" && newLocale === config.defaultLocale) {
|
|
116
132
|
return cleanPath;
|
package/dist/utils/locale.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/utils/locale.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAc,EAAU,EAAE,CACxD,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/utils/locale.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-i18n/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Framework-agnostic core utilities for Better i18n",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -22,6 +22,11 @@
|
|
|
22
22
|
"react-native": "./dist/index.js",
|
|
23
23
|
"default": "./dist/index.js"
|
|
24
24
|
},
|
|
25
|
+
"./react": {
|
|
26
|
+
"types": "./src/react/index.tsx",
|
|
27
|
+
"bun": "./src/react/index.tsx",
|
|
28
|
+
"default": "./dist/react/index.js"
|
|
29
|
+
},
|
|
25
30
|
"./package.json": "./package.json"
|
|
26
31
|
},
|
|
27
32
|
"files": [
|
|
@@ -45,8 +50,21 @@
|
|
|
45
50
|
"clean": "rm -rf dist",
|
|
46
51
|
"prepublishOnly": "bun run build"
|
|
47
52
|
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"react": ">=18.0.0",
|
|
55
|
+
"@floating-ui/react": ">=0.26.0"
|
|
56
|
+
},
|
|
57
|
+
"peerDependenciesMeta": {
|
|
58
|
+
"react": {
|
|
59
|
+
"optional": true
|
|
60
|
+
},
|
|
61
|
+
"@floating-ui/react": {
|
|
62
|
+
"optional": true
|
|
63
|
+
}
|
|
64
|
+
},
|
|
48
65
|
"devDependencies": {
|
|
49
66
|
"@types/node": "^20.0.0",
|
|
67
|
+
"@types/react": "^19.2.10",
|
|
50
68
|
"typescript": "~5.9.2"
|
|
51
69
|
}
|
|
52
70
|
}
|