@lobehub/ui 6.0.3 → 6.0.5

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.
@@ -6,9 +6,9 @@ export declare const accordionStyles: {
6
6
  action: string;
7
7
  content: string;
8
8
  trigger: string;
9
+ item: string;
9
10
  root: string;
10
11
  indicator: string;
11
- item: string;
12
12
  itemOutlined: string;
13
13
  rootOutlined: string;
14
14
  actionAlwaysVisible: string;
@@ -12,6 +12,7 @@ const createTanstackEngine = (initialValues) => {
12
12
  const serverErrors = /* @__PURE__ */ new Map();
13
13
  const validating = /* @__PURE__ */ new Set();
14
14
  const touched = /* @__PURE__ */ new Set();
15
+ const edited = /* @__PURE__ */ new Set();
15
16
  const listeners = /* @__PURE__ */ new Set();
16
17
  const valueListeners = /* @__PURE__ */ new Set();
17
18
  const snapshots = /* @__PURE__ */ new Map();
@@ -36,6 +37,10 @@ const createTanstackEngine = (initialValues) => {
36
37
  for (const entry of touched) if (isSameOrNested(entry, path)) return true;
37
38
  return false;
38
39
  };
40
+ const isEdited = (path) => {
41
+ for (const entry of edited) if (isSameOrNested(entry, path)) return true;
42
+ return false;
43
+ };
39
44
  const errorOf = (path) => serverErrors.get(path) ?? fieldErrors.get(path) ?? formErrors.get(path);
40
45
  const getField = (path) => {
41
46
  const next = {
@@ -70,7 +75,8 @@ const createTanstackEngine = (initialValues) => {
70
75
  if (mode === "change") return true;
71
76
  if (mode === "blur") return trigger === "blur";
72
77
  if (mode === "submit") return false;
73
- return trigger === "blur" || errorOf(path) !== void 0;
78
+ if (errorOf(path) !== void 0) return true;
79
+ return trigger === "blur" && (isEdited(path) || submitCount > 0);
74
80
  };
75
81
  const setOrDelete = (map, path, error) => {
76
82
  if (error === void 0) map.delete(path);
@@ -128,6 +134,7 @@ const createTanstackEngine = (initialValues) => {
128
134
  };
129
135
  const afterUserChange = (path) => {
130
136
  touched.add(path);
137
+ edited.add(path);
131
138
  serverErrors.delete(path);
132
139
  schedule(path, "change");
133
140
  for (const [other, runtime] of fields) if (other !== path && runtime.registration.deps?.includes(path) && isTouched(other)) runField(other, true);
@@ -160,6 +167,7 @@ const createTanstackEngine = (initialValues) => {
160
167
  serverErrors.clear();
161
168
  validating.clear();
162
169
  touched.clear();
170
+ edited.clear();
163
171
  };
164
172
  const runSubmit = async (onSubmit) => {
165
173
  submitCount += 1;
@@ -210,6 +218,7 @@ const createTanstackEngine = (initialValues) => {
210
218
  moveItem: (path, from, to) => {
211
219
  form.moveFieldValues(toEnginePath(path), from, to);
212
220
  touched.add(path);
221
+ edited.add(path);
213
222
  clearErrorsUnder(path);
214
223
  emitValueChange(path, "user");
215
224
  notify();
@@ -221,6 +230,7 @@ const createTanstackEngine = (initialValues) => {
221
230
  pushItem: (path, item) => {
222
231
  form.pushFieldValue(toEnginePath(path), item);
223
232
  touched.add(path);
233
+ edited.add(path);
224
234
  emitValueChange(path, "user");
225
235
  notify();
226
236
  },
@@ -243,6 +253,7 @@ const createTanstackEngine = (initialValues) => {
243
253
  removeItem: (path, index) => {
244
254
  form.removeFieldValue(toEnginePath(path), index);
245
255
  touched.add(path);
256
+ edited.add(path);
246
257
  clearErrorsUnder(path);
247
258
  emitValueChange(path, "user");
248
259
  notify();
@@ -256,6 +267,7 @@ const createTanstackEngine = (initialValues) => {
256
267
  validating.delete(key);
257
268
  }
258
269
  for (const entry of touched) if (isUnder(entry, path)) touched.delete(entry);
270
+ for (const entry of edited) if (isUnder(entry, path)) edited.delete(entry);
259
271
  clearErrorsUnder(path, true);
260
272
  form.setFieldValue(toEnginePath(path), getBy(baseline, toEnginePath(path)), { dontUpdateMeta: true });
261
273
  emitValueChange(path, "api");
@@ -1 +1 @@
1
- {"version":3,"file":"tanstack.mjs","names":[],"sources":["../../../src/FormKit/engine/tanstack.ts"],"sourcesContent":["import { FormApi, getBy, setBy } from '@tanstack/form-core';\nimport { isEqual } from 'es-toolkit/compat';\n\nimport type {\n ChangeSource,\n CreateEngine,\n FieldRegistration,\n FieldSnapshot,\n FormEngine,\n FormStatus,\n FormValidator,\n ValidateResult,\n ValidateTrigger,\n ValueChange,\n} from './types';\n\nconst toEnginePath = (path: string) => path.replaceAll(/\\.(\\d+)(?=\\.|$)/g, '[$1]');\n\nconst isSameOrNested = (a: string, b: string) =>\n a === b || a.startsWith(`${b}.`) || b.startsWith(`${a}.`);\n\nconst isUnder = (path: string, root: string) => path === root || path.startsWith(`${root}.`);\n\ninterface FieldRuntime {\n registration: FieldRegistration;\n timer?: ReturnType<typeof setTimeout>;\n token: number;\n}\n\nexport const createTanstackEngine: CreateEngine = (initialValues) => {\n const form = new FormApi({ defaultValues: initialValues });\n\n const fields = new Map<string, FieldRuntime>();\n const fieldErrors = new Map<string, string>();\n const formErrors = new Map<string, string>();\n const serverErrors = new Map<string, string>();\n const validating = new Set<string>();\n const touched = new Set<string>();\n const listeners = new Set<() => void>();\n const valueListeners = new Set<(change: ValueChange) => void>();\n const snapshots = new Map<string, FieldSnapshot>();\n\n let formValidator: FormValidator | undefined;\n let baseline = initialValues;\n let dirtyCache: { baseline: unknown; dirty: boolean; values: unknown } | undefined;\n let inflightSubmit: Promise<ValidateResult> | undefined;\n let submitting = false;\n let submitCount = 0;\n let status: FormStatus = { dirty: false, submitCount: 0, submitting: false };\n\n const notify = () => {\n for (const listener of listeners) listener();\n };\n const storeSubscription = form.store.subscribe(notify);\n\n const getValue = (path: string) => form.getFieldValue(toEnginePath(path) as never) as unknown;\n const getValues = () => form.state.values as Record<string, unknown>;\n const isTouched = (path: string) => {\n for (const entry of touched) if (isSameOrNested(entry, path)) return true;\n return false;\n };\n const errorOf = (path: string) =>\n serverErrors.get(path) ?? fieldErrors.get(path) ?? formErrors.get(path);\n\n const getField = (path: string): FieldSnapshot => {\n const next: FieldSnapshot = {\n error: errorOf(path),\n touched: isTouched(path),\n validating: validating.has(path),\n value: getValue(path),\n };\n const prev = snapshots.get(path);\n if (\n prev &&\n prev.error === next.error &&\n prev.touched === next.touched &&\n prev.validating === next.validating &&\n Object.is(prev.value, next.value)\n )\n return prev;\n snapshots.set(path, next);\n return next;\n };\n\n const getStatus = (): FormStatus => {\n const values = getValues();\n if (dirtyCache?.values !== values || dirtyCache.baseline !== baseline)\n dirtyCache = { baseline, dirty: !isEqual(values, baseline), values };\n const { dirty } = dirtyCache;\n if (\n status.dirty !== dirty ||\n status.submitting !== submitting ||\n status.submitCount !== submitCount\n )\n status = { dirty, submitCount, submitting };\n return status;\n };\n\n const shouldValidate = (path: string, trigger: ValidateTrigger) => {\n const mode = fields.get(path)?.registration.validateOn ?? 'auto';\n if (trigger === 'submit') return true;\n if (mode === 'change') return true;\n if (mode === 'blur') return trigger === 'blur';\n if (mode === 'submit') return false;\n return trigger === 'blur' || errorOf(path) !== undefined;\n };\n\n const setOrDelete = (map: Map<string, string>, path: string, error: string | undefined) => {\n if (error === undefined) map.delete(path);\n else map.set(path, error);\n };\n\n const runField = (path: string, withFormValidator: boolean): Promise<void> => {\n const runtime = fields.get(path);\n if (!runtime) return Promise.resolve();\n runtime.token += 1;\n const token = runtime.token;\n const { validate } = runtime.registration;\n if (!validate && !(withFormValidator && formValidator)) return Promise.resolve();\n\n validating.add(path);\n notify();\n return (async () => {\n const values = getValues();\n const [fieldError, formResult] = await Promise.all([\n validate?.(getValue(path), values),\n withFormValidator ? formValidator?.(values) : undefined,\n ]);\n if (runtime.token !== token || fields.get(path) !== runtime) return;\n setOrDelete(fieldErrors, path, fieldError);\n if (withFormValidator) setOrDelete(formErrors, path, formResult?.[path]);\n validating.delete(path);\n notify();\n })();\n };\n\n const schedule = (path: string, trigger: ValidateTrigger) => {\n const runtime = fields.get(path);\n if (!runtime || !shouldValidate(path, trigger)) return;\n clearTimeout(runtime.timer);\n const debounceMs = runtime.registration.debounceMs ?? 0;\n if (trigger === 'change' && debounceMs > 0) {\n runtime.token += 1;\n runtime.timer = setTimeout(() => void runField(path, true), debounceMs);\n return;\n }\n void runField(path, true);\n };\n\n const clearErrorsUnder = (path: string, inclusive = false) => {\n for (const map of [fieldErrors, formErrors, serverErrors])\n for (const key of map.keys())\n if (inclusive ? isUnder(key, path) : key.startsWith(`${path}.`)) map.delete(key);\n };\n\n const resetTo = (values: Record<string, unknown>) => {\n clearRuntimeState();\n baseline = values;\n form.reset(values);\n notify();\n };\n\n const emitValueChange = (path: string, source: ChangeSource) => {\n for (const listener of valueListeners) listener({ path, source });\n };\n\n const afterUserChange = (path: string) => {\n touched.add(path);\n serverErrors.delete(path);\n schedule(path, 'change');\n for (const [other, runtime] of fields) {\n if (other !== path && runtime.registration.deps?.includes(path) && isTouched(other))\n void runField(other, true);\n }\n notify();\n };\n\n const validate = async (paths?: string[]): Promise<ValidateResult> => {\n const values = getValues();\n const formResult = (formValidator ? await formValidator(values) : undefined) ?? {};\n const targets = paths ?? [...new Set([...fields.keys(), ...Object.keys(formResult)])];\n await Promise.all(targets.map((path) => runField(path, false)));\n for (const path of targets) setOrDelete(formErrors, path, formResult[path]);\n notify();\n const errors: Record<string, string> = {};\n for (const path of targets) {\n const error = errorOf(path);\n if (error !== undefined) errors[path] = error;\n }\n return { errors, valid: Object.keys(errors).length === 0 };\n };\n\n const clearRuntimeState = () => {\n for (const runtime of fields.values()) {\n clearTimeout(runtime.timer);\n runtime.token += 1;\n }\n fieldErrors.clear();\n formErrors.clear();\n serverErrors.clear();\n validating.clear();\n touched.clear();\n };\n\n const runSubmit = async (onSubmit?: (values: Record<string, unknown>) => unknown) => {\n submitCount += 1;\n serverErrors.clear();\n for (const path of fields.keys()) touched.add(path);\n let values: Record<string, unknown>;\n let result: ValidateResult;\n do {\n values = getValues();\n result = await validate();\n // Async validators must finish against unchanged values before submission.\n } while (values !== getValues());\n if (!result.valid) {\n notify();\n return result;\n }\n submitting = true;\n notify();\n try {\n await onSubmit?.(values);\n if (serverErrors.size > 0) return { errors: Object.fromEntries(serverErrors), valid: false };\n resetTo(getValues());\n } finally {\n submitting = false;\n notify();\n }\n return result;\n };\n\n const engine: FormEngine = {\n blurField: (path) => {\n touched.add(path);\n schedule(path, 'blur');\n notify();\n },\n destroy: () => {\n for (const runtime of fields.values()) clearTimeout(runtime.timer);\n storeSubscription.unsubscribe();\n listeners.clear();\n valueListeners.clear();\n },\n getField,\n getStatus,\n getValue,\n getValues,\n isTouched,\n moveItem: (path, from, to) => {\n form.moveFieldValues(toEnginePath(path) as never, from, to);\n touched.add(path);\n clearErrorsUnder(path);\n emitValueChange(path, 'user');\n notify();\n },\n onValueChange: (listener) => {\n valueListeners.add(listener);\n return () => valueListeners.delete(listener);\n },\n pushItem: (path, item) => {\n form.pushFieldValue(toEnginePath(path) as never, item as never);\n touched.add(path);\n emitValueChange(path, 'user');\n notify();\n },\n registerField: (path, registration) => {\n const runtime: FieldRuntime = { registration, token: 0 };\n fields.set(path, runtime);\n return () => {\n if (fields.get(path) !== runtime) return;\n clearTimeout(runtime.timer);\n fields.delete(path);\n fieldErrors.delete(path);\n validating.delete(path);\n snapshots.delete(path);\n notify();\n };\n },\n removeItem: (path, index) => {\n void form.removeFieldValue(toEnginePath(path) as never, index);\n touched.add(path);\n clearErrorsUnder(path);\n emitValueChange(path, 'user');\n notify();\n },\n reset: (values) => resetTo(values ?? baseline),\n resetField: (path) => {\n for (const [key, runtime] of fields) {\n if (!isUnder(key, path)) continue;\n clearTimeout(runtime.timer);\n runtime.token += 1;\n validating.delete(key);\n }\n for (const entry of touched) if (isUnder(entry, path)) touched.delete(entry);\n clearErrorsUnder(path, true);\n form.setFieldValue(toEnginePath(path) as never, getBy(baseline, toEnginePath(path)), {\n dontUpdateMeta: true,\n });\n emitValueChange(path, 'api');\n notify();\n },\n setErrors: (errors) => {\n for (const [path, error] of Object.entries(errors)) setOrDelete(serverErrors, path, error);\n notify();\n },\n setFormValidator: (validator) => {\n formValidator = validator;\n },\n setValue: (path, value, source) => {\n form.setFieldValue(toEnginePath(path) as never, value as never, { dontUpdateMeta: true });\n if (source === 'api') baseline = setBy(baseline, toEnginePath(path), () => value);\n emitValueChange(path, source);\n if (source === 'user') afterUserChange(path);\n },\n submit: (onSubmit) => {\n inflightSubmit ??= runSubmit(onSubmit).finally(() => {\n inflightSubmit = undefined;\n });\n return inflightSubmit;\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n validate,\n };\n\n return engine;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"tanstack.mjs","names":[],"sources":["../../../src/FormKit/engine/tanstack.ts"],"sourcesContent":["import { FormApi, getBy, setBy } from '@tanstack/form-core';\nimport { isEqual } from 'es-toolkit/compat';\n\nimport type {\n ChangeSource,\n CreateEngine,\n FieldRegistration,\n FieldSnapshot,\n FormEngine,\n FormStatus,\n FormValidator,\n ValidateResult,\n ValidateTrigger,\n ValueChange,\n} from './types';\n\nconst toEnginePath = (path: string) => path.replaceAll(/\\.(\\d+)(?=\\.|$)/g, '[$1]');\n\nconst isSameOrNested = (a: string, b: string) =>\n a === b || a.startsWith(`${b}.`) || b.startsWith(`${a}.`);\n\nconst isUnder = (path: string, root: string) => path === root || path.startsWith(`${root}.`);\n\ninterface FieldRuntime {\n registration: FieldRegistration;\n timer?: ReturnType<typeof setTimeout>;\n token: number;\n}\n\nexport const createTanstackEngine: CreateEngine = (initialValues) => {\n const form = new FormApi({ defaultValues: initialValues });\n\n const fields = new Map<string, FieldRuntime>();\n const fieldErrors = new Map<string, string>();\n const formErrors = new Map<string, string>();\n const serverErrors = new Map<string, string>();\n const validating = new Set<string>();\n const touched = new Set<string>();\n const edited = new Set<string>();\n const listeners = new Set<() => void>();\n const valueListeners = new Set<(change: ValueChange) => void>();\n const snapshots = new Map<string, FieldSnapshot>();\n\n let formValidator: FormValidator | undefined;\n let baseline = initialValues;\n let dirtyCache: { baseline: unknown; dirty: boolean; values: unknown } | undefined;\n let inflightSubmit: Promise<ValidateResult> | undefined;\n let submitting = false;\n let submitCount = 0;\n let status: FormStatus = { dirty: false, submitCount: 0, submitting: false };\n\n const notify = () => {\n for (const listener of listeners) listener();\n };\n const storeSubscription = form.store.subscribe(notify);\n\n const getValue = (path: string) => form.getFieldValue(toEnginePath(path) as never) as unknown;\n const getValues = () => form.state.values as Record<string, unknown>;\n const isTouched = (path: string) => {\n for (const entry of touched) if (isSameOrNested(entry, path)) return true;\n return false;\n };\n const isEdited = (path: string) => {\n for (const entry of edited) if (isSameOrNested(entry, path)) return true;\n return false;\n };\n const errorOf = (path: string) =>\n serverErrors.get(path) ?? fieldErrors.get(path) ?? formErrors.get(path);\n\n const getField = (path: string): FieldSnapshot => {\n const next: FieldSnapshot = {\n error: errorOf(path),\n touched: isTouched(path),\n validating: validating.has(path),\n value: getValue(path),\n };\n const prev = snapshots.get(path);\n if (\n prev &&\n prev.error === next.error &&\n prev.touched === next.touched &&\n prev.validating === next.validating &&\n Object.is(prev.value, next.value)\n )\n return prev;\n snapshots.set(path, next);\n return next;\n };\n\n const getStatus = (): FormStatus => {\n const values = getValues();\n if (dirtyCache?.values !== values || dirtyCache.baseline !== baseline)\n dirtyCache = { baseline, dirty: !isEqual(values, baseline), values };\n const { dirty } = dirtyCache;\n if (\n status.dirty !== dirty ||\n status.submitting !== submitting ||\n status.submitCount !== submitCount\n )\n status = { dirty, submitCount, submitting };\n return status;\n };\n\n const shouldValidate = (path: string, trigger: ValidateTrigger) => {\n const mode = fields.get(path)?.registration.validateOn ?? 'auto';\n if (trigger === 'submit') return true;\n if (mode === 'change') return true;\n if (mode === 'blur') return trigger === 'blur';\n if (mode === 'submit') return false;\n if (errorOf(path) !== undefined) return true;\n return trigger === 'blur' && (isEdited(path) || submitCount > 0);\n };\n\n const setOrDelete = (map: Map<string, string>, path: string, error: string | undefined) => {\n if (error === undefined) map.delete(path);\n else map.set(path, error);\n };\n\n const runField = (path: string, withFormValidator: boolean): Promise<void> => {\n const runtime = fields.get(path);\n if (!runtime) return Promise.resolve();\n runtime.token += 1;\n const token = runtime.token;\n const { validate } = runtime.registration;\n if (!validate && !(withFormValidator && formValidator)) return Promise.resolve();\n\n validating.add(path);\n notify();\n return (async () => {\n const values = getValues();\n const [fieldError, formResult] = await Promise.all([\n validate?.(getValue(path), values),\n withFormValidator ? formValidator?.(values) : undefined,\n ]);\n if (runtime.token !== token || fields.get(path) !== runtime) return;\n setOrDelete(fieldErrors, path, fieldError);\n if (withFormValidator) setOrDelete(formErrors, path, formResult?.[path]);\n validating.delete(path);\n notify();\n })();\n };\n\n const schedule = (path: string, trigger: ValidateTrigger) => {\n const runtime = fields.get(path);\n if (!runtime || !shouldValidate(path, trigger)) return;\n clearTimeout(runtime.timer);\n const debounceMs = runtime.registration.debounceMs ?? 0;\n if (trigger === 'change' && debounceMs > 0) {\n runtime.token += 1;\n runtime.timer = setTimeout(() => void runField(path, true), debounceMs);\n return;\n }\n void runField(path, true);\n };\n\n const clearErrorsUnder = (path: string, inclusive = false) => {\n for (const map of [fieldErrors, formErrors, serverErrors])\n for (const key of map.keys())\n if (inclusive ? isUnder(key, path) : key.startsWith(`${path}.`)) map.delete(key);\n };\n\n const resetTo = (values: Record<string, unknown>) => {\n clearRuntimeState();\n baseline = values;\n form.reset(values);\n notify();\n };\n\n const emitValueChange = (path: string, source: ChangeSource) => {\n for (const listener of valueListeners) listener({ path, source });\n };\n\n const afterUserChange = (path: string) => {\n touched.add(path);\n edited.add(path);\n serverErrors.delete(path);\n schedule(path, 'change');\n for (const [other, runtime] of fields) {\n if (other !== path && runtime.registration.deps?.includes(path) && isTouched(other))\n void runField(other, true);\n }\n notify();\n };\n\n const validate = async (paths?: string[]): Promise<ValidateResult> => {\n const values = getValues();\n const formResult = (formValidator ? await formValidator(values) : undefined) ?? {};\n const targets = paths ?? [...new Set([...fields.keys(), ...Object.keys(formResult)])];\n await Promise.all(targets.map((path) => runField(path, false)));\n for (const path of targets) setOrDelete(formErrors, path, formResult[path]);\n notify();\n const errors: Record<string, string> = {};\n for (const path of targets) {\n const error = errorOf(path);\n if (error !== undefined) errors[path] = error;\n }\n return { errors, valid: Object.keys(errors).length === 0 };\n };\n\n const clearRuntimeState = () => {\n for (const runtime of fields.values()) {\n clearTimeout(runtime.timer);\n runtime.token += 1;\n }\n fieldErrors.clear();\n formErrors.clear();\n serverErrors.clear();\n validating.clear();\n touched.clear();\n edited.clear();\n };\n\n const runSubmit = async (onSubmit?: (values: Record<string, unknown>) => unknown) => {\n submitCount += 1;\n serverErrors.clear();\n for (const path of fields.keys()) touched.add(path);\n let values: Record<string, unknown>;\n let result: ValidateResult;\n do {\n values = getValues();\n result = await validate();\n // Async validators must finish against unchanged values before submission.\n } while (values !== getValues());\n if (!result.valid) {\n notify();\n return result;\n }\n submitting = true;\n notify();\n try {\n await onSubmit?.(values);\n if (serverErrors.size > 0) return { errors: Object.fromEntries(serverErrors), valid: false };\n resetTo(getValues());\n } finally {\n submitting = false;\n notify();\n }\n return result;\n };\n\n const engine: FormEngine = {\n blurField: (path) => {\n touched.add(path);\n schedule(path, 'blur');\n notify();\n },\n destroy: () => {\n for (const runtime of fields.values()) clearTimeout(runtime.timer);\n storeSubscription.unsubscribe();\n listeners.clear();\n valueListeners.clear();\n },\n getField,\n getStatus,\n getValue,\n getValues,\n isTouched,\n moveItem: (path, from, to) => {\n form.moveFieldValues(toEnginePath(path) as never, from, to);\n touched.add(path);\n edited.add(path);\n clearErrorsUnder(path);\n emitValueChange(path, 'user');\n notify();\n },\n onValueChange: (listener) => {\n valueListeners.add(listener);\n return () => valueListeners.delete(listener);\n },\n pushItem: (path, item) => {\n form.pushFieldValue(toEnginePath(path) as never, item as never);\n touched.add(path);\n edited.add(path);\n emitValueChange(path, 'user');\n notify();\n },\n registerField: (path, registration) => {\n const runtime: FieldRuntime = { registration, token: 0 };\n fields.set(path, runtime);\n return () => {\n if (fields.get(path) !== runtime) return;\n clearTimeout(runtime.timer);\n fields.delete(path);\n fieldErrors.delete(path);\n validating.delete(path);\n snapshots.delete(path);\n notify();\n };\n },\n removeItem: (path, index) => {\n void form.removeFieldValue(toEnginePath(path) as never, index);\n touched.add(path);\n edited.add(path);\n clearErrorsUnder(path);\n emitValueChange(path, 'user');\n notify();\n },\n reset: (values) => resetTo(values ?? baseline),\n resetField: (path) => {\n for (const [key, runtime] of fields) {\n if (!isUnder(key, path)) continue;\n clearTimeout(runtime.timer);\n runtime.token += 1;\n validating.delete(key);\n }\n for (const entry of touched) if (isUnder(entry, path)) touched.delete(entry);\n for (const entry of edited) if (isUnder(entry, path)) edited.delete(entry);\n clearErrorsUnder(path, true);\n form.setFieldValue(toEnginePath(path) as never, getBy(baseline, toEnginePath(path)), {\n dontUpdateMeta: true,\n });\n emitValueChange(path, 'api');\n notify();\n },\n setErrors: (errors) => {\n for (const [path, error] of Object.entries(errors)) setOrDelete(serverErrors, path, error);\n notify();\n },\n setFormValidator: (validator) => {\n formValidator = validator;\n },\n setValue: (path, value, source) => {\n form.setFieldValue(toEnginePath(path) as never, value as never, { dontUpdateMeta: true });\n if (source === 'api') baseline = setBy(baseline, toEnginePath(path), () => value);\n emitValueChange(path, source);\n if (source === 'user') afterUserChange(path);\n },\n submit: (onSubmit) => {\n inflightSubmit ??= runSubmit(onSubmit).finally(() => {\n inflightSubmit = undefined;\n });\n return inflightSubmit;\n },\n subscribe: (listener) => {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n validate,\n };\n\n return engine;\n};\n"],"mappings":"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"}
@@ -58,13 +58,10 @@ import "./LandingSection/index.mjs";
58
58
  import { LogoMarqueeItem, LogoMarqueeProps } from "./LogoMarquee/type.mjs";
59
59
  import LogoMarquee from "./LogoMarquee/LogoMarquee.mjs";
60
60
  import "./LogoMarquee/index.mjs";
61
- import { SplineProps } from "./Spline/type.mjs";
62
- import Spline from "./Spline/Spine.mjs";
63
- import "./Spline/index.mjs";
64
61
  import { SpotlightProps } from "./Spotlight/type.mjs";
65
62
  import Spotlight from "./Spotlight/Spotlight.mjs";
66
63
  import "./Spotlight/index.mjs";
67
64
  import { CursorStyle, SegmentMode, TypewriterEffectProps } from "./TypewriterEffect/type.mjs";
68
65
  import TypewriterEffect from "./TypewriterEffect/TypewriterEffect.mjs";
69
66
  import "./TypewriterEffect/index.mjs";
70
- export { AgentSkillCard, type AgentSkillCardAgent, type AgentSkillCardMode, type AgentSkillCardPanel, type AgentSkillCardProps, AuroraBackground, type AuroraBackgroundProps, BentoCard, type BentoCardProps, BentoGrid, type BentoGridProps, BottomGradientButton, type BottomGradientButtonProps, CodeShowcase, type CodeShowcaseItem, type CodeShowcaseProps, type CursorStyle, DEFAULT_SKILL_AGENTS, FeatureGrid, type FeatureGridItem, type FeatureGridProps, type FeatureItemType, Features, type FeaturesProps, FluidGradient, type FluidGradientProps, Giscus, type GiscusProps, GradientButton, type GradientButtonProps, Grainient, type GrainientProps, GridBackground, type GridBackgroundProps, GridShowcase, type GridShowcaseProps, Hero, type HeroAction, type HeroProps, InstallBanner, type InstallBannerProps, LANDING_GRADIENT_VAR, LANDING_PALETTE_DARK, LANDING_PALETTE_LIGHT, type LandingAction, LandingHero, type LandingHeroAction, type LandingHeroProps, type LandingLinkProps, type LandingLinkRender, type LandingNavigate, type LandingPalette, LandingSection, type LandingSectionProps, LogoMarquee, type LogoMarqueeItem, type LogoMarqueeProps, type SegmentMode, Spline, type SplineProps, Spotlight, SpotlightCard, type SpotlightCardProps, type SpotlightProps, TypewriterEffect, type TypewriterEffectProps, accentGradient as landingAccentGradient };
67
+ export { AgentSkillCard, type AgentSkillCardAgent, type AgentSkillCardMode, type AgentSkillCardPanel, type AgentSkillCardProps, AuroraBackground, type AuroraBackgroundProps, BentoCard, type BentoCardProps, BentoGrid, type BentoGridProps, BottomGradientButton, type BottomGradientButtonProps, CodeShowcase, type CodeShowcaseItem, type CodeShowcaseProps, type CursorStyle, DEFAULT_SKILL_AGENTS, FeatureGrid, type FeatureGridItem, type FeatureGridProps, type FeatureItemType, Features, type FeaturesProps, FluidGradient, type FluidGradientProps, Giscus, type GiscusProps, GradientButton, type GradientButtonProps, Grainient, type GrainientProps, GridBackground, type GridBackgroundProps, GridShowcase, type GridShowcaseProps, Hero, type HeroAction, type HeroProps, InstallBanner, type InstallBannerProps, LANDING_GRADIENT_VAR, LANDING_PALETTE_DARK, LANDING_PALETTE_LIGHT, type LandingAction, LandingHero, type LandingHeroAction, type LandingHeroProps, type LandingLinkProps, type LandingLinkRender, type LandingNavigate, type LandingPalette, LandingSection, type LandingSectionProps, LogoMarquee, type LogoMarqueeItem, type LogoMarqueeProps, type SegmentMode, Spotlight, SpotlightCard, type SpotlightCardProps, type SpotlightProps, TypewriterEffect, type TypewriterEffectProps, accentGradient as landingAccentGradient };
@@ -21,6 +21,5 @@ import InstallBanner from "./InstallBanner/InstallBanner.mjs";
21
21
  import LandingHero from "./LandingHero/LandingHero.mjs";
22
22
  import LandingSection from "./LandingSection/LandingSection.mjs";
23
23
  import LogoMarquee from "./LogoMarquee/LogoMarquee.mjs";
24
- import Spline from "./Spline/Spine.mjs";
25
24
  import TypewriterEffect from "./TypewriterEffect/TypewriterEffect.mjs";
26
- export { AgentSkillCard, AuroraBackground, BentoCard, BentoGrid, BottomGradientButton, CodeShowcase, DEFAULT_SKILL_AGENTS, FeatureGrid, Features, FluidGradient, Giscus, GradientButton, Grainient, GridBackground, GridShowcase, Hero, InstallBanner, LANDING_GRADIENT_VAR, LANDING_PALETTE_DARK, LANDING_PALETTE_LIGHT, LandingHero, LandingSection, LogoMarquee, Spline, Spotlight, SpotlightCard, TypewriterEffect, accentGradient as landingAccentGradient };
25
+ export { AgentSkillCard, AuroraBackground, BentoCard, BentoGrid, BottomGradientButton, CodeShowcase, DEFAULT_SKILL_AGENTS, FeatureGrid, Features, FluidGradient, Giscus, GradientButton, Grainient, GridBackground, GridShowcase, Hero, InstallBanner, LANDING_GRADIENT_VAR, LANDING_PALETTE_DARK, LANDING_PALETTE_LIGHT, LandingHero, LandingSection, LogoMarquee, Spotlight, SpotlightCard, TypewriterEffect, accentGradient as landingAccentGradient };
@@ -6,6 +6,4 @@ import LobeHubText from "./LobeHubText/index.mjs";
6
6
  import Logo3d from "./Logo3d/index.mjs";
7
7
  import _default from "./LogoFlat/index.mjs";
8
8
  import icons_default from "./LogoMono/index.mjs";
9
- import LogoThree, { LogoThreeProps } from "./LogoThree/index.mjs";
10
- import LogoSpline, { LogoSplineProps } from "./LogoThree/LogoSpline.mjs";
11
- export { BrandLoading, type BrandLoadingProps, LobeChat, type LobeChatProps, LobeChatText, LobeHub, type LobeHubProps, LobeHubText, Logo3d, _default as LogoFlat, icons_default as LogoMono, LogoSpline, type LogoSplineProps, LogoThree, type LogoThreeProps };
9
+ export { BrandLoading, type BrandLoadingProps, LobeChat, type LobeChatProps, LobeChatText, LobeHub, type LobeHubProps, LobeHubText, Logo3d, _default as LogoFlat, icons_default as LogoMono };
@@ -6,6 +6,4 @@ import icons_default from "./LogoMono/index.mjs";
6
6
  import LobeChat from "./LobeChat/index.mjs";
7
7
  import LobeHubText from "./LobeHubText/index.mjs";
8
8
  import LobeHub from "./LobeHub/index.mjs";
9
- import LogoThree from "./LogoThree/index.mjs";
10
- import LogoSpline from "./LogoThree/LogoSpline.mjs";
11
- export { BrandLoading, LobeChat, LobeChatText, LobeHub, LobeHubText, Logo3d, LogoFlat_default as LogoFlat, icons_default as LogoMono, LogoSpline, LogoThree };
9
+ export { BrandLoading, LobeChat, LobeChatText, LobeHub, LobeHubText, Logo3d, LogoFlat_default as LogoFlat, icons_default as LogoMono };
@@ -2,7 +2,7 @@ import Icon from "../../Icon/Icon.mjs";
2
2
  import Center from "../../Flex/Center.mjs";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { Loader2 } from "lucide-react";
5
- //#region src/brand/LogoThree/Loading.tsx
5
+ //#region src/spline/LogoThree/Loading.tsx
6
6
  const Loading = ({ size = 32 }) => {
7
7
  return /* @__PURE__ */ jsx(Center, {
8
8
  height: "100%",
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Loading.mjs","names":[],"sources":["../../../src/spline/LogoThree/Loading.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\nimport { type FC } from 'react';\n\nimport { Center } from '@/Flex';\nimport Icon from '@/Icon';\n\nconst Loading: FC<{ size?: number }> = ({ size = 32 }) => {\n return (\n <Center height={'100%'} justify={'center'} style={{ position: 'absolute' }} width={'100%'}>\n <Icon spin icon={Loader2} size={size} />\n </Center>\n );\n};\n\nexport default Loading;\n"],"mappings":";;;;;AAMA,MAAM,WAAkC,EAAE,OAAO,SAAS;CACxD,OACE,oBAAC,QAAD;EAAQ,QAAQ;EAAQ,SAAS;EAAU,OAAO,EAAE,UAAU,WAAW;EAAG,OAAO;EACjF,UAAA,oBAAC,MAAD;GAAM,MAAA;GAAK,MAAM;GAAe;EAAO,CAAA;CACjC,CAAA;AAEZ"}
@@ -1,7 +1,7 @@
1
- import { SplineProps } from "../../awesome/Spline/type.mjs";
2
- import "../../awesome/Spline/index.mjs";
1
+ import { SplineProps } from "../Spline/type.mjs";
2
+ import "../Spline/index.mjs";
3
3
  import { CSSProperties } from "react";
4
- //#region src/brand/LogoThree/LogoSpline.d.ts
4
+ //#region src/spline/LogoThree/LogoSpline.d.ts
5
5
  export interface LogoSplineProps extends Partial<SplineProps> {
6
6
  className?: string;
7
7
  height?: number | string;
@@ -1,9 +1,9 @@
1
1
  import { useThemeMode } from "../../styles/theme/scope.mjs";
2
- import Spline from "../../awesome/Spline/Spine.mjs";
2
+ import Spline from "../Spline/Spine.mjs";
3
3
  import Loading from "./Loading.mjs";
4
4
  import { memo, useState } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
- //#region src/brand/LogoThree/LogoSpline.tsx
6
+ //#region src/spline/LogoThree/LogoSpline.tsx
7
7
  const LIGHT = "https://hub-apac-1.lobeobjects.space/light.splinecode";
8
8
  const DARK = "https://hub-apac-1.lobeobjects.space/dark.splinecode";
9
9
  const LogoSpline = memo(({ className, style, width, height, onLoad, ...rest }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"LogoSpline.mjs","names":[],"sources":["../../../src/brand/LogoThree/LogoSpline.tsx"],"sourcesContent":["import { type CSSProperties, memo, useState } from 'react';\n\nimport Spline, { type SplineProps } from '@/awesome/Spline';\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport Loading from './Loading';\n\nconst LIGHT = 'https://hub-apac-1.lobeobjects.space/light.splinecode';\nconst DARK = 'https://hub-apac-1.lobeobjects.space/dark.splinecode';\n\nexport interface LogoSplineProps extends Partial<SplineProps> {\n className?: string;\n height?: number | string;\n style?: CSSProperties;\n width?: number | string;\n}\n\nconst LogoSpline = memo<LogoSplineProps>(({ className, style, width, height, onLoad, ...rest }) => {\n const { isDarkMode } = useThemeMode();\n const [loading, setLoading] = useState(true);\n return (\n <div className={className} style={{ height, position: 'relative', width, ...style }}>\n {loading && <Loading />}\n <Spline\n scene={isDarkMode ? DARK : LIGHT}\n onLoad={(splineApp) => {\n setLoading(false);\n onLoad?.(splineApp);\n }}\n {...rest}\n />\n </div>\n );\n});\n\nexport default LogoSpline;\n"],"mappings":";;;;;;AAOA,MAAM,QAAQ;AACd,MAAM,OAAO;AASb,MAAM,aAAa,MAAuB,EAAE,WAAW,OAAO,OAAO,QAAQ,QAAQ,GAAG,WAAW;CACjG,MAAM,EAAE,eAAe,aAAa;CACpC,MAAM,CAAC,SAAS,cAAc,SAAS,IAAI;CAC3C,OACE,qBAAC,OAAD;EAAgB;EAAW,OAAO;GAAE;GAAQ,UAAU;GAAY;GAAO,GAAG;EAAM;EAAlF,UAAA,CACG,WAAW,oBAAC,SAAD,CAAU,CAAA,GACtB,oBAAC,QAAD;GACE,OAAO,aAAa,OAAO;GAC3B,SAAS,cAAc;IACrB,WAAW,KAAK;IAChB,SAAS,SAAS;GACpB;GACA,GAAI;EACL,CAAA,CACE;;AAET,CAAC"}
1
+ {"version":3,"file":"LogoSpline.mjs","names":[],"sources":["../../../src/spline/LogoThree/LogoSpline.tsx"],"sourcesContent":["import { type CSSProperties, memo, useState } from 'react';\n\nimport Spline, { type SplineProps } from '@/spline/Spline';\nimport { useThemeMode } from '@/styles/theme/scope';\n\nimport Loading from './Loading';\n\nconst LIGHT = 'https://hub-apac-1.lobeobjects.space/light.splinecode';\nconst DARK = 'https://hub-apac-1.lobeobjects.space/dark.splinecode';\n\nexport interface LogoSplineProps extends Partial<SplineProps> {\n className?: string;\n height?: number | string;\n style?: CSSProperties;\n width?: number | string;\n}\n\nconst LogoSpline = memo<LogoSplineProps>(({ className, style, width, height, onLoad, ...rest }) => {\n const { isDarkMode } = useThemeMode();\n const [loading, setLoading] = useState(true);\n return (\n <div className={className} style={{ height, position: 'relative', width, ...style }}>\n {loading && <Loading />}\n <Spline\n scene={isDarkMode ? DARK : LIGHT}\n onLoad={(splineApp) => {\n setLoading(false);\n onLoad?.(splineApp);\n }}\n {...rest}\n />\n </div>\n );\n});\n\nexport default LogoSpline;\n"],"mappings":";;;;;;AAOA,MAAM,QAAQ;AACd,MAAM,OAAO;AASb,MAAM,aAAa,MAAuB,EAAE,WAAW,OAAO,OAAO,QAAQ,QAAQ,GAAG,WAAW;CACjG,MAAM,EAAE,eAAe,aAAa;CACpC,MAAM,CAAC,SAAS,cAAc,SAAS,IAAI;CAC3C,OACE,qBAAC,OAAD;EAAgB;EAAW,OAAO;GAAE;GAAQ,UAAU;GAAY;GAAO,GAAG;EAAM;EAAlF,UAAA,CACG,WAAW,oBAAC,SAAD,CAAU,CAAA,GACtB,oBAAC,QAAD;GACE,OAAO,aAAa,OAAO;GAC3B,SAAS,cAAc;IACrB,WAAW,KAAK;IAChB,SAAS,SAAS;GACpB;GACA,GAAI;EACL,CAAA,CACE;;AAET,CAAC"}
@@ -1,7 +1,7 @@
1
- import { SplineProps } from "../../awesome/Spline/type.mjs";
2
- import "../../awesome/Spline/index.mjs";
1
+ import { SplineProps } from "../Spline/type.mjs";
2
+ import "../Spline/index.mjs";
3
3
  import { CSSProperties } from "react";
4
- //#region src/brand/LogoThree/index.d.ts
4
+ //#region src/spline/LogoThree/index.d.ts
5
5
  export interface LogoThreeProps extends Partial<SplineProps> {
6
6
  className?: string;
7
7
  size?: number;
@@ -2,10 +2,10 @@
2
2
  import { useCdnFn } from "../../ConfigProvider/index.mjs";
3
3
  import FlexBasic_default from "../../Flex/FlexBasic.mjs";
4
4
  import Img from "../../Img/index.mjs";
5
- import Spline from "../../awesome/Spline/Spine.mjs";
5
+ import Spline from "../Spline/Spine.mjs";
6
6
  import { memo, useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
- //#region src/brand/LogoThree/index.tsx
8
+ //#region src/spline/LogoThree/index.tsx
9
9
  const LOGO_3D = {
10
10
  path: "assets/logo-3d.webp",
11
11
  pkg: "@lobehub/assets-logo",
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["Flexbox"],"sources":["../../../src/brand/LogoThree/index.tsx"],"sourcesContent":["'use client';\n\nimport { type CSSProperties, memo, useState } from 'react';\n\nimport Spline, { type SplineProps } from '@/awesome/Spline';\nimport { useCdnFn } from '@/ConfigProvider';\nimport { Flexbox } from '@/Flex';\nimport Img from '@/Img';\n\nconst LOGO_3D = {\n path: 'assets/logo-3d.webp',\n pkg: '@lobehub/assets-logo',\n version: '1.2.0',\n};\n\nexport interface LogoThreeProps extends Partial<SplineProps> {\n className?: string;\n size?: number;\n style?: CSSProperties;\n}\n\nconst LogoThree = memo<LogoThreeProps>(({ className, style, size = 128, onLoad, ...rest }) => {\n const genCdnUrl = useCdnFn();\n const [loading, setLoading] = useState(true);\n return (\n <Flexbox\n align={'center'}\n className={className}\n flex={'none'}\n justify={'center'}\n style={{ height: size, overflow: 'hidden', position: 'relative', width: size, ...style }}\n >\n {loading && (\n <Img\n alt={'logo'}\n height={size * 0.75}\n src={genCdnUrl(LOGO_3D)}\n style={{ position: 'absolute' }}\n width={size * 0.75}\n />\n )}\n <Spline\n scene={'https://hub-apac-1.lobeobjects.space/logo.splinecode'}\n style={{\n flex: 'none',\n height: size,\n width: size,\n }}\n onLoad={(splineApp) => {\n setLoading(false);\n onLoad?.(splineApp);\n }}\n {...rest}\n />\n </Flexbox>\n );\n});\n\nLogoThree.displayName = 'LobeHubLogoThree';\n\nexport default LogoThree;\n"],"mappings":";;;;;;;;AASA,MAAM,UAAU;CACd,MAAM;CACN,KAAK;CACL,SAAS;AACX;AAQA,MAAM,YAAY,MAAsB,EAAE,WAAW,OAAO,OAAO,KAAK,QAAQ,GAAG,WAAW;CAC5F,MAAM,YAAY,SAAS;CAC3B,MAAM,CAAC,SAAS,cAAc,SAAS,IAAI;CAC3C,OACE,qBAACA,mBAAD;EACE,OAAO;EACI;EACX,MAAM;EACN,SAAS;EACT,OAAO;GAAE,QAAQ;GAAM,UAAU;GAAU,UAAU;GAAY,OAAO;GAAM,GAAG;EAAM;EALzF,UAAA,CAOG,WACC,oBAAC,KAAD;GACE,KAAK;GACL,QAAQ,OAAO;GACf,KAAK,UAAU,OAAO;GACtB,OAAO,EAAE,UAAU,WAAW;GAC9B,OAAO,OAAO;EACf,CAAA,GAEH,oBAAC,QAAD;GACE,OAAO;GACP,OAAO;IACL,MAAM;IACN,QAAQ;IACR,OAAO;GACT;GACA,SAAS,cAAc;IACrB,WAAW,KAAK;IAChB,SAAS,SAAS;GACpB;GACA,GAAI;EACL,CAAA,CACM;;AAEb,CAAC;AAED,UAAU,cAAc"}
1
+ {"version":3,"file":"index.mjs","names":["Flexbox"],"sources":["../../../src/spline/LogoThree/index.tsx"],"sourcesContent":["'use client';\n\nimport { type CSSProperties, memo, useState } from 'react';\n\nimport { useCdnFn } from '@/ConfigProvider';\nimport { Flexbox } from '@/Flex';\nimport Img from '@/Img';\nimport Spline, { type SplineProps } from '@/spline/Spline';\n\nconst LOGO_3D = {\n path: 'assets/logo-3d.webp',\n pkg: '@lobehub/assets-logo',\n version: '1.2.0',\n};\n\nexport interface LogoThreeProps extends Partial<SplineProps> {\n className?: string;\n size?: number;\n style?: CSSProperties;\n}\n\nconst LogoThree = memo<LogoThreeProps>(({ className, style, size = 128, onLoad, ...rest }) => {\n const genCdnUrl = useCdnFn();\n const [loading, setLoading] = useState(true);\n return (\n <Flexbox\n align={'center'}\n className={className}\n flex={'none'}\n justify={'center'}\n style={{ height: size, overflow: 'hidden', position: 'relative', width: size, ...style }}\n >\n {loading && (\n <Img\n alt={'logo'}\n height={size * 0.75}\n src={genCdnUrl(LOGO_3D)}\n style={{ position: 'absolute' }}\n width={size * 0.75}\n />\n )}\n <Spline\n scene={'https://hub-apac-1.lobeobjects.space/logo.splinecode'}\n style={{\n flex: 'none',\n height: size,\n width: size,\n }}\n onLoad={(splineApp) => {\n setLoading(false);\n onLoad?.(splineApp);\n }}\n {...rest}\n />\n </Flexbox>\n );\n});\n\nLogoThree.displayName = 'LobeHubLogoThree';\n\nexport default LogoThree;\n"],"mappings":";;;;;;;;AASA,MAAM,UAAU;CACd,MAAM;CACN,KAAK;CACL,SAAS;AACX;AAQA,MAAM,YAAY,MAAsB,EAAE,WAAW,OAAO,OAAO,KAAK,QAAQ,GAAG,WAAW;CAC5F,MAAM,YAAY,SAAS;CAC3B,MAAM,CAAC,SAAS,cAAc,SAAS,IAAI;CAC3C,OACE,qBAACA,mBAAD;EACE,OAAO;EACI;EACX,MAAM;EACN,SAAS;EACT,OAAO;GAAE,QAAQ;GAAM,UAAU;GAAU,UAAU;GAAY,OAAO;GAAM,GAAG;EAAM;EALzF,UAAA,CAOG,WACC,oBAAC,KAAD;GACE,KAAK;GACL,QAAQ,OAAO;GACf,KAAK,UAAU,OAAO;GACtB,OAAO,EAAE,UAAU,WAAW;GAC9B,OAAO,OAAO;EACf,CAAA,GAEH,oBAAC,QAAD;GACE,OAAO;GACP,OAAO;IACL,MAAM;IACN,QAAQ;IACR,OAAO;GACT;GACA,SAAS,cAAc;IACrB,WAAW,KAAK;IAChB,SAAS,SAAS;GACpB;GACA,GAAI;EACL,CAAA,CACM;;AAEb,CAAC;AAED,UAAU,cAAc"}
@@ -2,7 +2,7 @@ import { mergeRefs } from "../../utils/mergeRefs.mjs";
2
2
  import { memo, useEffect, useMemo, useRef, useState } from "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { debounce } from "es-toolkit/compat";
5
- //#region src/awesome/Spline/ParentSize.tsx
5
+ //#region src/spline/Spline/ParentSize.tsx
6
6
  const defaultIgnoreDimensions = [];
7
7
  const defaultParentSizeStyles = {
8
8
  height: "100%",
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ParentSize.mjs","names":[],"sources":["../../../src/spline/Spline/ParentSize.tsx"],"sourcesContent":["import { debounce } from 'es-toolkit/compat';\nimport {\n type CSSProperties,\n memo,\n type ReactNode,\n type Ref,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { mergeRefs } from '@/utils/mergeRefs';\n\ninterface ResizeObserverCallback {\n (entries: ResizeObserverEntry[], observer: ResizeObserver): void;\n}\n\ninterface ResizeObserverPolyfill {\n new (callback: ResizeObserverCallback): ResizeObserver;\n}\n\n// @TODO remove when upgraded to TS 4 which has its own declaration\ninterface PrivateWindow {\n ResizeObserver: ResizeObserverPolyfill;\n}\n\nexport interface ParentSizeProps {\n /** Child render function `({ width, height, top, left, ref, resize }) => ReactNode`. */\n children: (\n args: {\n ref: HTMLDivElement | null;\n resize: (state: ParentSizeState) => void;\n } & ParentSizeState,\n ) => ReactNode;\n /** Optional `className` to add to the parent `div` wrapper used for size measurement. */\n className?: string;\n /** Child render updates upon resize are delayed until `debounceTime` milliseconds _after_ the last resize event is observed. */\n debounceTime?: number;\n /** Optional flag to toggle leading debounce calls. When set to true this will ensure that the component always renders immediately. (defaults to true) */\n enableDebounceLeadingCall?: boolean;\n /** Optional dimensions provided won't trigger a state change when changed. */\n ignoreDimensions?: keyof ParentSizeState | (keyof ParentSizeState)[];\n /** Optional `style` object to apply to the parent `div` wrapper used for size measurement. */\n parentSizeStyles?: CSSProperties;\n ref?: Ref<HTMLDivElement>;\n /** Optionally inject a ResizeObserver polyfill, else this *must* be globally available. */\n resizeObserverPolyfill?: ResizeObserverPolyfill;\n}\n\ntype ParentSizeState = {\n height: number;\n left: number;\n top: number;\n width: number;\n};\n\nexport type ParentSizeProvidedProps = ParentSizeState;\n\nconst defaultIgnoreDimensions: ParentSizeProps['ignoreDimensions'] = [];\nconst defaultParentSizeStyles = { height: '100%', width: '100%' };\n\nconst ParentSize = memo<ParentSizeProps>(\n ({\n ref,\n className,\n children,\n debounceTime = 300,\n ignoreDimensions = defaultIgnoreDimensions,\n parentSizeStyles,\n enableDebounceLeadingCall = true,\n resizeObserverPolyfill,\n ...restProps\n }) => {\n const target = useRef<HTMLDivElement | null>(null);\n const animationFrameID = useRef(0);\n\n const [state, setState] = useState<ParentSizeState>({\n height: 0,\n left: 0,\n top: 0,\n width: 0,\n });\n\n const resize = useMemo(() => {\n const normalized = Array.isArray(ignoreDimensions) ? ignoreDimensions : [ignoreDimensions];\n\n return debounce(\n (incoming: ParentSizeState) => {\n setState((existing) => {\n const stateKeys = Object.keys(existing) as (keyof ParentSizeState)[];\n const keysWithChanges = stateKeys.filter((key) => existing[key] !== incoming[key]);\n const shouldBail = keysWithChanges.every((key) => normalized.includes(key));\n\n return shouldBail ? existing : incoming;\n });\n },\n debounceTime,\n { leading: enableDebounceLeadingCall },\n );\n }, [debounceTime, enableDebounceLeadingCall, ignoreDimensions]);\n\n useEffect(() => {\n const LocalResizeObserver =\n resizeObserverPolyfill || (window as unknown as PrivateWindow).ResizeObserver;\n\n const observer = new LocalResizeObserver((entries) => {\n for (const entry of entries) {\n const { left, top, width, height } = entry?.contentRect ?? {};\n animationFrameID.current = window.requestAnimationFrame(() => {\n resize({ height, left, top, width });\n });\n }\n });\n if (target.current) observer.observe(target.current);\n\n return () => {\n window.cancelAnimationFrame(animationFrameID.current);\n observer.disconnect();\n resize.cancel();\n };\n }, [resize, resizeObserverPolyfill]);\n\n return (\n <div\n className={className}\n ref={mergeRefs<HTMLDivElement>([ref, target])}\n style={{ ...defaultParentSizeStyles, ...parentSizeStyles }}\n {...restProps}\n >\n {children({\n ...state,\n ref: target.current,\n resize,\n })}\n </div>\n );\n },\n);\n\nexport default ParentSize;\n"],"mappings":";;;;;AA2DA,MAAM,0BAA+D,CAAC;AACtE,MAAM,0BAA0B;CAAE,QAAQ;CAAQ,OAAO;AAAO;AAEhE,MAAM,aAAa,MAChB,EACC,KACA,WACA,UACA,eAAe,KACf,mBAAmB,yBACnB,kBACA,4BAA4B,MAC5B,wBACA,GAAG,gBACC;CACJ,MAAM,SAAS,OAA8B,IAAI;CACjD,MAAM,mBAAmB,OAAO,CAAC;CAEjC,MAAM,CAAC,OAAO,YAAY,SAA0B;EAClD,QAAQ;EACR,MAAM;EACN,KAAK;EACL,OAAO;CACT,CAAC;CAED,MAAM,SAAS,cAAc;EAC3B,MAAM,aAAa,MAAM,QAAQ,gBAAgB,IAAI,mBAAmB,CAAC,gBAAgB;EAEzF,OAAO,UACJ,aAA8B;GAC7B,UAAU,aAAa;IAKrB,OAJkB,OAAO,KAAK,QACE,CAAC,CAAC,QAAQ,QAAQ,SAAS,SAAS,SAAS,IAC5C,CAAC,CAAC,OAAO,QAAQ,WAAW,SAAS,GAAG,CAEzD,IAAI,WAAW;GACjC,CAAC;EACH,GACA,cACA,EAAE,SAAS,0BAA0B,CACvC;CACF,GAAG;EAAC;EAAc;EAA2B;CAAgB,CAAC;CAE9D,gBAAgB;EAId,MAAM,WAAW,KAFf,0BAA2B,OAAoC,iBAEvB,YAAY;GACpD,KAAK,MAAM,SAAS,SAAS;IAC3B,MAAM,EAAE,MAAM,KAAK,OAAO,WAAW,OAAO,eAAe,CAAC;IAC5D,iBAAiB,UAAU,OAAO,4BAA4B;KAC5D,OAAO;MAAE;MAAQ;MAAM;MAAK;KAAM,CAAC;IACrC,CAAC;GACH;EACF,CAAC;EACD,IAAI,OAAO,SAAS,SAAS,QAAQ,OAAO,OAAO;EAEnD,aAAa;GACX,OAAO,qBAAqB,iBAAiB,OAAO;GACpD,SAAS,WAAW;GACpB,OAAO,OAAO;EAChB;CACF,GAAG,CAAC,QAAQ,sBAAsB,CAAC;CAEnC,OACE,oBAAC,OAAD;EACa;EACX,KAAK,UAA0B,CAAC,KAAK,MAAM,CAAC;EAC5C,OAAO;GAAE,GAAG;GAAyB,GAAG;EAAiB;EACzD,GAAI;EAEH,UAAA,SAAS;GACR,GAAG;GACH,KAAK,OAAO;GACZ;EACF,CAAC;CACE,CAAA;AAET,CACF"}
@@ -0,0 +1,7 @@
1
+ import { SplineProps } from "./type.mjs";
2
+ import { SPEObject, SplineEvent as SplineEvent$1, SplineEventName } from "@splinetool/runtime";
3
+ //#region src/spline/Spline/Spine.d.ts
4
+ declare const Spline: import("react").NamedExoticComponent<SplineProps>;
5
+ //#endregion
6
+ export { type SPEObject, type SplineEvent$1 as SplineEvent, type SplineEventName, Spline as default };
7
+ //# sourceMappingURL=Spine.d.mts.map
@@ -2,8 +2,7 @@
2
2
  import ParentSize from "./ParentSize.mjs";
3
3
  import { memo, useEffect, useRef, useState } from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
- import { Application } from "@splinetool/runtime";
6
- //#region src/awesome/Spline/Spine.tsx
5
+ //#region src/spline/Spline/Spine.tsx
7
6
  const Spline = memo(({ ref, scene, style, onMouseDown, onMouseUp, onMouseHover, onKeyDown, onKeyUp, onStart, onLookAt, onFollow, onWheel, onLoad, renderOnDemand = true, ...props }) => {
8
7
  const canvasRef = useRef(null);
9
8
  const [isLoading, setIsLoading] = useState(true);
@@ -15,6 +14,9 @@ const Spline = memo(({ ref, scene, style, onMouseDown, onMouseUp, onMouseHover,
15
14
  };
16
15
  useEffect(() => {
17
16
  setIsLoading(true);
17
+ const canvas = canvasRef.current;
18
+ if (!canvas) return;
19
+ let disposed = false;
18
20
  let speApp;
19
21
  const events = [
20
22
  {
@@ -54,11 +56,14 @@ const Spline = memo(({ ref, scene, style, onMouseDown, onMouseUp, onMouseHover,
54
56
  name: "scroll"
55
57
  }
56
58
  ];
57
- if (canvasRef.current) {
58
- speApp = new Application(canvasRef.current, { renderOnDemand });
59
+ import("@splinetool/runtime").then((runtime) => {
60
+ if (disposed) return;
61
+ speApp = new runtime.Application(canvas, { renderOnDemand });
59
62
  init(speApp, events);
60
- }
63
+ });
61
64
  return () => {
65
+ disposed = true;
66
+ if (!speApp) return;
62
67
  for (const event of events) if (event.cb) speApp.removeEventListener(event.name, event.cb);
63
68
  speApp.dispose();
64
69
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Spine.mjs","names":[],"sources":["../../../src/spline/Spline/Spine.tsx"],"sourcesContent":["'use client';\n\nimport type { Application, SplineEvent, SplineEventName } from '@splinetool/runtime';\nimport { memo, useEffect, useRef, useState } from 'react';\n\nimport ParentSize from './ParentSize';\nimport { type SplineProps } from './type';\n\nconst Spline = memo<SplineProps>(\n ({\n ref,\n scene,\n style,\n onMouseDown,\n onMouseUp,\n onMouseHover,\n onKeyDown,\n onKeyUp,\n onStart,\n onLookAt,\n onFollow,\n onWheel,\n onLoad,\n renderOnDemand = true,\n ...props\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const init = async (\n speApp: Application,\n events: {\n cb?: (e: SplineEvent) => void;\n name: SplineEventName;\n }[],\n ) => {\n await speApp.load(scene);\n\n for (const event of events) {\n if (event.cb) {\n speApp.addEventListener(event.name, event.cb);\n }\n }\n\n setIsLoading(false);\n onLoad?.(speApp);\n };\n\n // Initialize runtime when component is mounted\n useEffect(() => {\n setIsLoading(true);\n\n const canvas = canvasRef.current;\n if (!canvas) return;\n\n let disposed = false;\n let speApp: Application | undefined;\n const events: {\n cb?: (e: SplineEvent) => void;\n name: SplineEventName;\n }[] = [\n {\n cb: onMouseDown,\n name: 'mouseDown',\n },\n {\n cb: onMouseUp,\n name: 'mouseUp',\n },\n {\n cb: onMouseHover,\n name: 'mouseHover',\n },\n {\n cb: onKeyDown,\n name: 'keyDown',\n },\n {\n cb: onKeyUp,\n name: 'keyUp',\n },\n {\n cb: onStart,\n name: 'start',\n },\n {\n cb: onLookAt,\n name: 'lookAt',\n },\n {\n cb: onFollow,\n name: 'follow',\n },\n {\n cb: onWheel,\n name: 'scroll',\n },\n ];\n\n void import('@splinetool/runtime').then((runtime) => {\n if (disposed) return;\n speApp = new runtime.Application(canvas, { renderOnDemand });\n void init(speApp, events);\n });\n\n return () => {\n disposed = true;\n if (!speApp) return;\n for (const event of events) {\n if (event.cb) {\n speApp.removeEventListener(event.name, event.cb);\n }\n }\n speApp.dispose();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [scene]);\n\n return (\n <ParentSize debounceTime={50} parentSizeStyles={style} ref={ref} {...props}>\n {() => {\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: isLoading ? 'none' : 'block',\n }}\n />\n );\n }}\n </ParentSize>\n );\n },\n);\n\nSpline.displayName = 'Spline';\n\nexport default Spline;\n\nexport type { SPEObject, SplineEvent, SplineEventName } from '@splinetool/runtime';\n"],"mappings":";;;;;AAQA,MAAM,SAAS,MACZ,EACC,KACA,OACA,OACA,aACA,WACA,cACA,WACA,SACA,SACA,UACA,UACA,SACA,QACA,iBAAiB,MACjB,GAAG,YACC;CACJ,MAAM,YAAY,OAA0B,IAAI;CAChD,MAAM,CAAC,WAAW,gBAAgB,SAAS,IAAI;CAE/C,MAAM,OAAO,OACX,QACA,WAIG;EACH,MAAM,OAAO,KAAK,KAAK;EAEvB,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,IACR,OAAO,iBAAiB,MAAM,MAAM,MAAM,EAAE;EAIhD,aAAa,KAAK;EAClB,SAAS,MAAM;CACjB;CAGA,gBAAgB;EACd,aAAa,IAAI;EAEjB,MAAM,SAAS,UAAU;EACzB,IAAI,CAAC,QAAQ;EAEb,IAAI,WAAW;EACf,IAAI;EACJ,MAAM,SAGA;GACJ;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;EACF;EAEA,OAAY,sBAAsB,CAAC,MAAM,YAAY;GACnD,IAAI,UAAU;GACd,SAAS,IAAI,QAAQ,YAAY,QAAQ,EAAE,eAAe,CAAC;GAC3D,KAAU,QAAQ,MAAM;EAC1B,CAAC;EAED,aAAa;GACX,WAAW;GACX,IAAI,CAAC,QAAQ;GACb,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,IACR,OAAO,oBAAoB,MAAM,MAAM,MAAM,EAAE;GAGnD,OAAO,QAAQ;EACjB;CAEF,GAAG,CAAC,KAAK,CAAC;CAEV,OACE,oBAAC,YAAD;EAAY,cAAc;EAAI,kBAAkB;EAAY;EAAK,GAAI;EAC5D,gBAAA;GACL,OACE,oBAAC,UAAD;IACE,KAAK;IACL,OAAO,EACL,SAAS,YAAY,SAAS,QAChC;GACD,CAAA;EAEL;CACU,CAAA;AAEhB,CACF;AAEA,OAAO,cAAc"}
@@ -1,6 +1,6 @@
1
1
  import { HTMLAttributes, Ref } from "react";
2
2
  import { Application, SplineEvent } from "@splinetool/runtime";
3
- //#region src/awesome/Spline/type.d.ts
3
+ //#region src/spline/Spline/type.d.ts
4
4
  export interface SplineProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onLoad' | 'onMouseDown' | 'onMouseUp' | 'onMouseHover' | 'onKeyDown' | 'onKeyUp' | 'onWheel'> {
5
5
  onFollow?: (e: SplineEvent) => void;
6
6
  onKeyDown?: (e: SplineEvent) => void;
@@ -0,0 +1,6 @@
1
+ import { SplineProps } from "./Spline/type.mjs";
2
+ import Spline, { SPEObject, SplineEvent, SplineEventName } from "./Spline/Spine.mjs";
3
+ import "./Spline/index.mjs";
4
+ import LogoThree, { LogoThreeProps } from "./LogoThree/index.mjs";
5
+ import LogoSpline, { LogoSplineProps } from "./LogoThree/LogoSpline.mjs";
6
+ export { LogoSpline, type LogoSplineProps, LogoThree, type LogoThreeProps, type SPEObject, Spline, type SplineEvent, type SplineEventName, type SplineProps };
@@ -0,0 +1 @@
1
+ export * from './index.d.mts';
@@ -0,0 +1 @@
1
+ export * from './index.mjs';
@@ -0,0 +1,4 @@
1
+ import Spline from "./Spline/Spine.mjs";
2
+ import LogoThree from "./LogoThree/index.mjs";
3
+ import LogoSpline from "./LogoThree/LogoSpline.mjs";
4
+ export { LogoSpline, LogoThree, Spline };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/ui",
3
- "version": "6.0.3",
3
+ "version": "6.0.5",
4
4
  "description": "Lobe UI is an open-source UI component library for building AIGC web apps",
5
5
  "keywords": [
6
6
  "lobehub",
@@ -49,6 +49,10 @@
49
49
  "types": "./es/brand/index.d.mts",
50
50
  "import": "./es/brand/index.mjs"
51
51
  },
52
+ "./spline": {
53
+ "types": "./es/spline/index.d.mts",
54
+ "import": "./es/spline/index.mjs"
55
+ },
52
56
  "./chat": {
53
57
  "types": "./es/chat/index.d.mts",
54
58
  "import": "./es/chat/index.mjs"
@@ -149,7 +153,6 @@
149
153
  "@shikijs/core": "^4.5.0",
150
154
  "@shikijs/stream": "^4.5.0",
151
155
  "@shikijs/transformers": "^4.5.0",
152
- "@splinetool/runtime": "1.12.98",
153
156
  "@stylexjs/stylex": "0.19.1",
154
157
  "@tanstack/form-core": "^1.33.5",
155
158
  "@tanstack/react-table": "^9.2.8",
@@ -188,10 +191,16 @@
188
191
  "peerDependencies": {
189
192
  "@lobehub/fluent-emoji": "^5.0.0-beta.1",
190
193
  "@lobehub/icons": "^6.0.0-beta.1",
194
+ "@splinetool/runtime": "^1.12.0",
191
195
  "motion": "^13.0.0 || ^14.0.0",
192
196
  "react": "^19.0.0",
193
197
  "react-dom": "^19.0.0"
194
198
  },
199
+ "peerDependenciesMeta": {
200
+ "@splinetool/runtime": {
201
+ "optional": true
202
+ }
203
+ },
195
204
  "packageManager": "pnpm@12.3.4+sha512.961aa41fb077da3a04a441d9f8e15ebc0c96da8ef710b2eb67bf9ee7cb0610eabd48f1fd85f51cffe73846785fa0f87c56a3a872a1d893f8446741b5cce45457",
196
205
  "engines": {
197
206
  "node": ">=22.22.0"
@@ -1 +0,0 @@
1
- {"version":3,"file":"ParentSize.mjs","names":[],"sources":["../../../src/awesome/Spline/ParentSize.tsx"],"sourcesContent":["import { debounce } from 'es-toolkit/compat';\nimport {\n type CSSProperties,\n memo,\n type ReactNode,\n type Ref,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\n\nimport { mergeRefs } from '@/utils/mergeRefs';\n\ninterface ResizeObserverCallback {\n (entries: ResizeObserverEntry[], observer: ResizeObserver): void;\n}\n\ninterface ResizeObserverPolyfill {\n new (callback: ResizeObserverCallback): ResizeObserver;\n}\n\n// @TODO remove when upgraded to TS 4 which has its own declaration\ninterface PrivateWindow {\n ResizeObserver: ResizeObserverPolyfill;\n}\n\nexport interface ParentSizeProps {\n /** Child render function `({ width, height, top, left, ref, resize }) => ReactNode`. */\n children: (\n args: {\n ref: HTMLDivElement | null;\n resize: (state: ParentSizeState) => void;\n } & ParentSizeState,\n ) => ReactNode;\n /** Optional `className` to add to the parent `div` wrapper used for size measurement. */\n className?: string;\n /** Child render updates upon resize are delayed until `debounceTime` milliseconds _after_ the last resize event is observed. */\n debounceTime?: number;\n /** Optional flag to toggle leading debounce calls. When set to true this will ensure that the component always renders immediately. (defaults to true) */\n enableDebounceLeadingCall?: boolean;\n /** Optional dimensions provided won't trigger a state change when changed. */\n ignoreDimensions?: keyof ParentSizeState | (keyof ParentSizeState)[];\n /** Optional `style` object to apply to the parent `div` wrapper used for size measurement. */\n parentSizeStyles?: CSSProperties;\n ref?: Ref<HTMLDivElement>;\n /** Optionally inject a ResizeObserver polyfill, else this *must* be globally available. */\n resizeObserverPolyfill?: ResizeObserverPolyfill;\n}\n\ntype ParentSizeState = {\n height: number;\n left: number;\n top: number;\n width: number;\n};\n\nexport type ParentSizeProvidedProps = ParentSizeState;\n\nconst defaultIgnoreDimensions: ParentSizeProps['ignoreDimensions'] = [];\nconst defaultParentSizeStyles = { height: '100%', width: '100%' };\n\nconst ParentSize = memo<ParentSizeProps>(\n ({\n ref,\n className,\n children,\n debounceTime = 300,\n ignoreDimensions = defaultIgnoreDimensions,\n parentSizeStyles,\n enableDebounceLeadingCall = true,\n resizeObserverPolyfill,\n ...restProps\n }) => {\n const target = useRef<HTMLDivElement | null>(null);\n const animationFrameID = useRef(0);\n\n const [state, setState] = useState<ParentSizeState>({\n height: 0,\n left: 0,\n top: 0,\n width: 0,\n });\n\n const resize = useMemo(() => {\n const normalized = Array.isArray(ignoreDimensions) ? ignoreDimensions : [ignoreDimensions];\n\n return debounce(\n (incoming: ParentSizeState) => {\n setState((existing) => {\n const stateKeys = Object.keys(existing) as (keyof ParentSizeState)[];\n const keysWithChanges = stateKeys.filter((key) => existing[key] !== incoming[key]);\n const shouldBail = keysWithChanges.every((key) => normalized.includes(key));\n\n return shouldBail ? existing : incoming;\n });\n },\n debounceTime,\n { leading: enableDebounceLeadingCall },\n );\n }, [debounceTime, enableDebounceLeadingCall, ignoreDimensions]);\n\n useEffect(() => {\n const LocalResizeObserver =\n resizeObserverPolyfill || (window as unknown as PrivateWindow).ResizeObserver;\n\n const observer = new LocalResizeObserver((entries) => {\n for (const entry of entries) {\n const { left, top, width, height } = entry?.contentRect ?? {};\n animationFrameID.current = window.requestAnimationFrame(() => {\n resize({ height, left, top, width });\n });\n }\n });\n if (target.current) observer.observe(target.current);\n\n return () => {\n window.cancelAnimationFrame(animationFrameID.current);\n observer.disconnect();\n resize.cancel();\n };\n }, [resize, resizeObserverPolyfill]);\n\n return (\n <div\n className={className}\n ref={mergeRefs<HTMLDivElement>([ref, target])}\n style={{ ...defaultParentSizeStyles, ...parentSizeStyles }}\n {...restProps}\n >\n {children({\n ...state,\n ref: target.current,\n resize,\n })}\n </div>\n );\n },\n);\n\nexport default ParentSize;\n"],"mappings":";;;;;AA2DA,MAAM,0BAA+D,CAAC;AACtE,MAAM,0BAA0B;CAAE,QAAQ;CAAQ,OAAO;AAAO;AAEhE,MAAM,aAAa,MAChB,EACC,KACA,WACA,UACA,eAAe,KACf,mBAAmB,yBACnB,kBACA,4BAA4B,MAC5B,wBACA,GAAG,gBACC;CACJ,MAAM,SAAS,OAA8B,IAAI;CACjD,MAAM,mBAAmB,OAAO,CAAC;CAEjC,MAAM,CAAC,OAAO,YAAY,SAA0B;EAClD,QAAQ;EACR,MAAM;EACN,KAAK;EACL,OAAO;CACT,CAAC;CAED,MAAM,SAAS,cAAc;EAC3B,MAAM,aAAa,MAAM,QAAQ,gBAAgB,IAAI,mBAAmB,CAAC,gBAAgB;EAEzF,OAAO,UACJ,aAA8B;GAC7B,UAAU,aAAa;IAKrB,OAJkB,OAAO,KAAK,QACE,CAAC,CAAC,QAAQ,QAAQ,SAAS,SAAS,SAAS,IAC5C,CAAC,CAAC,OAAO,QAAQ,WAAW,SAAS,GAAG,CAEzD,IAAI,WAAW;GACjC,CAAC;EACH,GACA,cACA,EAAE,SAAS,0BAA0B,CACvC;CACF,GAAG;EAAC;EAAc;EAA2B;CAAgB,CAAC;CAE9D,gBAAgB;EAId,MAAM,WAAW,KAFf,0BAA2B,OAAoC,iBAEvB,YAAY;GACpD,KAAK,MAAM,SAAS,SAAS;IAC3B,MAAM,EAAE,MAAM,KAAK,OAAO,WAAW,OAAO,eAAe,CAAC;IAC5D,iBAAiB,UAAU,OAAO,4BAA4B;KAC5D,OAAO;MAAE;MAAQ;MAAM;MAAK;KAAM,CAAC;IACrC,CAAC;GACH;EACF,CAAC;EACD,IAAI,OAAO,SAAS,SAAS,QAAQ,OAAO,OAAO;EAEnD,aAAa;GACX,OAAO,qBAAqB,iBAAiB,OAAO;GACpD,SAAS,WAAW;GACpB,OAAO,OAAO;EAChB;CACF,GAAG,CAAC,QAAQ,sBAAsB,CAAC;CAEnC,OACE,oBAAC,OAAD;EACa;EACX,KAAK,UAA0B,CAAC,KAAK,MAAM,CAAC;EAC5C,OAAO;GAAE,GAAG;GAAyB,GAAG;EAAiB;EACzD,GAAI;EAEH,UAAA,SAAS;GACR,GAAG;GACH,KAAK,OAAO;GACZ;EACF,CAAC;CACE,CAAA;AAET,CACF"}
@@ -1,7 +0,0 @@
1
- import { SplineProps } from "./type.mjs";
2
- import "@splinetool/runtime";
3
- //#region src/awesome/Spline/Spine.d.ts
4
- declare const Spline: import("react").NamedExoticComponent<SplineProps>;
5
- //#endregion
6
- export { Spline as default };
7
- //# sourceMappingURL=Spine.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Spine.mjs","names":[],"sources":["../../../src/awesome/Spline/Spine.tsx"],"sourcesContent":["'use client';\n\nimport { type SplineEvent, type SplineEventName } from '@splinetool/runtime';\nimport { Application } from '@splinetool/runtime';\nimport { memo, useEffect, useRef, useState } from 'react';\n\nimport ParentSize from './ParentSize';\nimport { type SplineProps } from './type';\n\nconst Spline = memo<SplineProps>(\n ({\n ref,\n scene,\n style,\n onMouseDown,\n onMouseUp,\n onMouseHover,\n onKeyDown,\n onKeyUp,\n onStart,\n onLookAt,\n onFollow,\n onWheel,\n onLoad,\n renderOnDemand = true,\n ...props\n }) => {\n const canvasRef = useRef<HTMLCanvasElement>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const init = async (\n speApp: Application,\n events: {\n cb?: (e: SplineEvent) => void;\n name: SplineEventName;\n }[],\n ) => {\n await speApp.load(scene);\n\n for (const event of events) {\n if (event.cb) {\n speApp.addEventListener(event.name, event.cb);\n }\n }\n\n setIsLoading(false);\n onLoad?.(speApp);\n };\n\n // Initialize runtime when component is mounted\n useEffect(() => {\n setIsLoading(true);\n\n let speApp: Application;\n const events: {\n cb?: (e: SplineEvent) => void;\n name: SplineEventName;\n }[] = [\n {\n cb: onMouseDown,\n name: 'mouseDown',\n },\n {\n cb: onMouseUp,\n name: 'mouseUp',\n },\n {\n cb: onMouseHover,\n name: 'mouseHover',\n },\n {\n cb: onKeyDown,\n name: 'keyDown',\n },\n {\n cb: onKeyUp,\n name: 'keyUp',\n },\n {\n cb: onStart,\n name: 'start',\n },\n {\n cb: onLookAt,\n name: 'lookAt',\n },\n {\n cb: onFollow,\n name: 'follow',\n },\n {\n cb: onWheel,\n name: 'scroll',\n },\n ];\n\n if (canvasRef.current) {\n speApp = new Application(canvasRef.current, { renderOnDemand });\n init(speApp, events);\n }\n\n return () => {\n for (const event of events) {\n if (event.cb) {\n speApp.removeEventListener(event.name, event.cb);\n }\n }\n speApp.dispose();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [scene]);\n\n return (\n <ParentSize debounceTime={50} parentSizeStyles={style} ref={ref} {...props}>\n {() => {\n return (\n <canvas\n ref={canvasRef}\n style={{\n display: isLoading ? 'none' : 'block',\n }}\n />\n );\n }}\n </ParentSize>\n );\n },\n);\n\nSpline.displayName = 'Spline';\n\nexport default Spline;\n\nexport { type SPEObject, type SplineEvent, type SplineEventName } from '@splinetool/runtime';\n"],"mappings":";;;;;;AASA,MAAM,SAAS,MACZ,EACC,KACA,OACA,OACA,aACA,WACA,cACA,WACA,SACA,SACA,UACA,UACA,SACA,QACA,iBAAiB,MACjB,GAAG,YACC;CACJ,MAAM,YAAY,OAA0B,IAAI;CAChD,MAAM,CAAC,WAAW,gBAAgB,SAAS,IAAI;CAE/C,MAAM,OAAO,OACX,QACA,WAIG;EACH,MAAM,OAAO,KAAK,KAAK;EAEvB,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,IACR,OAAO,iBAAiB,MAAM,MAAM,MAAM,EAAE;EAIhD,aAAa,KAAK;EAClB,SAAS,MAAM;CACjB;CAGA,gBAAgB;EACd,aAAa,IAAI;EAEjB,IAAI;EACJ,MAAM,SAGA;GACJ;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;GACA;IACE,IAAI;IACJ,MAAM;GACR;EACF;EAEA,IAAI,UAAU,SAAS;GACrB,SAAS,IAAI,YAAY,UAAU,SAAS,EAAE,eAAe,CAAC;GAC9D,KAAK,QAAQ,MAAM;EACrB;EAEA,aAAa;GACX,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,IACR,OAAO,oBAAoB,MAAM,MAAM,MAAM,EAAE;GAGnD,OAAO,QAAQ;EACjB;CAEF,GAAG,CAAC,KAAK,CAAC;CAEV,OACE,oBAAC,YAAD;EAAY,cAAc;EAAI,kBAAkB;EAAY;EAAK,GAAI;EAC5D,gBAAA;GACL,OACE,oBAAC,UAAD;IACE,KAAK;IACL,OAAO,EACL,SAAS,YAAY,SAAS,QAChC;GACD,CAAA;EAEL;CACU,CAAA;AAEhB,CACF;AAEA,OAAO,cAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Loading.mjs","names":[],"sources":["../../../src/brand/LogoThree/Loading.tsx"],"sourcesContent":["import { Loader2 } from 'lucide-react';\nimport { type FC } from 'react';\n\nimport { Center } from '@/Flex';\nimport Icon from '@/Icon';\n\nconst Loading: FC<{ size?: number }> = ({ size = 32 }) => {\n return (\n <Center height={'100%'} justify={'center'} style={{ position: 'absolute' }} width={'100%'}>\n <Icon spin icon={Loader2} size={size} />\n </Center>\n );\n};\n\nexport default Loading;\n"],"mappings":";;;;;AAMA,MAAM,WAAkC,EAAE,OAAO,SAAS;CACxD,OACE,oBAAC,QAAD;EAAQ,QAAQ;EAAQ,SAAS;EAAU,OAAO,EAAE,UAAU,WAAW;EAAG,OAAO;EACjF,UAAA,oBAAC,MAAD;GAAM,MAAA;GAAK,MAAM;GAAe;EAAO,CAAA;CACjC,CAAA;AAEZ"}
File without changes